Quản lý Tài nguyên Secret và ConfigMap trong Kubernetes

一、Secret

1.1 Khái niệm

Secret là tài nguyên Kubernetes được dùng để lưu trữ dữ liệu nhạy cảm như mật khẩu, token, khóa và các thông tin bảo mật khác. Mặc dù dữ liệu này có thể được lưu trữ trực tiếp trong Pod hoặc hình ảnh container, việc sử dụng Secret giúp kiểm soát cách sử dụng dữ liệu tốt hơn và giảm thiểu rủi ro lộ thông tin.

1.2 Ba loại Secret chính

●kubernetes.io/service-account-token: Do Kubernetes tự động tạo ra, dùng để truy cập APIServer. Pod mặc định sử dụng Secret này để giao tiếp với APIServer và tự động mount vào thư mục /run/secrets/kubernetes.io/serviceaccount của Pod; ●Opaque: Secret có định dạng base64 encoding, dùng để lưu trữ mật khẩu, khóa do người dùng tự định nghĩa, là loại Secret mặc định; ●kubernetes.io/dockerconfigjson: Dùng để lưu trữ thông tin xác thực cho Docker registry riêng tư.

1.3 Ba cách Pod sử dụng Secret

Pod cần tham chiếu đến Secret trước khi sử dụng:

●Làm tệp trong volume được mount vào một hoặc nhiều container; ●Làm biến môi trường của container; ●Được kubelet sử dụng khi kéo hình ảnh cho Pod.

Ứng dụng: Thông tin xác thực
Tài liệu chính thức:
https://kubernetes.io/docs/concepts/configuration/secret/

//Tạo Secret

  1. Tạo Secret bằng lệnh kubectl create secret
echo -n 'nguyenvan' > username.txt
echo -n 'xzy7890' > password.txt

kubectl create secret generic mysecret --from-file=username.txt --from-file=password.txt

kubectl get secrets
NAME                  TYPE                                  DATA   AGE
default-token-8pqp6   kubernetes.io/service-account-token   3      3d1h
mysecret              Opaque                                2      51s

kubectl describe secret mysecret
Name:         mysecret
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
password.txt:  7 bytes
username.txt:  8 bytes

//Các lệnh get hoặc describe sẽ không hiển thị nội dung thực tế của secret, đây là biện pháp bảo vệ dữ liệu

  1. Tạo Secret với nội dung đã mã hóa base64
echo -n nguyenvan | base64
bmd1eW5ldmFuCg==

echo -n xzy7890 | base64
eHp5Nzg5MAo=

vim secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: mysecret1
type: Opaque
data:
  username: bmd1eW5ldmFuCg==
  password: eHp5Nzg5MAo==

kubectl create -f secret.yaml 

kubectl get secrets
NAME                  TYPE                                  DATA   AGE
default-token-8pqp6   kubernetes.io/service-account-token   3      3d1h
mysecret              Opaque                                2      43m
mysecret1             Opaque                                2      6s

kubectl get secret mysecret1 -o yaml
apiVersion: v1
data:
  password: eHp5Nzg5MAo==
  username: bmd1eW5ldmFuCg==
kind: Secret
metadata:
  creationTimestamp: 2021-05-24T09:11:18Z
  name: mysecret1
  namespace: default
  resourceVersion: "45641"
  selfLink: /api/v1/namespaces/default/secrets/mysecret1
  uid: fffb7902-bc6f-11eb-acba-000c29d88bba
type: Opaque

//Cách sử dụng

  1. Mount Secret vào Volume dưới dạng tệp trong thư mục của Pod
vim secret-test.yaml
apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: nginx
    image: nginx
    volumeMounts:
    - name: secrets
      mountPath: "/etc/secrets"
      readOnly: true
  volumes:
  - name: secrets
    secret:
      secretName: mysecret

kubectl create -f secret-test.yaml

kubectl get pods
NAME         READY   STATUS    RESTARTS   AGE
seret-test   1/1     Running   0          16s

