Skip to main content

PSMDB - A MongoDB alternative for having Encryption At Rest


Encryption is the most popular tool for securing data both in transit and at rest.

- For protecting data in transit, we can configure to use the TLS connection

- For protecting data at rest, we can use Percona Server for MongoDB (PSMDB), an open-source alternative for MongoDB Enterprise.


License

PSMDB Docker images follow the SSPL license. Therefore, it is not a problem when I only have my containers deployed in on-premises environments.

Running MongoDB Replication on OpenShift

I have successfully installed the replication by following the guide Install Percona Server for MongoDB on OpenShift. In order to make it work properly with my needs, I disabled some features from the default deployment. See the detail in this change

Basically, I needed to create a CRD (Custom Resource Definition) to let OpenShift/Kubernetes what PSMDB is. Then, I deployed the Operator pod. Finally, I deployed the PSMDB StatefulSet. I used NFS shares for Persistent Volumes.

Create CRD for PSMDB

2git clone https://github.com/percona/percona-server-mongodb-operator 3cd percona-server-mongodb-operator 4 5# create Custom Resource Definition (CRD) with cluster-admin role 6# This task is needed to executed once 7oc apply -f deploy/crd.yaml

Deploy the Operator pod

2oc new-project psmdb 3 4# Add role-based access control (RBAC) 5oc apply -f deploy/rbac.yaml 6 7# deploy operator pod 8oc apply -f deploy/operator.yaml 9 10# Add secret 11oc create -f deploy/secrets.yaml

Create SealedSecret for local keyfile

(Assumed that SealedSecret is installed and ready for use)

By default, the operator generates a normal Kubernetes secret with the name "my-cluster-name-mongodb-encryption-key". This secret is automatically attached to the MongoDB StatefulSet and persisted as a file through volumes. The operator also handles passing the files to "mongod" command in the container entry point. We can replace the secret in the deployment templates "deploy/cr.yaml". For example:

1 security 2 enableEncryption: true 3 encryptionKeySecret: mongodb-encryption-key 4 encryptionCipherMode: AES256-CBC

Here is an example to create a SealedSecret "mongodb-encryption-key" locally and apply it to the project.
1 $ openssl rand -base64 32 > mongodb-keyfile 2$ cat mongodb-keyfile | kubectl create secret generic mongodb-encryption-key \ 3--dry-run=client --from-file=encryption-key=/dev/stdin \ 4-o yaml > mongodb-encryption-secret.yaml 5$ kubeseal < mongodb-encryption-secret.yaml > mongodb-encryption-sealed-secret.yaml 6$ oc create -f mongodb-encryption-sealed-secret.yaml

Install PSMDB StatefulSet

(Assumed that NFS is installed and ready for use)

Create NFS shares: data-0, data-1, and data-2. Here is a sample command for data-0
1$> ssh someuser@files.example.com.local 2$> sudo mkdir /srv/data/psmdb/mongodb/data-0 3$> sudo chown nfsnobody:0 /srv/data/psmdb/mongodb/data-0 4$> sudo chmod go+w /srv/data/psmdb/mongodb/data-0 5$> sudo chmod g+s /srv/data/psmdb/mongodb/data-0

The directory attributes should look like

drwxrwsrwx. 5 nfsnobody root 4096 Jun 24 03:31 data-0

drwxrwsrwx. 5 nfsnobody root 4096 Jun 24 03:30 data-1

drwxrwsrwx. 5 nfsnobody root 4096 Jun 24 03:31 data-2

Create corresponding Persistent Volumes with NFS shares
1kind: PersistentVolume 2apiVersion: v1 3metadata: 4 name: psmdb-mongodb-data-0 5spec: 6 capacity: 7 storage: 2Gi 8 nfs: 9 server: files.example.com.local 10 path: /srv/data/psmdb/mongodb/data-0 11 accessModes: 12 - ReadWriteOnce 13 persistentVolumeReclaimPolicy: Recycle 14 storageClassName: psmdb 15

Install the PSMDB StatefulSet
1 $> oc apply -f deploy/cr.yaml

Comments

Popular posts from this blog

Google I/O 2017 Notes

WOW! How meaningful this below video explains about the name of  "I/O". Sundar Pichai talked a lot of Machine Learning Machine Learning is a very hot trend these days. Google uses it for their products. Google Assistant: Easily booking an online meal by talking with Google Assistant like a staff of partners, for example. Google Home: Hands-free calling. Google Photos: sharing suggestion, shared library, photo books and google lens. Youtube: 360 degree video, live stream. Kotlin became an official programming language for Android https://kotlinlang.org I'm on the way to Kotlin! ^^ Reference: [1]. https://www.youtube.com/watch?v=Y2VF8tmLFHw

Junit - Test fails on French or German string assertion

In my previous post about building a regex to check a text without special characters but allow German and French . I met a problem that the unit test works fine on my machine using Eclipse, but it was fail when running on Jenkins' build job. Here is my test: @Test public void shouldAllowFrenchAndGermanCharacters(){ String source = "ÄäÖöÜüß áÁàÀâÂéÉèÈêÊîÎçÇ"; assertFalse(SpecialCharactersUtils.isExistSpecialCharater(source)); } Production code: public static boolean isExistNotAllowedCharacters(String source){ Pattern regex = Pattern.compile("^[a-zA-Z_0-9_ÄäÖöÜüß áÁàÀâÂéÉèÈêÊîÎçÇ]*$"); Matcher matcher = regex.matcher(source); return !matcher.matches(); } The result likes the following: Failed tests: SpecialCharactersUtilsTest.shouldAllowFrenchAndGermanCharacters:32 null A guy from stackoverflow.com says: "This is probably due to the default encoding used for your Java source files. The ö in the string literal in the J...

JSF, Primefaces - Invoking Application Code Even When Validation Failed

A use case I have a form which has requirements as follow: - There are some mandatory fields. - Validation is triggered when changing value on each field. - A button "Next" is enable only when all fields are entered. It turns to disabled if any field is empty. My first approach I defined a variable "isDisableNext" at a backend bean "Controller" for dynamically disabling/enabling the "Next" button by performing event "onValueChange", but, it had a problem: <h:form id="personForm"> <p:outputLabel value="First Name" for="firstName"/> <p:inputText id="firstName" value="#{person.firstName}" required="true"> <p:ajax event="change" listener="#{controller.onValueChange}" update="nextButton"/> </p:inputText> <p:outputLabel value="Last Name" for="lastName"/> <p:i...

There is no expert, there is only us

Chairs in my office Once I was chatting with my teammates... Me : "I wonder why it is always necessary to refer to this source, that source, has anyone done it, is there any research? While no problem is the same, no situation is the same. Why not use our own brains to create a whole new one? Why do we have to be the insiders to consult the outsiders? Isn't that very paradoxical?" My teammate : "I agree with your point that no two situations will be exactly the same and that there is no one size fits all. But there's one like this, I don't think it's all the problems we're dealing with that only we can meet. So of course, if I can find a source to refer to first, it's still better. Just like when implementing a software feature, not every problem is the same. But I still have to go check to see if I'm the only one I've met? Or if someone has met me, I have to see if their method suits me before I decide to try it, but I don't blindly ...