🎬 Introduction
This blog post series is intended to give an overview of how datastores capable of supporting high volumes of data from IoT devices and Big Data services can be deployed on Kubernetes. In the first part of this series , the StatefulSet primitive has been used to set up and deploy a mongoDB Replica Set (cluster). In the second part it has been demonstrated how other Kubernetes primitives such as Secret can be applied to secure our initial, dummy deployment. This article of the series explains how to further secure (by enabling client and member mutual TLS authentication based on x509 certificates) and to shard our mongoDB Cluster.
Prerequisites
It is assumed that you already have an up and running K8s environment, such as minikube .
All the examples have been developed using minikube on macOS Catalina with VirtualBox.
First of all, a new, clean namespace named shard
has to be created to develop this part.
kubectl create namespace shard
đź“ś Enabling client and member authentication based on x509 certificates
Our objective at this stage is to deploy a mongoDB Replica Set with client and member authentication based on x509 certificates (additional details about this architecture can be found here ). This Replica Set will be later part of our final mongoDB shard.
After completing successfully these steps, it will only be possible to get access to the mongoDB cluster by presenting the proper client certificates and associated secret keys (i.e. no insecure user/pass anymore) packaged as “keycert” files.
Certificate Generation
First of all the following certificates have to be generated:
One certificate for cluster server TLS. Already generated in part 2 of this series.
For each member of the Replica Set, one certificate for internal member authentication.
One certificate for client authentication. It will be needed as much certificates as clients our database is going to have.
For generating our certificates the steps already explained here have to be followed:
Thus, in the end we will have:
3 “keycert” files (one for each Replica Set member):
mongo.cluster.0.keycert
mongo.cluster.1.keycert
mongo.cluster.2.keycert
1 “keycert” file corresponding to our database testing client:
the “keycert” file we already generated in part 2 corresponding to the server TLS certificate of the whole cluster:
Bootstrapping the mongoDB statefulset
Unfortunately, when it comes to certificate-based authentication, mongoDB does not provide any deployment mechanism in one step. Thus, it is needed to perform a two step process. In the first step, bootstrapping step, a mongoDB cluster with no authentication will be run (as we explained in part 1 ). After configuring the cluster, in the second step, our K8s manifest will be reapplied to set up the final configuration with certificate-based authentication enabled.
For bootstrapping the following steps have to be taken as explained in part 1 :
apiVersion : apps/v1
kind : StatefulSet
metadata :
name : mongo-db-statefulset-sh1
labels :
mongoDB-replica : " true"
mongoDB-secured : " false"
mongoDB-sharding : " true"
annotations :
author : JMCF
namespace : sharding
spec :
selector :
matchLabels :
app : mongoDB-replica-sh1
serviceName : mongo-db-replica-sh1
replicas : 3
template :
metadata :
labels :
app : mongoDB-replica-sh1
spec :
terminationGracePeriodSeconds : 10
containers :
- name : mongo-db
image : mongo:4.2.6
ports :
- containerPort : 27017
protocol : TCP
volumeMounts :
- mountPath : /data/db
name : mongo-volume-for-replica
args :
- --replSet
- $(REPLICA_SET_NAME)
terminationMessagePath : /dev/termination-log
terminationMessagePolicy : File
imagePullPolicy : IfNotPresent
envFrom :
- configMapRef :
name : mongo-config-sh1
volumeClaimTemplates :
- metadata :
name : mongo-volume-for-replica
spec :
accessModes :
- ReadWriteOnce
resources :
requests :
storage : 100Mi
After the successful deployment of the statefulset above, the next step is to set up the replica set using this script . Once the Replica Set has been set up, the cluster users as per the DNs already defined when certificates were generated have to be created (from the mongo client console) as follows:
db . getSiblingDB ( " $external " ). runCommand (
{
createUser : " CN=App1,OU=Applications,O=CanteraFonseca,C=ES " ,
roles : [
{ role : " readWrite " , db : ' test ' },
{ role : " userAdminAnyDatabase " , db : " admin " },
{ role : " clusterAdmin " , db : " admin " }
],
writeConcern : { w : " majority " , wtimeout : 5000 }
}
);
db . getSiblingDB ( " $external " ). runCommand (
{
createUser : " CN=mongo-db-statefulset-sh1-0.mongo-db-replica-sh1.sharding,OU=Software,O=CanteraFonseca,C=ES " ,
roles : [
{ role : " __system " , db : " admin " }
],
writeConcern : { w : " majority " , wtimeout : 5000 }
}
);
db . getSiblingDB ( " $external " ). runCommand (
{
createUser : " CN=mongo-db-statefulset-sh1-1.mongo-db-replica-sh1.sharding,OU=Software,O=CanteraFonseca,C=ES " ,
roles : [
{ role : " __system " , db : " admin " }
],
writeConcern : { w : " majority " , wtimeout : 5000 }
}
);
db . getSiblingDB ( " $external " ). runCommand (
{
createUser : " CN=mongo-db-statefulset-sh1-2.mongo-db-replica-sh1.sharding,OU=Software,O=CanteraFonseca,C=ES " ,
roles : [
{ role : " __system " , db : " admin " }
],
writeConcern : { w : " majority " , wtimeout : 5000 }
}
);
db . getSiblingDB ( " $external " ). runCommand (
{
createUser : " CN=mongos.sharding,OU=Software,O=CanteraFonseca,C=ES " ,
roles : [
{ role : " __system " , db : " admin " }
],
writeConcern : { w : " majority " , wtimeout : 5000 }
}
);
db . getSiblingDB ( " $external " ). runCommand (
{
createUser : " CN=mongo-db-statefulset-sh2-0.mongo-db-replica-sh2.sharding,OU=Software,O=CanteraFonseca,C=ES " ,
roles : [
{ role : " __system " , db : " admin " }
],
writeConcern : { w : " majority " , wtimeout : 5000 }
}
);
db . getSiblingDB ( " $external " ). runCommand (
{
createUser : " CN=mongo-db-statefulset-sh2-1.mongo-db-replica-sh2.sharding,OU=Software,O=CanteraFonseca,C=ES " ,
roles : [
{ role : " __system " , db : " admin " }
],
writeConcern : { w : " majority " , wtimeout : 5000 }
}
);
db . getSiblingDB ( " $external " ). runCommand (
{
createUser : " CN=mongo-db-statefulset-sh2-2.mongo-db-replica-sh2.sharding,OU=Software,O=CanteraFonseca,C=ES " ,
roles : [
{ role : " __system " , db : " admin " }
],
writeConcern : { w : " majority " , wtimeout : 5000 }
}
);
db . getSiblingDB ( " $external " ). runCommand (
{
createUser : " CN=mongos.sharding,OU=Software,O=CanteraFonseca,C=ES " ,
roles : [
{ role : " __system " , db : " admin " }
],
writeConcern : { w : " majority " , wtimeout : 5000 }
}
);
đź“Ś Â The command above has to issued against the mongoDB Replica Set member marked as PRIMARY
.
In this case we are creating 4 users under the $external
database:
The user corresponding to our initial testing client which is assigned some admin roles and it is granted explicitly permissions over the test
database.
One user for each of the Replica Set members. These users are granted a system role.
Now everything is ready to switch our initial bootstrap to a fully authenticated cluster.
Running our final statefulset
After performing the initial bootstrapping we can switch to an authenticated set up as follows:
First of all, we need to create a new K8s Secret
that will contain the member certificates (“keycert” files) for authentication:
apiVersion : v1
kind : Secret
metadata :
name : mongo-secret-sh1
namespace : sharding
type : Opaque
data :
tls.keycert : " LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVBMnd0bzJRdzRZSVlZZFgzaU8wbElnaTJUL0tzVG5nSml6ZHFBdFY4R0V2eFI2OHQzCkhxZkpUYVlUUTduL2tScXZ0a2xzY2RyL1VvSXJJcXBXZ0hzRzcvU2pmQUNEZGMrbm5PQUM4enlDbUFsRnE0b04Kanhya2tZQWsyd0ZkcGtyOER3RzBNN0xXWmtsZDdFb1lJSFN4U2pWQkl0dGJFNXAwWHk5NFZDdE9qSS9oUElZegp3OGhRWDcvYzRPdFJZUlhBZUc3MjhmaC9laWtZY2ZUdWFBNGNOVy9nZzZOeDRWWXBrMHYrRDFWUmFTMVdOdUtzClJTOWQ5MUhOUmI0ZWhwWEN4NmZEUDc5N0E5QmdZM0pHSzJOWUpoaVVja3JKTkdDa1EwRjg5ckpHSHpEaWliTCsKU29mbTFTakkxWWdnQUc2YVZWMDhlTUxVZjdhT1dEWFlmdlFBaVFJREFRQUJBb0lCQURna0EzcGx2R2xZMVJuLwo2cVRoVW5reTcxUDZFT3dWbG5kR1FtaTU4eGVZbmZKK1VvaUQzbjlOU25DNFVqMUJocm1FdGd1MFltNG1PS0lJCjRHVExvMnFLMi8vakxjNWJLNDEwaUswSTNEdlZYSXJydGkvd1o1YTNManNIYlpZNmI4SDA0TmZEUlZvd0FhZVgKRWZuM2pwMERheTlnNDBYeDkxT1NHaGdRaFhCVzBxbFh1VkZaMzFWb29OZHlVOUx1czBvc0EwNCt1SElLOXJGaAoyT1FEbnhIcENtczkwUDBleHlNQUgySDRBOFJUbTZWNGUyZ1FIUCs4UjVKRE5Sd2kvSzJaSTB3VFJ3eTYyWjM0Cml0WVl2d0xtdnRxTlN6NW1KMGRlbEd3MGEvNTd3MlBDbklYaTdOR0d2QytqSWdrZGt1M3Z2MFRHbitKWUNXc3gKQWg5ZEtaRUNnWUVBOHc2cFFIZCtQYnFiMVhRdlo1T1JzM2djYmhNNmxNOWdtUm9Ic2tVOCtDbVhCRU16SHRYcwpxaHFRZHh1NERPZlVhejBIamo0QWplMXNyNjdTcWpidWdGMHZOakdTanpEMndVN0RsWkNEVWZSaEZLUXRWdkk4CjdLb05uZ2Q5aUFWMzhaZXBhbjFJdW5LWC9UVXgxQ3FpOElCWjNRR2RodlZ3bENQMUdHcUUxblVDZ1lFQTVyVm8KdHI2K3R6SW1QQy96ZWlqc0dMRml0bzdoTEdPZUdmeWNXUVQ3blowNlFtZ1hmMVhhRUF5a0JSMGI2RmErV0k1bgovWE03ZWhGSVZDRE9pVzMvRUluOTRSY0pjRXYwaENORDhqVDdPamRycWllaktEa2dTdndDMEZaRVRPaUxSREswClJTcXlWbVdtcTUxcjFpUktyZ0FTeXlKQmlMaC8vTTZMWVRzRkIwVUNnWUFLMXkyUFZZVUk1Y2pMaFdvVDJZNFgKRGhWZWgzY0dhaFZwM3JKWExpVmhBQ0hmSzh3YzVQZXdRbzBNOHV5TGpzOTNsUHBBU3QybGR1QnhHWUFGM1h0WAp1RkJCdjRaRTRxOHV3ZitSTFNmZVFPTVBrNTcrRU1ITTRHekpEcFozdVo2MjVNZkdteDNpU3ZnaWIvdnY5WkxjCjNTeWs0Y3lQMTJTVkJ1R0luRCtlZlFLQmdRQ1MzYmtqWEpvY0ZSaXlCL1IvTjczVW1sZTB6NUFZcWZIanFTUCsKcDJWbUdNa1ZyUjRJT2FidndKeEpoUlpXK2FHQ3ptVDB1MzZKWHFja3B4M1Q3dW9JcFUreEV2RTNRNk1NMjBaTgowZHg4V3Z0Mi9uU25EbmE0UldXbEtzV2dFQWxZQ004cG1OeWVrMmRlcUlBVmVsVHdINnZYRkorVFlhQllWMFB6ClNaY1I0UUtCZ0VYZmhTVHV3cEgwbEgyQXNWMlAxUExTZU1rRVI3Rm9IZndpWmhPT1h6VGdNT2lVdjd4UjQxTmMKeG9WcWJiQnNyVitkcjQzSW1sYWFuQzBEeWZua2g0Zlp2Uld4OUJLTG05SGhDbHZSd2ptZzYxaHpzTDZGNERaVgpXSGFHZktRY1RKQnNWaHl3UFRMQmZZM1gybWZjTHdsbW90a3ludWIreDlqTE12WUt3UmZyCi0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCi0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlEN1RDQ0F0V2dBd0lCQWdJUVAwRDFQeVNZbDZQTWp2eExGUTl1aURBTkJna3Foa2lHOXcwQkFRc0ZBREFWCk1STXdFUVlEVlFRREV3cHRhVzVwYTNWaVpVTkJNQjRYRFRJd01USXlOREV5TVRJd01Gb1hEVEl4TVRJeU5ERXkKTVRJd01Gb3dPREVMTUFrR0ExVUVCaE1DUlZNeEZ6QVZCZ05WQkFzVERrTmhiblJsY21GR2IyNXpaV05oTVJBdwpEZ1lEVlFRREV3ZHRiMjVuYjBSQ01JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBCjJ3dG8yUXc0WUlZWWRYM2lPMGxJZ2kyVC9Lc1RuZ0ppemRxQXRWOEdFdnhSNjh0M0hxZkpUYVlUUTduL2tScXYKdGtsc2Nkci9Vb0lySXFwV2dIc0c3L1NqZkFDRGRjK25uT0FDOHp5Q21BbEZxNG9Oanhya2tZQWsyd0ZkcGtyOApEd0cwTTdMV1prbGQ3RW9ZSUhTeFNqVkJJdHRiRTVwMFh5OTRWQ3RPakkvaFBJWXp3OGhRWDcvYzRPdFJZUlhBCmVHNzI4ZmgvZWlrWWNmVHVhQTRjTlcvZ2c2Tng0VllwazB2K0QxVlJhUzFXTnVLc1JTOWQ5MUhOUmI0ZWhwWEMKeDZmRFA3OTdBOUJnWTNKR0syTllKaGlVY2tySk5HQ2tRMEY4OXJKR0h6RGlpYkwrU29mbTFTakkxWWdnQUc2YQpWVjA4ZU1MVWY3YU9XRFhZZnZRQWlRSURBUUFCbzRJQkZEQ0NBUkF3RGdZRFZSMFBBUUgvQkFRREFnV2dNQXdHCkExVWRFd0VCL3dRQ01BQXdnZThHQTFVZEVRU0I1ekNCNUlKS2JXOXVaMjh0WkdJdGMzUmhkR1ZtZFd4elpYUXQKYzJneExUQXViVzl1WjI4dFpHSXRjbVZ3YkdsallTMXphREV1YzJoaGNtUnBibWN1YzNaakxtTnNkWE4wWlhJdQpiRzlqWVd5Q1NtMXZibWR2TFdSaUxYTjBZWFJsWm5Wc2MyVjBMWE5vTVMweExtMXZibWR2TFdSaUxYSmxjR3hwClkyRXRjMmd4TG5Ob1lYSmthVzVuTG5OMll5NWpiSFZ6ZEdWeUxteHZZMkZzZ2twdGIyNW5ieTFrWWkxemRHRjAKWldaMWJITmxkQzF6YURFdE1pNXRiMjVuYnkxa1lpMXlaWEJzYVdOaExYTm9NUzV6YUdGeVpHbHVaeTV6ZG1NdQpZMngxYzNSbGNpNXNiMk5oYkRBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVFFQWVCVWdSTnltQ0dSRmR3VllDVk9OClVCd2ZtOGgxazJGYnZnV2ZBT0d3K0NsYTdMWE5kK011alR6MEhpcTg1T3ArY1J0TzM3bjFRcWUzQUJmaFdPV0oKdkNPV1Ixb21PZWx6NUEzK2hqNERuSmQyWEFQZnFkNjBubnZsL0MxUlhZeXp6ZHc5VFRua0hLTGVmWWZUMHJtVwpNeTkvanNBODBhNnhOekNLOFkwS09yY210OCt3N1Z4OUZyMGxybnl5TVBqMURnQU1EK1ZXenRuVFV1MGRPSllOCktBUTJ4ZXkybkRpY3FOTGRYbkQwQk10ZGlXZE1YS0NGeFQ2RVhhOStiSjlYRkd6dHp0dW9qcnI3ZnlsdkRZOUcKcDljQWpJYnUvMzJEUXBRcC9HNXMzMlhia2JFN1BQd2xSaHpnVXk3K3g1Vi9ueFE5Yk9LaWgrTmh5YkdSVVlMUgpJdz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K"
tls.cluster.0.keycert : " LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcFFJQkFBS0NBUUVBNEc4L0IyTm5Xd3pNaVZQbzFzWGluWXVwcVVSZ296VkNobk1BSHNjc1hUN1pwWkE5Ck1FNjBwRG1FNFVIMnN5aDJKOUF2REhXc3lnRXRqZkpxbUlVZUVlMUZKWlAxdUVrS2dOUUMxMTZNOWcrTUdrYlUKeWljOHhFZy9UZGY2ZGV0Z05IRVFkUXUrY2U2ZTIzY3Y1dWFqOVQwT2h0QjR3N2Qyc0ZPSTFheGZiUWFzY0F4OApQZ3JJMkxVZERTWHdUWjJnWjl5RysyR3NjZ3YyWHRGZ3VUaWJUb3NidmZNdVlIcVVvQ0F3Y0NESVVOeVFNdG50Cm9kUmhES2dUUi95UUNQVkFIZlpKQm13eEQzWGk2by9CcklML0NPVE1EcGcvVlpaL3FqenlUZ1d6ejgyMk90cUYKdkt2MWpqalF0QjZNQ2NUcFJhWGVHbEFpMnJ6SnFUSHpjaWpwMXdJREFRQUJBb0lCQVFDVXRFRC94VFl6RnN6aQo1TXp1bVJqb3FDUVcraTVKbFQxcDFnS3JZZTZjTGN1SnJvTk1ZYW5BOGplQUJQUFBpeXlXZnBMZDM0NUlIZld3CkNvSGtZcmNreTZBNElNdjdlYkhTNENhdHlvRDlmQm1wUTJzME1rRktFRkNaWkZRWUU0ZWYxNVkrNXpRZFN5ekkKWHpWRytXU0RWaHdzNlM1TEIyRkZ2V041cUFkbU5YcWZIUHBPeW54K2pQa2t5UG5PK3llaVhMODZXWDhhT3FBVApOOEVxWGRnNi9hNFh2b1dNREZnTjlITXRWRWJXcnkrNzBVWHlRc0kzQndMTjRQdFIxdll2Yk0vQlhOWnA0amxOCmhENHFJYUxLNWFpa3pKMDN4Rnl5WHF6eTRSd2ZCalJ4cGpSbkdSUzlwNHdvM05sTVV2RFBZOXFxdTJMQUZSeWMKdStyZzhrVFpBb0dCQVAydU4yRENnenZ5S2IzV3pzdXBHTG54MUhGV091ZjRCY0FyWFJ3WDF1Z2NQOHkvTXl3WQpWOG9XNUg2TVhPbytWb3dxd3hRSmNRcXZXS3pXaTkyd0FIWnBVU1BERUxXbitVUlVyQWZyNFBCbU1mRE9VNW9CCnpYNXpXZHJiNHUrVVJvZVltdW8yRmRBcmFPRTg4STZqVk5XMVlpdUJGb3hERU1Pb3U2N1JRaEpGQW9HQkFPSjgKa3haT3dxVW5oeFp6bG9Xbk96VjJxUCtoZXV4STNvY0JhNDFpem91Q1MrcFNPSC9SS2wzRE1GVmZmejR4VlV4Lwp2UDRGTnZXTXlvZE9KU21WdXk3U3B6YThnQmFtNDVuUlRSWDVOUlhYczg3dXd1MWJManZJSk5rWkJPbG9vZTdpCi9TdkFWSHVrL2t4MWFUUUcyazU0SjJNY3JxNkRmSktLRzFtZUJodHJBb0dCQU8wUEw4cnBHbkFiZGF4a255MHMKb09HcXZtY0hPTmJyTEp5UEtWeUdYcHJiUXplWGVUOThwQlZDM1ZYdzN5YzdCKy9HU2pSZ09sWE0xR1gzdkE1MwpXWWRPRmJnQW9vM1BJWjRjTGdMZEI0QS9UKzRETVpiYWxtalRiS1djRSs3a3RpQWltS25EenhDUWNGc0RjcDBvCnZxOVM2Q0ZWYVhlN2VHQVBQd3czbXJHdEFvR0FJRjRaVHpqV1RIQUh1RWV3blUwM0F2OEFTL2d4N3c3QzdweGYKV0lka2FUK254Y2NXVi8zMmhndmRIblpWWXZmOTdyN2FyWnJsTGRaL0l6TWgwSDJia0tkK1NpNUtSL0oxMkllMgo4b3I0OFRRd2VFUmJDenphc0tSN3o2THB0c25EU3JhWjQrVEtyaGo0VnNqNHpmeWt1azRsb3Q1NGdHdytJMXNsCmFYdFIrQjBDZ1lFQTBiclBYVGJ3bE9KNU9WVklzbUtkQzU2RzNCYmRhZUZrdzZ1NTNjcm9LMjYrY2RPank5NTcKeTloSVhuWlF5SVRxRW0rKzBsUjJldnVKY3cwK2hBRVYxRjJKY3E4akZkejAyeXhQeHhtb0lTWFd3QnlnME04dgp2SVFzbXRCUk1SV1pMVnhKQk5RZWFMa2RMcGtlQVo1NG51aXNWejlHa1c2YmpWY3E1L0JodnlBPQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRE96Q0NBaU9nQXdJQkFnSVFQcm02cHowOXRicW9Wbmw2Y1dyV21qQU5CZ2txaGtpRzl3MEJBUXNGQURBVgpNUk13RVFZRFZRUURFd3B0YVc1cGEzVmlaVU5CTUI0WERUSXdNVEl5TkRFNE1EYzFPVm9YRFRJeE1USXlOREU0Ck1EYzFPVm93ZkRFTE1Ba0dBMVVFQmhNQ1JWTXhGekFWQmdOVkJBb1REa05oYm5SbGNtRkdiMjV6WldOaE1SRXcKRHdZRFZRUUxFd2hUYjJaMGQyRnlaVEZCTUQ4R0ExVUVBeE00Ylc5dVoyOHRaR0l0YzNSaGRHVm1kV3h6WlhRdApjMmd4TFRBdWJXOXVaMjh0WkdJdGNtVndiR2xqWVMxemFERXVjMmhoY21ScGJtY3dnZ0VpTUEwR0NTcUdTSWIzCkRRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRRGdiejhIWTJkYkRNeUpVK2pXeGVLZGk2bXBSR0NqTlVLR2N3QWUKeHl4ZFB0bWxrRDB3VHJTa09ZVGhRZmF6S0hZbjBDOE1kYXpLQVMyTjhtcVloUjRSN1VVbGsvVzRTUXFBMUFMWApYb3oyRDR3YVJ0VEtKenpFU0Q5TjEvcDE2MkEwY1JCMUM3NXg3cDdiZHkvbTVxUDFQUTZHMEhqRHQzYXdVNGpWCnJGOXRCcXh3REh3K0Nzall0UjBOSmZCTm5hQm4zSWI3WWF4eUMvWmUwV0M1T0p0T2l4dTk4eTVnZXBTZ0lEQncKSU1oUTNKQXkyZTJoMUdFTXFCTkgvSkFJOVVBZDlra0diREVQZGVMcWo4R3NndjhJNU13T21EOVZsbitxUFBKTwpCYlBQemJZNjJvVzhxL1dPT05DMEhvd0p4T2xGcGQ0YVVDTGF2TW1wTWZOeUtPblhBZ01CQUFHaklEQWVNQTRHCkExVWREd0VCL3dRRUF3SUZvREFNQmdOVkhSTUJBZjhFQWpBQU1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRQXgKU2JINmdiQkUwQ2xXQy9XSlEzUkRWM2RyOEkxcmdIcmg5UjJnT2F6KzUzclZvaHliMDV2NWJkb056dk1Rbmp1eQpuQ0xSU29uZ2RVOVhkb0djQnVudkZpZ3NrcVE2VG8xWUlMaVF4dW5uOHlCakNFcDA3ZUR1aGlrOU9XYlVHa20yCjgyWjAxa2wrNE5VSmgybnV5VG5ycFVtTHprb0Y4NnpVdlA1aHRFMFZCYWUyNFZQN09xWDNDUGE1WGU5bHcrUEQKZUJBT3YxUzRMYlRjZTFGbXVsK3d2ZjdTT3o4NHU4SHFwd0ZNMFRSQ2p6YWVNTEJGNVF6elpsT2w5ZFpRdURWVAorY05uUmhnQW9PUUFzRkE2UFhnMmVjM0VIV3RxSk4yOW1Ua0ZocjZuZXhBcEJnd0VHRnZPclNaZ3FwZmpNcEVZCmM1MmRSUWxaSEFzQk1ua0EzUzhmCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K"
tls.cluster.1.keycert : " LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcFFJQkFBS0NBUUVBdHFGRDNKV0k5MlIyTU51WWR1dms3YzFHRUtBMXdkSmJMbFJkYUJxYWNSS05uMmZTCk9EQzFhZ1RVL1BkUFpkVjF5ZHZpaHA0TEpHZThYLzNQWmtSS1IvYXhaWTl2eVZuc1h4dUt6bjMxUVMyYnJ2MWIKOG1ZVEM5eXhXUVhqaURiUXJQeVdxS282UVFQZlVCRnpLRzZ6NjFYZEt4aUx3ajZoZjNjTnBHcUxrUU53R1VLZApGUzA3a3M4YUZYUTdOcEhqSkpxeUMxL05qMzN0V2pDMmJiSDBKZ2JONkg1YTNEVmpnR2FGZGNWQjQwUWhRU0dpCk1Ob1BiSElVUERjOExiVHI5Z0lqd2FORGx6dEs2TVIzeDduclNaL05kOGY0UTBscXNjNGVFanZHclhtbEtUREkKRWVKbjBEMDVBODVyWjVZTmorMy9qWWlTMGJqT0cxSEljVzNMVHdJREFRQUJBb0lCQVFDYnJLdGtCRE5VYmxZeApIMzYvSUNWc2IyWWlGZTY4NE1ySW16Rmo1QWx5Q1JhZm9xZ1hMYTMyU1Zna3Fjc01Td0MwcUxKWGZiQ1J2N3RiCk44YnFyWnVEN0UwYS9VR1VxUXBMcC9hU1Bkd3BTdTlDSXNXVndseko1NzFrM1JndXJFc0VxZXJpcXZndEkxZmYKc0lBeEh1eE8xa3BJeWd1WDhEdEpvL29GQkswalZoQWJrZnJSYlpUdGt5d0ZmQ3ZDdFMzTjJMR3Z5eEF1Umd5NgpYTE8xdnhBN3hYMUJOS1lnekJrUUdGY0dZaEZ3WWViaWttL2Z6NjdqUU1vSDNFbUU5d2F4eXVKcUorYVEyalFFCml6akFsaWgvUU1RMXRTcnJnbjRZVlpWN3FrNWxGditxT1N6ai9SYUJoNlVjUEJmYkJBTWE2eVRCZlN6TWVKVUUKRUFmMzd2aEJBb0dCQVBEUEt4SkNLc2ZyOXA5L3BUNHo3bmtKMWdIa1pvUjZWQzFhbnpUZzE3a2tLb1RpUFdFbApZL2dwUTUzSldtNTljS2E0dFhmUDdDblJucmJIenUvZ05zSlZ4YnpMbTZGNzlmT0tLOTlIc1dSZjNDYjNjemZoCjcyckNheXRzaWhGQWtrcC9HSTMrSCtqblVTMHRCdGxzdUZuN1M3TWdaejZZMlhFL2I3MU9NbityQW9HQkFNSW0KanZQcUI4L05Pb25MMkY0aEJvckJVdHdJVnl4TVR2dTNZSndlS1cwbFVsUEZuTm1BVkpUM3FvUWNDeHNxN3grOQp1SVNnV3Buak1lTmZWZG45V2IzelRTTUJrVGQxTWdrYTdLSkZZYTRtMWJWSVRyeDl2UlhySGZaOXFYTmRzNXE5Cnh3Y3JOcC9wSFNRTnc4YUV1bkZYRFd3Qm9nUGEyYlhRQkw0VDFzN3RBb0dBVW45bXpoYUUrWURKT05OT0ZRVk4KaVlIcEl6VFFPa3ArVkJ0YnQ0M2YyYm1lSjNBcWZ3R0VRaHhBNGVsOVphVHIxdklvbVNkT1RQVlhYbDhOY2ZocQpTaUdBWUxHUVc3NVFBR014cklpdktTZitFQXR1R1pMNXBxVjhlWi94blA5MkhyZHovaEUxZFdEcDJvUTJlSDVhCm1ka1JrZ2hqMW5vZTVFRkxVcHRiaVlrQ2dZRUFzQTJPNjVkNFpmTFA5a3dtYzVTMi9mTzRVMVlzMWpxTUZLMkEKcVpDZ09Cenp2b3NmWkF0K3AyYTk5UFlKRENXdW1MWE5NRmJJVVdzM3ZkcWhXdjdsOWQwK1FWUVdmcGVETzhaeQpkZU04WkZOS3p3dzJlYTM3WEhqTHZzek1iNVMwWE1saVJSbm1lck5FZllFTjJtSlpQcFdWMGk3WTMyNEFwV0Z3CkszeUorVEVDZ1lFQW1tRkR6bHF0OXZsTmIwSCtwcjdhbzRsMkR1S2FlSWRESWxvM1d2NDZsMlB5MnFLcVpMaFYKT3RvSXJta2p1OE1aUjI5NWtja2xRdHVhWWZvTXBlZ1BiYjIrdEdjcFBHN1dvRkFrZENQbTBGczc2MHkrdGo4awo3eG55RXAvVk1nenByc3VFSmV0b3dYbEQvRC83blZOSCtGOXo3U2E3QzhXeC9WdmNDY1RJSjhrPQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRFBEQ0NBaVNnQXdJQkFnSVJBTncxTDZycE9xajh0TVgxejFHd2xtSXdEUVlKS29aSWh2Y05BUUVMQlFBdwpGVEVUTUJFR0ExVUVBeE1LYldsdWFXdDFZbVZEUVRBZUZ3MHlNREV5TWpReE9ERTFNelZhRncweU1URXlNalF4Ck9ERTFNelZhTUh3eEN6QUpCZ05WQkFZVEFrVlRNUmN3RlFZRFZRUUtFdzVEWVc1MFpYSmhSbTl1YzJWallURVIKTUE4R0ExVUVDeE1JVTI5bWRIZGhjbVV4UVRBL0JnTlZCQU1UT0cxdmJtZHZMV1JpTFhOMFlYUmxablZzYzJWMApMWE5vTVMweExtMXZibWR2TFdSaUxYSmxjR3hwWTJFdGMyZ3hMbk5vWVhKa2FXNW5NSUlCSWpBTkJna3Foa2lHCjl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUF0cUZEM0pXSTkyUjJNTnVZZHV2azdjMUdFS0Exd2RKYkxsUmQKYUJxYWNSS05uMmZTT0RDMWFnVFUvUGRQWmRWMXlkdmlocDRMSkdlOFgvM1Baa1JLUi9heFpZOXZ5Vm5zWHh1Swp6bjMxUVMyYnJ2MWI4bVlUQzl5eFdRWGppRGJRclB5V3FLbzZRUVBmVUJGektHNno2MVhkS3hpTHdqNmhmM2NOCnBHcUxrUU53R1VLZEZTMDdrczhhRlhRN05wSGpKSnF5QzEvTmozM3RXakMyYmJIMEpnYk42SDVhM0RWamdHYUYKZGNWQjQwUWhRU0dpTU5vUGJISVVQRGM4TGJUcjlnSWp3YU5EbHp0SzZNUjN4N25yU1ovTmQ4ZjRRMGxxc2M0ZQpFanZHclhtbEtURElFZUpuMEQwNUE4NXJaNVlOaiszL2pZaVMwYmpPRzFISWNXM0xUd0lEQVFBQm95QXdIakFPCkJnTlZIUThCQWY4RUJBTUNCYUF3REFZRFZSMFRBUUgvQkFJd0FEQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUEKWXNjTEprWThJTWJrRk14TEJJcGt4RTFhdzlDaHNDM0hPRXpCUlhhb2dFTXZUd2xzRFB3Q0Zhc3l6aTZzeDFnZApZVmdBMXp6WEhabWhpdkJGZ2x0MXZYZlZFNTdaRmFJaVNOQXp2NUV5a2lKVHhFd2t6SmNQWVFJYTE3b3UxYkRMCitPSG1TVHlOZXJFMjhVY2J3YkcwN1hNeXd3S2JTZCtTU1I4dzMrZXYwMWhzRDZZZm5FU0hjZzlscEt2ekFseWkKL0ljVEZHQzBNeEtoUWVmUWo3UE8vWVpVZkpSalZHK1dXeEZzSWI3L0JCSFgzaWwwMVBEQzY1bmdPaUlHQktKdApxWUpLREVKL1lwalc0ZHpIWTV6VXRqNVh5TkQrMFY3UVBBUWQwQW4zUzNLbURsZkRzZ2xjeEZDdDJHZEdRM05sCm16TnZqazNJSU1UeWxwMFNCV0lPcFE9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg=="
tls.cluster.2.keycert : " LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcFFJQkFBS0NBUUVBempCbkpzdlZSYTlQRVNKRWVjSnBENDdEU1hyenplME1oZjk0cW5ITTNzM0IzekdTCjJBVUk5U2RiOVF0ajBTY2lnOFJ0NWsrUk5OanFtTDIwN2RqbUhMRytDS01aUnRmeVdXZkZGN1NINkk3cE9MVFYKN3d0ZkpWMlJmWDNBSWhBZ0V5bEdDVFU4K3E0NjN3Z1hBOVVVWDBxdUd6ZEVnaVNCdnVVUzV2a2JMdlFyZjY4aApEMkZsc3NkQlhHRW5zY0YzbHBlZDBZYTgrZksxenllSTEzTWNrRkFnbitKaVp4Mlcva1VBcTQ2MkxWTkl4bll4ClpPWmZiL3ZyWnRSR0J6QTl6T0o2S2FZWi92L3hZWGhKd2htRUQ4VWprNnR3VzBPdFFFT1hCT1grK0I3V0NGWDQKV1NqMzhZR1FqbnVvZmZ3S2VvQjQxUzBWNndTQjRLeGtwR1MwUndJREFRQUJBb0lCQUY2d2lkNmVRMDVpU1F4VQpVV0FkY1FRdEN2QW0zK3BWRDZoRi81TSsrZGZrWkVGczBjUVU0OTA1K3hnWTUvazRZTGhrc0JmUnVKeXRkV2M1CnorcGU3cWFFMWdHL2JTOUVvczUrUWx3MWt5aXc0TmdpN0JDQWgyeHdnUTFCZjhmazRlWUswVmdQTS9ibnBxK2cKVm5sekZJMENqZHgvMEIxNFNJRnpUKy8wdkpBZHpEUnlZeFBHU2YrMjZKU3A0VTJWMmwyK3pabFQrRThicC9CRQpQTXJsLyt0NkFiNjE3K0l3MlpFcHNFMW9SMmZpNHBxSllqelAzNGpvdC9xMW9jUjNKb0RRUFZva2dmRzdteDduCkdVbmFsVkNXM1hadDU4QlA4dTh6ckVFTzhlSXdlRWE0UGVQcWs0M3VTRjBCemtEOCtiODR3VU1uWVVkdmJ3bVoKZmNRbUFUa0NnWUVBK3lWTVpMUjVKZHBzeldjUGxwU2lxSEcyQXdhaGlEbXRGc3VITW12MFFRS1VVd1p0aXBBSgpRbGNMb09Hb0RjY01xOHc4Nml1K0RvVGpVN1hWcjRIYTJLZWlJVUd3TG5Qd203OFZSWVJzRVB0Wm84TWZYOEw5CnJQdEFsVFFUM2NUbHA5MEZtMTJlU0tUVldLZGR6YmFBY3lhREZWN2tEM0FRckdHcmxiSlVDSk1DZ1lFQTBpeW4KUHVzUnh0dXdPMVNBNHBRaDhyNlFMT2VVcG9Iajl4NUQzSmI0ZWIyMUJhZS91VEZMWmtUSXNZZGx3T2RGMWNJLwpPY2hLN0dHYkRDUWRueWRHMitEem8rcHY0RDdUY2pvQ2hsaTF6UUtzMjQ1WDFtVms1R0xjcnpmR0VhUkwvL0puCnp3QjgrQ2Y0c1JtVWpSOXNNSGNqMzVBYWZxYjQvQWI1RG5RQ3VmMENnWUVBNXVDckVnazNOaTFPeUtWdUZ5Z2QKUUcwSXZrOWlRREdGaGVjbEtwMUR0bUFBcXpMRmtSUkk3c3ZHek9lbDdzU0dTWWxBbHFZUDJwa2Z3dHp1ektHNwo1bUIxRTgybmdZemtMTW5GYkZzSVhiUXorL0JzNzBQNm9RTjVvN0IwY3ZPSGpJSUxuWUM2K2wxT0pHbjRPaDBFCmlOZG11a2E1c2RkNy9IenRtSGlQK0RFQ2dZRUFsRnc4K3VjSXQyMGdxK0RzMGdSckttVm1kS3hNZkhVNExKcksKb0k1WmUrWjBRRGUzMk14NVF3bk8rYkp3RzRtbC9FeVFRUU9vRDlDZW1DVnVXNGhvTnBKR3FqQzFKSUIwMWk4bwoxUmtOekZmVkdXOFRoaDR3NkI3NVZSNXp6TVJEZWJydG1HdnB5MnE3M0pnSUNzNWhtcHlmVUJMekFQQncxY2MrClMvdU1hU2tDZ1lFQXVOSEJzMHRFWTJXaTE2akM4ZWxPbVdPQ3hBRTdFV1p3cHZBZTJyZzRBcFNnWU0rZUo2UnIKcG4wWFptbEJCVnFpQjM4aFVYc2FFRm5YT1pNWEtYcEoyNUthakFMNDF6WGEySTF6UG1JUjBvU2JvYjhPekVwSwp5VDFFTW5ld3o0eldWOUhGbmZBSW1XeW1hcW1hNVdwSEdQNGRnS3VLQ2RXUmxmemRiVE93cGNFPQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRE96Q0NBaU9nQXdJQkFnSVFPMnZheGhCZjA4c3oxM1FsTC9QM2ZUQU5CZ2txaGtpRzl3MEJBUXNGQURBVgpNUk13RVFZRFZRUURFd3B0YVc1cGEzVmlaVU5CTUI0WERUSXdNVEl5TkRFNE1UZ3pPRm9YRFRJeE1USXlOREU0Ck1UZ3pPRm93ZkRFTE1Ba0dBMVVFQmhNQ1JWTXhGekFWQmdOVkJBb1REa05oYm5SbGNtRkdiMjV6WldOaE1SRXcKRHdZRFZRUUxFd2hUYjJaMGQyRnlaVEZCTUQ4R0ExVUVBeE00Ylc5dVoyOHRaR0l0YzNSaGRHVm1kV3h6WlhRdApjMmd4TFRJdWJXOXVaMjh0WkdJdGNtVndiR2xqWVMxemFERXVjMmhoY21ScGJtY3dnZ0VpTUEwR0NTcUdTSWIzCkRRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRRE9NR2NteTlWRnIwOFJJa1I1d21rUGpzTkpldlBON1F5Ri8zaXEKY2N6ZXpjSGZNWkxZQlFqMUoxdjFDMlBSSnlLRHhHM21UNUUwMk9xWXZiVHQyT1ljc2I0SW94bEcxL0paWjhVWAp0SWZvanVrNHROWHZDMThsWFpGOWZjQWlFQ0FUS1VZSk5UejZyanJmQ0JjRDFSUmZTcTRiTjBTQ0pJRys1UkxtCitSc3U5Q3QvcnlFUFlXV3l4MEZjWVNleHdYZVdsNTNSaHJ6NThyWFBKNGpYY3h5UVVDQ2Y0bUpuSFpiK1JRQ3IKanJZdFUwakdkakZrNWw5disrdG0xRVlITUQzTTRub3BwaG4rLy9GaGVFbkNHWVFQeFNPVHEzQmJRNjFBUTVjRQo1Zjc0SHRZSVZmaFpLUGZ4Z1pDT2U2aDkvQXA2Z0hqVkxSWHJCSUhnckdTa1pMUkhBZ01CQUFHaklEQWVNQTRHCkExVWREd0VCL3dRRUF3SUZvREFNQmdOVkhSTUJBZjhFQWpBQU1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRQ0cKMWNXYmlhV3pMT2orRDRZQ1FHMnRMR1Z6YWtRbUhwaHpFaTU4QW9jUFBqK2lIRjRNWS9GTWFrd3pUM1o4RUd4UApCd21wWUZRYW9iMzgyUVJpczBuQ1ZobFpicVZ3N2ZnL2dRb01TbVBMRUJteVNqY0ZoWS9mWGpZSHpHQm9XU056CjR3Tm9vMGM4RkRSU0s2cU9MWVRjOUZ5VDZVeTd6NGl4c3QwMk83MEpTTzdkYmJPZFNBQ2pGZGtzMmJMQm1Ya0wKcytsRnBrdGM5WjNtMzhrVDhDWG9aZ0l4bFo0TG9yUmYvMGh0WjlZVklxd0czWFF6eUJ6dXpCY25GNnk0YzFCZApMOFpXSzFSZm9lTE9LNVBYYW5UQU9LYjMvNGROTEt5VENUZ1pmbXRCb2grYkRXK2dhSy9tTC9sUGlQK29GbVdpClp6ZGVUd3h4M3VQN0JuZzQvN1Q1Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K"
đź“Ś Â The content of the secrets under the data
block have to be encoded in base64 format.
Now, everything is ready to apply our final K8s statefulset that will mutate our cluster into an authenticated cluster. With respect to part 2 of this series, the manifest has been tweaked a bit to copy to each member of the Replica Set its corresponding “keycert” file. It can be observed that new parameters have been added to convey the options related to the member authentication based on x509. In addition the parameter --tlsAllowConnectionsWithoutCertificates
no longer appears, as connections without certificates are not allowed.
apiVersion : apps/v1
kind : StatefulSet
metadata :
name : mongo-db-statefulset-sh1
labels :
mongoDB-replica : " true"
mongoDB-secured : " true"
mongoDB-sharding : " true"
annotations :
author : JMCF
namespace : sharding
spec :
selector :
matchLabels :
app : mongoDB-replica-sh1
serviceName : mongo-db-replica-sh1
replicas : 3
template :
metadata :
labels :
app : mongoDB-replica-sh1
spec :
terminationGracePeriodSeconds : 10
volumes :
- name : initial-secret-volume
secret :
secretName : mongo-secret-sh1
- name : secret-volume
emptyDir : {}
initContainers :
- name : set-file-permissions
image : busybox
env :
- name : POD_NAME
valueFrom :
fieldRef :
fieldPath : metadata.name
command :
- sh
- -c
args :
- >-
cp /var/init-secrets/tls.keycert /var/secrets/tls.keycert &&
chmod 400 /var/secrets/tls.keycert &&
chown 999:999 /var/secrets/tls.keycert;
export POD_NUMBER=${POD_NAME##*-} &&
cp /var/init-secrets/tls.cluster.$POD_NUMBER.keycert /var/secrets/tls.cluster.keycert &&
chmod 400 /var/secrets/tls.cluster.keycert &&
chown 999:999 /var/secrets/tls.cluster.keycert;
volumeMounts :
- mountPath : /var/init-secrets
name : initial-secret-volume
readOnly : true
- mountPath : /var/secrets
name : secret-volume
readOnly : false
containers :
- name : mongo-db
image : mongo:4.2.6
ports :
- containerPort : 27017
protocol : TCP
volumeMounts :
- mountPath : /data/db
name : mongo-volume-for-replica
- mountPath : /var/secrets
name : secret-volume
readOnly : true
args :
- --replSet
- $(REPLICA_SET_NAME)
- --tlsMode
- requireTLS
- --clusterAuthMode
- x509
- --tlsClusterFile
- /var/secrets/tls.cluster.keycert
- --tlsCertificateKeyFile
- /var/secrets/tls.keycert
- --tlsCAFile
- /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
terminationMessagePath : /dev/termination-log
terminationMessagePolicy : File
imagePullPolicy : IfNotPresent
envFrom :
- configMapRef :
name : mongo-config-sh1
volumeClaimTemplates :
- metadata :
name : mongo-volume-for-replica
spec :
accessModes :
- ReadWriteOnce
resources :
requests :
storage : 100Mi
If everything is fine, after applying the manifest above, the Pods associated to the statefulset should restart and finally be up and running waiting for new connections.
Testing our mongoDB Cluster
At this point in time, our mongoDB cluster can only be accessed by presenting a proper “keycert” file. In order to test, our initial client.keycert
is going to be used (corresponding to the user’s DN CN=App1,OU=Applications,O=CanteraFonseca,C=ES
). For convenience reasons, a new K8s secret is created as follows:
apiVersion : v1
kind : Secret
metadata :
name : mongo-secret-client
namespace : sharding
type : Opaque
data :
tls.client.keycert : " LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcGdJQkFBS0NBUUVBNlMyUkwwSnFVRDRONmhmWTVkMEtMelBnRnBXQkgrbUl3UVRkcjY0TUpqbnVGSXpsCmFBNFhwOWE0YytQTWRnQmhnWTl1ZGZXdy9RVlF4OVMwaDZYM0xiTGpYUi8wbG1sOW9BZzVFTDZqKzJIVEp3MDAKUEt3WXhDVzN4c1haRk5YL2hTYnR6WUtQaDhkUFJXc3d6SFBWeFhjYlR2NVFJNzJXWVRnRUh3cmNPWWVOQkRqSQovaTdnTTVUSCtvdUd0OGx0bm5nKzlqZEdCaEI1ZHFtSm00NzFOYmJuUDRkLzkzeS91aFFsQmE3U1lJcEZ3NENuCmlCT0tXaENUa0tHV1daVEpYR3hoWnFUeFBKZW8vY1pkQ21HOUNMMVQ5QWNuT050VEx4ck5MQmZ2RGRqWGd1R3MKeXNXR3BwbXI1ZW9ON0xZZTIzZXlRS0g4MEVCbHBENmZDU0VPdlFJREFRQUJBb0lCQVFDVXM0eDgrUHZYaEZ0WApTREg0RlFoanBjOW9WNXRyQUlGSHBwVEJibHN0SFpCbzVwbDl6RTdscUJjbFFNYXBFZ0Vjb0oydStDb1FrWTA4CmdyZEdNbDc1YzdWdk0rdkU2QzFIR3pkWktGcG0rN0d1bThzT1RpblZITUNnTUpnSm81YzZFT05pUmJyR3VpSWgKZ1FRenZrTTdsSU9EMHNiRXBDajhncjZPRlZ6d0NmdmhPd010dG90ZEZkTnBsRWFLN3NmZjBkSGorN0FaVWIvbAp3dGZDUXQ1Tmt0Y2s5ZFFWc3B5WVppYlNsa1FOTFpuMTF2QjNNMk4xQk9rbzBNTTdyb09rc2tLTzVvcUtjOW1lCnVldGo1YStWQW1UUWRJZkNwL1dpUDYyNE9NdXVyMDdQQUwyblNvY28xS3lPT0Z0UmxnTER6ekMwS2RvWGZ1SHgKTVRxbWNSUzVBb0dCQVAwWTBIeHJUTDdnU3FNZlF1TlRvd3JkZzdtQ1l1c3Z2QkxHQ0sxQkMxWW5hVGpZdVhWdgpCWEJYMmt2UXRkRkJvM3RaNytsUzUwWTZGcHN1SS9YR3VqcXcrNzB2dk9wTzJTRmc2T2JjK2U4QXRVNDlMcDAvCk9uaTV2eC9oOHo2Q29RR1RBN3dMcnlGRWsrbVVBN3dZUVNQWnREL0xxbDFGWEZHQlRkTDhZR24zQW9HQkFPdmEKUTI5R2NRYkJrdnVXakRsT1lvVFJvVXJ4NmpXVzMybStTNkx6OHRjNDFKUitMRWMvOEQ3djc1Y2ZkRHFYYkxnVwp4VVdEcWNUaldKM3o1OGN2U0dBZlZMYjVxTGcyZGhFMUlWRVlsYzhSZzIrQlFPL2JFNy9sM3hua055bi93NDV6Cit0SytudkFpL284Nnh2eEwvV05yWm55WGtsdkd4QVc2dDhpdTFEL3JBb0dCQUpRM011aVp3WkRLTW90Q1pGNVIKL1ZvQWpRSlhLK3lFd01QUnV3VVM0VHVyeXIvaWt3RUZhZzczTTd4UVZobGNNZ3VyaUlaLzZUWkVFRGNDRjBiNApBTmtjQ2VBcGs1MDNYWXBoZ1NLcFo2Z2lKd3JSWTNuc3JDWkV5SHM0UzhWZ3BEOFN4QTRjWFl2QzZFZlNTVG1lCmpvOGJENmFJYzVVNWFDM0c1amRYV25MVEFvR0JBTHl6bGU2cTZuV2dYUXhFU0k3MUl5Zm5YV2hNSTdxYXFzZTkKQkdFdFUyZFZSZWhGQndJK3F1YUFMQzY2Y05FTUpHVXBlczZDYUV0cUpwWEI5dmpMNE5sZlYvVkp6TzhPUytxNgptcHg2MGltcGRvSzVaSTVEdHdwN1RjUTJidGlBbFNNZHNsbjVQOHNjQkpYdVRoVEFhOHltdW9vRzc0ZlVnVE9nClQ3a1dBQ1hmQW9HQkFNUXM0eUtKM0ZXYmFtc0NINllOUENuTVNnM3lRSEhYSldjcklIa3RMcFIxRm5kL29uczcKSmNha0tDSTRMZmhSL09VR0ZubUdVa1hrbzl3T3BndlZQb1JlblB3Uko0eVBXODl3aE5BZ3B1TGlJQ3pYVHZjUgpRZzJXSVAwRDJLOFdERmQwN1RNZ1FpbHNWeG8wcHlNVVZ5N3ZFanhFMDhKM21PaDM2Y3duYjV6RgotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJREREQ0NBZlNnQXdJQkFnSVJBTzh5SStPb1JxWERCTWxkT2pJazcrUXdEUVlKS29aSWh2Y05BUUVMQlFBdwpGVEVUTUJFR0ExVUVBeE1LYldsdWFXdDFZbVZEUVRBZUZ3MHlNREV5TWpVeE5qRTRNVFJhRncweU1URXlNalV4Ck5qRTRNVFJhTUV3eEN6QUpCZ05WQkFZVEFrVlRNUmN3RlFZRFZRUUtFdzVEWVc1MFpYSmhSbTl1YzJWallURVYKTUJNR0ExVUVDeE1NUVhCd2JHbGpZWFJwYjI1ek1RMHdDd1lEVlFRREV3UkJjSEF4TUlJQklqQU5CZ2txaGtpRwo5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBNlMyUkwwSnFVRDRONmhmWTVkMEtMelBnRnBXQkgrbUl3UVRkCnI2NE1Kam51Rkl6bGFBNFhwOWE0YytQTWRnQmhnWTl1ZGZXdy9RVlF4OVMwaDZYM0xiTGpYUi8wbG1sOW9BZzUKRUw2aisySFRKdzAwUEt3WXhDVzN4c1haRk5YL2hTYnR6WUtQaDhkUFJXc3d6SFBWeFhjYlR2NVFJNzJXWVRnRQpId3JjT1llTkJEakkvaTdnTTVUSCtvdUd0OGx0bm5nKzlqZEdCaEI1ZHFtSm00NzFOYmJuUDRkLzkzeS91aFFsCkJhN1NZSXBGdzRDbmlCT0tXaENUa0tHV1daVEpYR3hoWnFUeFBKZW8vY1pkQ21HOUNMMVQ5QWNuT050VEx4ck4KTEJmdkRkalhndUdzeXNXR3BwbXI1ZW9ON0xZZTIzZXlRS0g4MEVCbHBENmZDU0VPdlFJREFRQUJveUF3SGpBTwpCZ05WSFE4QkFmOEVCQU1DQmFBd0RBWURWUjBUQVFIL0JBSXdBREFOQmdrcWhraUc5dzBCQVFzRkFBT0NBUUVBCktZc3FhdFhna1dETWRLUitkbVBGRTBNOG9zS1VnY1lCNkEvNEUvWnRWSG5Ndk1QTFJ3bmF4SGJNTFcza2E5NzQKeWYyT2F3THZ2aG92MkpiT0k4U0x6Q29PandnblBrdlFqTFJDU25wM3FEYUZtSGdaUjNKMENFM0lpaDV6UldTSAorQXRwOENpRnNsZk9hMTdWckZDcFdPbEVvWWttNFBwbk5xVVZMOWprQ1NRTTc1Rk5XVmZ3eE83RTFmK0JFUjliCmtOWGk0YmZaQUFSWTZsUXAxMU10MVpRT1ZGbTNudUpoa3JhY1NRU2J1T3FVS3p2bml0WWlWVnNNVjAzdC9oQ2YKU2NEUWtoZkZJQ3lmT2o3VHVseUFzTDB1b3pNQUFOUTlPcWYwSnlEQkh4VWFpVTBkSm9hWnVxVkdlcWl2WmgzegpSTFI2dzc1dFViL3pFNW5yR0MrQm13PT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo="
It contains the keycert to be presented when connecting to our mongoDB cluster.
As we would like to continue using kubectl and all the K8s facilities, we need to define a K8s Pod manifest fragment as follows:
{
"apiVersion" : "v1" ,
"spec" : {
"volumes" : [
{
"name" : "initial-secret-volume" ,
"secret" : {
"secretName" : "mongo-secret-client"
}
}
],
"containers" : [
{
"name" : "tm-mongo-pod-mongos" ,
"image" : "mongo:4.2.6" ,
"stdin" : true ,
"tty" : true ,
"command" : [ "mongo" ],
"args" : [
"--verbose" ,
"--tls" ,
"--tlsCAFile" ,
"/var/run/secrets/kubernetes.io/serviceaccount/ca.crt" ,
"--tlsCertificateKeyFile" ,
"/var/init-secrets/tls.client.keycert" ,
"mongos.sharding.svc.cluster.local"
],
"volumeMounts" : [
{
"mountPath" : "/var/init-secrets" ,
"name" : "initial-secret-volume" ,
"readOnly" : true
}
]
}
]
}
}
It can be observed that a volume with our keycert file secret has been properly mapped to be used when connecting to our cluster by executing:
kubectl run tm-mongo-pod --image = mongo:4.2.6 --rm = true -it --restart = Never --namespace = sharding --overrides = " $( cat mongo-client.json) "
After executing the command above, we will be under the mongo shell console prompt but not authenticated yet. In order to authenticate the following Javascript sentence has to be executed (at this time, against the PRIMARY
Replica Set member):
db . getSiblingDB ( " $external " ). auth (
{
mechanism : " MONGODB-X509 " ,
user : " CN=App1,OU=Applications,O=CanteraFonseca,C=ES "
}
);
db . getSiblingDB ( " $external " ). auth (
{
mechanism : " MONGODB-X509 " ,
user : " CN=mongos.sharding,OU=Software,O=CanteraFonseca,C=ES "
}
);
đź“Ś Â We can authenticate as, on the command line, we have already presented a keycert file as a proof of our identity (CN=App1,OU=Applications,O=CanteraFonseca,C=ES
).
Once we are authenticated we can create a new database, named test
, and insert a document into a collection testCollection
as follows:
use test ;
db . testCollection . insertOne ({ " type " : " Building " , " name " : " Eiffel Tower " });
db . testCollection . find ({});
Later, we can check that the data has been propagated to all members of our Replica Set by connecting to a SECONDARY
cluster member, authenticating against it (using the procedure describe above), and querying the data on the test
database (at this step don’t forget to issue rs.slaveOk()
before querying).
🔌 Sharded mongoDB
To be developed.
https://docs.mongodb.com/manual/_images/sharded-cluster-production-architecture.bakedsvg.svg
https://docs.mongodb.com/manual/_images/sharded-cluster-mixed.bakedsvg.svg
https://docs.mongodb.com/manual/_images/sharded-cluster-production-architecture.bakedsvg.svg
sh.splitAt( “tsharding.col1”, { age: 50 } )
use tsharding;
db.adminCommand( {
enableSharding: “tsharding”
} );
db.col1.createIndex({ age: 1})
db.adminCommand( { shardCollection: “tsharding.col1”, key: { age: 1 } } );
🖊️ Conclusions
Kubernetes provides powerful primitives to deploy a clustered mongoDB datastore service. Furthermore, we can deploy a secured and sharded mongoDB so that we can give production-grade support to IoT and Big Data Applications which demand higher scalability.
🗒️ Feedback
Please enable JavaScript to view the comments powered by Disqus.