kubectl exec -it seret-test bash
 # cd /etc/secrets/
 # ls
password.txt  username.txt
 # vi password.txt 
 # vi username.txt

Khi sử dụng lệnh kubectl exec -it seret-test bash để vào container và dùng lệnh vim, bạn sẽ gặp lỗi:

Giải pháp:

Lúc này bạn cần cài đặt vim, nhưng khi gõ lệnh apt-get install vim, hệ thống sẽ báo:

Sau đó nhập lệnh apt-get update để cập nhật, và sau khi cập nhật xong, thực hiện lại lệnh apt-get install vim để cài đặt thành công.

  1. Xuất Secret thành biến môi trường
vim secret-test1.yaml
apiVersion: v1
kind: Pod
metadata:
  name: mypod1
spec:
  containers:
  - name: nginx
    image: nginx
    env:
      - name: TEST_USER
        valueFrom:
          secretKeyRef:
            name: mysecret1
            key: username
      - name: TEST_PASSWORD
        valueFrom:
          secretKeyRef:
            name: mysecret1
            key: password

kubectl apply -f secret-test1.yaml 

kubectl get pods
NAME         READY   STATUS    RESTARTS   AGE
mypod1       1/1     Running   0          77s

kubectl exec -it mypod bash
 # echo $TEST_USER
nguyenvan
 # echo $TEST_PASSWORD
xzy7890

二、ConfigMap

2.1 Khái niệm

Tương tự như Secret, nhưng ConfigMap được dùng để lưu trữ thông tin cấu hình không cần mã hóa. Tính năng ConfigMap được giới thiệu trong phiên bản Kubernetes 1.2, nhiều ứng dụng đọc thông tin cấu hình từ tệp cấu hình, tham số dòng lệnh hoặc biến môi trường. API ConfigMap cung cấp cơ chế chèn thông tin cấu hình vào container, ConfigMap có thể được dùng để lưu trữ thuộc tính đơn lẻ, toàn bộ tệp cấu hình hoặc đối tượng nhị phân JSON. Ứng dụng: Cấu hình ứng dụng

2.1.1 Tạo ConfigMap

1. Sử dụng thư mục để tạo

mkdir /opt/configmap/
 
vim /opt/configmap/game.properties
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30
 
vim /opt/configmap/ui.properties
color.good=purple
color.bad=yellow
allow.textmode=true
how.nice.to.look=fairlyNice

ls /opt/configmap/
game.properties
ui.properties

kubectl create configmap game-config --from-file=/opt/configmap/

//--from-file chỉ định tất cả các tệp trong thư mục sẽ được dùng để tạo các cặp khóa-giá trị trong ConfigMap, tên khóa là tên tệp, giá trị là nội dung tệp

kubectl get cm
NAME          DATA   AGE
game-config   2      10s

kubectl get cm game-config -o yaml
apiVersion: v1
data:
  game.properties: |
    enemies=aliens
    lives=3
    enemies.cheat=true
    enemies.cheat.level=noGoodRotten
    secret.code.passphrase=UUDDLRLRBABAS
    secret.code.allowed=true
    secret.code.lives=30
  ui.properties: |
    color.good=purple
    color.bad=yellow
    allow.textmode=true
    how.nice.to.look=fairlyNice
kind: ConfigMap
metadata:
  creationTimestamp: 2021-05-25T06:49:18Z
  name: game-config
  namespace: default
  resourceVersion: "87803"
  selfLink: /api/v1/namespaces/default/configmaps/game-config
  uid: 541b5302-bd25-11eb-acba-000c29d88bba

2. Sử dụng tệp để tạo

Chỉ định một tệp duy nhất để tạo ConfigMap từ tệp đó Tham số --from-file có thể sử dụng nhiều lần, tức là có thể sử dụng hai lần để chỉ định hai tệp cấu hình trong ví dụ trên, kết quả sẽ giống như chỉ định toàn bộ thư mục

kubectl create configmap game-config-2 --from-file=/opt/configmap/game.properties --from-file=/opt/configmap/ui.properties

