Kubernetes ConfigMaps & Secrets

Dengan environment variable, kita tidak perlu lagi melakukan hardcoded terhadap image docker yang akan dideploy dengan kubernetes, tetapi ada kekurangan dari teknik ini. Jika ingin menganti variablenya, kita harus melakukan deploy ulang atau memodifikasi deploymentnya. Yang lebih buruk adalah jika kita menggunakan variabel tersebut untuk beberapa namespaces dan deployment, ganti satu persatu.

Kubernetes menawarkan solusi untuk itu, yaitu ConfigMaps (untuk data yang tidak bersifat rahasia) dan Secrets (untuk data yang bersifat rahasia, password,token,etc).

Buat configmap :

kubectl create configmap database --from-literal=user=dbuser --from-literal=password=dbpassword

atau

apiVersion: v1
kind: ConfigMap
metadata:
  name: database
data:
  password: dbpassword
  user: dbuser

Ada beberapa metode membuat sebuah configmap

sama halnya dengan configmap, pembuatan secret adalah hal yang hampir mirip dengan configmap :

Buat secret :

kubectl create secret generic database-secret --from-literal=rootpwd=myrootpwd --from-literal=database=db1

Mari kita gunakan configmap dan secret untuk membuat sebuah deployment

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: mysql-database
spec:
  replicas: 1
  template:
    metadata:
      labels:
        apps: mysql-database
    spec:
     containers:
      - name: mysql-database
        image: mysql/mysql-server
        ports:
        - containerPort: 3306
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: database-secret
              key: rootpwd
        - name: MYSQL_DATABASE
          valueFrom:
            secretKeyRef:
              name: database-secret
              key: database
        - name: MYSQL_USER
          valueFrom:
            configMapKeyRef:
              name: database
              key: user
        - name: MYSQL_PASSWORD
          valueFrom:
            configMapKeyRef:
              name: database
              key: password

jangan lupa buat service untuk expose deploymentnya

kind: Service
apiVersion: v1
metadata:
  name: mysql-server
spec:
  ports:
  - port: 3306
    protocol: TCP
  selector:
    apps: mysql-database

Lakukan Deploy

ubuntu@master:~/cm-secret$ kubectl create -f deployment.yaml 
deployment.extensions "mysql-database" created
ubuntu@master:~/cm-secret$ kubectl create -f service.yaml 
service "mysql-server" created
ubuntu@master:~/cm-secret$ kubectl get deployment
NAME             DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
mysql-database   1         1         1            1           15s
ubuntu@master:~/cm-secret$ kubectl get pod
NAME                             READY     STATUS    RESTARTS   AGE
mysql-database-788fd8f4d-qg5v7   1/1       Running   0          20s
ubuntu@master:~/cm-secret$ kubectl get svc
NAME           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
kubernetes     ClusterIP   10.96.0.1       <none>        443/TCP    7d
mysql-server   ClusterIP   10.103.40.208   <none>        3306/TCP   17s

Untuk melakukan testing terhadap database, gunakan script python

import mysql.connector
from mysql.connector import Error
 
 
def connect():
    """ Connect to MySQL database """
    try:
        conn = mysql.connector.connect(host='10.103.40.208',
                                       database='db1',
                                       user='dbuser',
                                       password='dbpassword')
        if conn.is_connected():
            print('Connected to MySQL database')
 
    except Error as e:
        print(e)
 
    finally:
        conn.close()
 
 
if __name__ == '__main__':
    connect()

coba jalankan :

ubuntu@master:~/cm-secret$ python checkdb.py 
Connected to MySQL database
ubuntu@master:~/cm-secret$

Jika module belum terinstall

pip install mysql-connector-python

bisa juga cek secara langsung dengan masuk kedalam container

ubuntu@master:~/cm-secret$ kubectl get pod
NAME                             READY     STATUS    RESTARTS   AGE
mysql-database-788fd8f4d-qg5v7   1/1       Running   0          3m
ubuntu@master:~/cm-secret$ kubectl exec mysql-database-788fd8f4d-qg5v7 -it -- bash 
bash-4.2# mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 8.0.11 MySQL Community Server - GPL

Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| db1                |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

untuk menganti salah satu value didalam configmap atau secret :

kubectl create configmap database --from-literal=user=userdb --from-literal=password=dbpassword -o yaml --dry-run | kubectl replace -f -

Lalu restart pod, cukup delete pod tersebut (dengan deployment pod baru akan muncul)

buntu@master:~/cm-secret$ kubectl delete pod mysql-database-788fd8f4d-qg5v7
pod "mysql-database-788fd8f4d-qg5v7" deleted
ubuntu@master:~/cm-secret$ kubectl get pod
NAME                             READY     STATUS              RESTARTS   AGE
mysql-database-788fd8f4d-vw4g5   0/1       ContainerCreating   0          3s
ubuntu@master:~/cm-secret$ kubectl get pod
NAME                             READY     STATUS    RESTARTS   AGE
mysql-database-788fd8f4d-vw4g5   1/1       Running   0          39s
ubuntu@master:~/cm-secret$ python checkdb.py 
1045 (28000): Access denied for user 'dbuser'@'10.244.0.0' (using password: YES)

perhatikan bahwa ada access denied of user ‘dbuser’ karena sudah diganti dengan userdb.

Comments are closed.