kubectl get configmaps game-config-2 -o yaml

kubectl describe cm game-config-2

3. Sử dụng giá trị trực tiếp để tạo

Sử dụng giá trị trực tiếp để tạo, sử dụng tham số --from-literal để truyền thông tin cấu hình, tham số này có thể sử dụng nhiều lần, định dạng như sau

kubectl create configmap special-config --from-literal=special.how=very --from-literal=special.type=good

kubectl get configmaps special-config -o yaml
apiVersion: v1
data:
  special.how: very                    #cấu trúc khóa-giá trị
  special.type: good
kind: ConfigMap
metadata:
  creationTimestamp: 2021-05-25T06:59:37Z
  name: special-config
  namespace: default
  resourceVersion: "88610"
  selfLink: /api/v1/namespaces/default/configmaps/special-config
  uid: c4f45936-bd26-11eb-acba-000c29d88bba


kubectl delete cm --all
kubectl delete pod --all

2.1.2 Sử dụng ConfigMap trong Pod

1. Sử dụng ConfigMap để thay thế biến môi trường

vim env.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: special-config
  namespace: default
data:
  special.how: very
  special.type: good
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: env-config
  namespace: default
data:
  log_level: INFO


kubectl create -f env.yaml 

kubectl get cm
NAME             DATA   AGE
env-config       1      6s
special-config   2      6s

//Tạo Pod

vim test-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
  - name: busybox
    image: busybox:1.28.4
    command: [ "/bin/sh", "-c", "env" ]
    env:
      - name: SPECIAL_HOW_KEY
        valueFrom:
          configMapKeyRef:
            name: special-config
            key: special.how
      - name: SPECIAL_TYPE_KEY
        valueFrom:
          configMapKeyRef:
            name: special-config
            key: special.type
    envFrom:
      - configMapRef:
          name: env-config
  restartPolicy: Never


kubectl create -f test-pod.yaml

kubectl get pods
NAME         READY   STATUS      RESTARTS   AGE
pod-test     0/1     Completed   0          33s
kubectl logs pod-test
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.0.0.1:443
HOSTNAME=pod-test
SHLVL=1
SPECIAL_HOW_KEY=very            #gán giá trị biến SPECIAL_HOW_KEY là special.how: very của special-config
HOME=/root
SPECIAL_TYPE_KEY=good            #gán giá trị biến SPECIAL_TYPE_KEY là special.type: good của special-config
KUBERNETES_PORT_443_TCP_ADDR=10.0.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
log_level=INFO                    #nhập biến log_level: INFO từ env-config
KUBERNETES_PORT_443_TCP=tcp://10.0.0.1:443
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_SERVICE_HOST=10.0.0.1
PWD=/

2. Sử dụng ConfigMap để đặt tham số dòng lệnh

vim test-pod2.yaml
apiVersion: v1
kind: Pod
metadata:
  name: test-pod2
spec:
  containers:
  - name: busybox
    image: busybox:1.28.4
    command: 
    - /bin/sh
    - -c
    - echo "$(SPECIAL_HOW_KEY) $(SPECIAL_TYPE_KEY)"
    env:
      - name: SPECIAL_HOW_KEY
        valueFrom:
          configMapKeyRef:
            name: special-config
            key: special.how
      - name: SPECIAL_TYPE_KEY
        valueFrom:
          configMapKeyRef:
            name: special-config
            key: special.type
    envFrom:
      - configMapRef:
          name: env-config
  restartPolicy: Never


kubectl create -f test-pod2.yaml

kubectl get pods
NAME        READY   STATUS      RESTARTS   AGE
test-pod2   0/1     Completed   0          34s

kubectl logs test-pod2
very good

3. Sử dụng ConfigMap qua plugin Volume

Sử dụng ConfigMap trong volume, tức là điền tệp vào volume, trong tệp này, khóa là tên tệp, giá trị là nội dung tệp

vim test-pod3.yaml
apiVersion: v1
kind: Pod
metadata:
  name: test-pod3
spec:
  containers:
  - name: busybox
    image: busybox:1.28.4
    command: [ "/bin/sh", "-c", "sleep 36000" ]
    volumeMounts:
    - name: config-volume
      mountPath: /etc/config
  volumes:
    - name: config-volume
      configMap:
        name: special-config
  restartPolicy: Never


kubectl create -f test-pod3.yaml 

kubectl get pods
NAME        READY   STATUS      RESTARTS   AGE
test-pod3   1/1     Running     0          5s

kubectl exec -it test-pod3 sh
 # cd /etc/config/
 # ls
special.how   special.type
 # vi special.how 
 # vi special.type 

2.1.3 Cập nhật nóng ConfigMap

vim test-pod4.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: log-config
  namespace: default
data:
  log_level: INFO
---
apiVersion: extensions/v1beta1     #vì phiên bản k8s của tôi là 1.16.2, trong phiên bản này Deployment đã bị loại bỏ khỏi extensions/v1beta1
kind: Deployment
metadata:
  name: my-nginx
spec:
  replicas: 1
  template:
    metadata:
      labels:
        run: my-nginx
    spec:
      containers:
      - name: my-nginx
        image: nginx
        ports:
        - containerPort: 80
        volumeMounts:
        - name: config-volume
          mountPath: /etc/config
      volumes:
        - name: config-volume
          configMap:
            name: log-config


kubectl apply -f test-pod5.yaml

kubectl get pods 
NAME                        READY   STATUS    RESTARTS   AGE
my-nginx-76b6489f44-6dwxh   1/1     Running   0          46s
kubectl exec -it my-nginx-76b6489f44-6dwxh -- cat /etc/config/log_level
INFO

kubectl edit configmap log-config
apiVersion: v1
data:
  log_level: DEBUG        #thay INFO thành DEBUG
kind: ConfigMap
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","data":{"log_level":"DEBUG"},"kind":"ConfigMap","metadata":{"annotations":{},"name":"log-config","namespace":"default"}}            #thay INFO thành DEBUG
  creationTimestamp: 2021-05-25T07:59:18Z
  name: log-config
  namespace: default
  resourceVersion: "93616"
  selfLink: /api/v1/namespaces/default/configmaps/log-config
  uid: 1b8115de-bd2f-11eb-acba-000c29d88bba

//Chờ khoảng 10 giây, dữ liệu trong Volume sử dụng ConfigMap sẽ được đồng bộ cập nhật

kubectl exec -it my-nginx-76b6489f44-6dwxh -- cat /etc/config/log_level
DEBUG

2.1.4 Cập nhật Pod khi ConfigMap thay đổi

Việc cập nhật ConfigMap hiện tại sẽ không kích hoạt cập nhật rolling cho Pod liên quan, bạn có thể thêm version/config vào .spec.template.metadata.annotations để kích hoạt cập nhật rolling mỗi khi version/config được thay đổi

kubectl patch deployment my-nginx --patch '{"spec": {"template": {"metadata": {"annotations": {"version/config": "20210525" }}}}}'
kubectl get pods 
NAME                        READY   STATUS              RESTARTS   AGE
my-nginx-665dd4dc8c-j4k9t   0/1     ContainerCreating   0          4s
my-nginx-76b6489f44-6dwxh   0/1     Terminating         0          10m

kubectl get pods 
NAME                        READY   STATUS    RESTARTS   AGE
my-nginx-665dd4dc8c-j4k9t   1/1     Running   0          74s

Lưu ý: Sau khi cập nhật ConfigMap: ●Các biến môi trường sử dụng ConfigMap sẽ không được đồng bộ cập nhật. ●Dữ liệu trong Volume sử dụng ConfigMap cần một khoảng thời gian (khoảng 10 giây theo thực tế) để được đồng bộ cập nhật.

Thẻ: Kubernetes Secret ConfigMap Container-Orchestration

Đăng vào ngày 4 tháng 8 lúc 14:13