Tìm hiểu cách định cấu hình ứng dụng Kubernetes bằng ConfigMap

cloudFun

"Tách cấu hình khỏi code" là một trong những nguyên lý của các ứng dụng 12 yếu tố. Ngoại hóa những thứ có thể thay đổi sẽ giúp các ứng dụng dễ dàng di chuyển hơn. Điều này rất quan trọng trong thế giới Kubernetes - nơi các ứng dụng của được đóng gói dưới dạng Docker image. Kubernetes ConfigMap cho phép cấu hình trừu tượng từ code và hơn hết là Docker image.

kube-configmap-secret-deployment.png


Bài viết này sẽ cung cấp hướng dẫn thực hành về các tùy chọn liên quan đến cấu hình ứng dụng có sẵn trong Kubernetes.

Như mọi khi, code có sẵn trên GitHub.
Để cấu hình ứng dụng trong Kubernetes, có thể sử dụng:
  • Biến environment cũ tốt
  • ConfigMap
  • Secret — điều này sẽ được đề cập trong bài viết tiếp theo
Cần có một cluster Kubernetes để bắt đầu. Đây có thể là một cluster cục bộ, một node đơn giản sử dụng minikube, Docker cho Mac, v.v. hoặc dịch vụ Kubernetes được quản lý từ Azure (AKS), Google, AWS, v.v. Để truy cập cluster Kubernetes, sẽ cần kubectl, cài đặt nó khá dễ.
ví dụ. để cài đặt kubectl cho Mac, chỉ cần
curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/darwin/amd64/kubectl && \
chmod +x ./kubectl && \
sudo mv ./kubectl /usr/local/bin/kubectl


Sử dụng biến environment để cấu hình
Hãy bắt đầu với một ví dụ đơn giản để xem cách sử dụng các biến environment, bằng cách chỉ định chúng trực tiếp trong spec Pod.
Mã:
apiVersion: v1
kind: Pod
metadata:
  name: pod1
spec:
  containers:
  - name: nginx
    image: nginx
    env:
      - name: ENVVAR1
        value: value1
      - name: ENVVAR2
        value: value2
Lưu ý cách xác định hai biến trong
spec.containers.env — ENVVAR1ENVVAR2 với các giá trị value1 value2 tương ứng.
Hãy bắt đầu bằng cách tạo Pod nhờ sử dụng file YAML được chỉ định ở trên.
Pod chỉ là một tài nguyên hoặc đối tượng Kubernetes. File YAML mô tả trạng thái mong muốn của nó cùng với một số thông tin cơ bản - nó cũng được gọi là một manifest, spec (viết tắt cho specification) hoặc definition.
Sử dụng lệnh kubectl apply để gửi thông tin Pod cho Kubernetes.
Để đơn giản, file YAML đang được tham chiếu trực tiếp từ GitHub repo, nhưng cũng có thể tải file xuống máy và sử dụng nó theo cách tương tự
$ kubectl apply -f https://raw.githubusercontent.com/abhirockzz/kubernetes-in-a-nutshell/master/configuration/kin-config-envvar-in-pod.yaml
pod/pod1 created


Để kiểm tra các biến environment, sẽ cần thực thi lệnh "bên trong" Pod bằng cách sử dụng kubectl exec —  sẽ thấy các biến xuất hiện trong Pod definition.
Ở đây, grep được sử dụng để lọc (các) biến được quan tâm
$ kubectl exec pod1 -it -- env | grep ENVVAR
ENVVAR1=value1
ENVVAR2=value2


kubectl exec là gì? Nói một cách đơn giản, nó cho phép thực thi một lệnh trong container cụ thể của Pod. Trong trường hợp này, Pod có một container duy nhất, vì vậy không cần chỉ định

Sử dụng ConfigMaps
Cách thức hoạt động là cấu hình được xác định trong đối tượng ConfigMaps, sau đó được tham chiếu trong Pod (hoặc Deployment).
Dưới đây các cách được dùng thể tạo ConfigMap
Sử dụng manifest file
Nó có thể tạo một ConfigMap cùng với config data được lưu trữ dưới dạng cặp khóa-giá trị trong phần data của definition.
Mã:
apiVersion: v1
kind: ConfigMap
metadata:
  name: simpleconfig
data:
  foo: bar
  hello: world
---
apiVersion: v1
kind: Pod
metadata:
  name: pod2
spec:
  containers:
  - name: nginx
    image: nginx
    env:
      - name: FOO_ENV_VAR
        valueFrom:
          configMapKeyRef:
            name: simpleconfig
            key: foo
      - name: HELLO_ENV_VAR
        valueFrom:
          configMapKeyRef:
            name: simpleconfig
            key: hello
Trong manifest trên:
  • ConfigMap có tên simpleconfig chứa hai phần dữ liệu (khóa-giá trị)  — hello=worldfoo=bar
  • simpleconfig được tham chiếu bởi một Pod (pod2; các khóa hello foo được sử dụng như các biến environment HELLO_ENV_VARFOO_ENV_VAR tương ứng.
Lưu ý rằng định nghĩa của Pod ConfigMap đã có trong file YAML và phân tách bằng ---
Tạo ConfigMap và xác nhận rằng các biến environment đã được chọn
$ kubectl apply -f https://raw.githubusercontent.com/abhirockzz/kubernetes-in-a-nutshell/master/configuration/kin-config-envvar-configmap.yaml
configmap/config1 created
pod/pod2 created
$ kubectl get configmap/config1
NAME DATA AGE
config1 2 18s
$ kubectl exec pod2 -it -- env | grep _ENV_
FOO_ENV_VAR=bar
HELLO_ENV_VAR=world


Sử dụng envVar
Config data (foo hello) được tiêu thụ bằng cách tham chiếu riêng biệt, nhưng có một cách dễ dàng hơn! Có thể sử dụng envFrom trong manifest để tham chiếu trực tiếp tất cả dữ liệu khóa-giá trị trong ConfigMap
Khi sử dụng dữ liệu ConfigMap theo cách này, khóa được sử dụng trực tiếp làm tên biến environment. Đó là lý do tại sao cần tuân theo quy ước đặt tên, tức là mỗi khóa phải bao gồm các ký tự chữ và số ‘-’, ‘_’ hoặc ‘.’
Mã:
apiVersion: v1
kind: ConfigMap
metadata:
  name: config2
data:
  FOO_ENV: bar
  HELLO_ENV: world
---
apiVersion: v1
kind: Pod
metadata:
  name: pod3
spec:
  containers:
  - name: nginx
    image: nginx
    envFrom:
      - configMapRef:
         name: config2
Cũng giống như trước đây, cần tạo Pod ConfigMap và xác nhận sự tồn tại của các biến environment
$ kubectl apply -f https://raw.githubusercontent.com/abhirockzz/kubernetes-in-a-nutshell/master/configuration/kin-config-envvar-with-envFrom.yaml
configmap/config2 created
pod/pod3 created
$ kubectl get configmap/config2
NAME DATA AGE
config2 2 25s
$ kubectl exec pod3 -it -- env | grep _ENV
HELLO_ENV=world
FOO_ENV=bar


Dữ liệu cấu hình dưới dạng file
Một cách thú vị khác để sử dụng config data là bằng cách trỏ đến ConfigMap trong phần spec.volumes của thông số Deployment hoặc Pod.

Nếu không biết Volumes (trong Kubernetes) là gì, đừng lo lắng. Chúng sẽ được nhắc đến trong các blog sắp tới. Hiện tại, chỉ cần hiểu rằng volumes là một cách trừu tượng hóa container khỏi hệ thống lưu trữ cơ bản, ví dụ: nó có thể là một đĩa cục bộ hoặc trong đám mây như Azure Disk, GCP Persistent Disk, v.v
Mã:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: testapp
spec:
  selector:
    matchLabels:
      app: testapp
  replicas: 1
  template:
    metadata:
      labels:
        app: testapp
    spec:
      volumes:
        - name: config-data-volume
          configMap:
            name: app-config
      containers:
      - name: testapp
        image: testapp
        volumeMounts:
        - mountPath: /config
          name: config-data-volume
Trong spec trên, hãy chú ý đến phần spec.volumes - lưu ý rằng nó đề cập đến một ConfigMap hiện có. Mỗi khóa trong ConfigMap được thêm dưới dạng file vào thư mục được chỉ định trong spec ví dụ như spec.containers.volumeMount.mountPath và giá trị không có gì ngoài nội dung của file.
Lưu ý rằng các file trong volumes được tự động cập nhật nếu ConfigMap thay đổi.
Ngoài các giá trị chuỗi cơ bản, cũng có thể sử dụng các file hoàn chỉnh (JSON, text, YAML, v.v.) làm các giá trị trong ConfigMap.
Mã:
apiVersion: v1
kind: ConfigMap
metadata:
  name: config3
data:
  appconfig.json: |
    {
      "array": [
        1,
        2,
        3
      ],
      "boolean": true,
      "number": 123,
      "object": {
        "a": "b",
        "c": "d",
        "e": "f"
      },
      "string": "Hello World"
    }
---
apiVersion: v1
kind: Pod
metadata:
  name: pod4
spec:
  containers:
  - name: nginx
    image: nginx
    env:
      - name: APP_CONFIG_JSON
        valueFrom:
          configMapKeyRef:
            name: config3
            key: appconfig.json
Trong ví dụ trên, toàn bộ JSON đã được nhúng trong trong phần dữ liệu của ConfigMap. Để thử điều này, hãy tạo Pod ConfigMap
$ kubectl apply -f https://raw.githubusercontent.com/abhirockzz/kubernetes-in-a-nutshell/master/configuration/kin-config-envvar-json.yaml
configmap/config3 created
pod/pod4 created
$ kubectl get configmap/config3
NAME DATA AGE
config3 1 11s


Như một bài tập, hãy xác nhận rằng biến environment đã được tạo trong Pod. Có vài gợi ý:
  • Tên của Pod pod4
  • Kiểm tra kỹ tên của biến environment cần tìm
kubectl CLI cũng có thể được dùng để tạo ConfigMap. Nó có thể không phù hợp cho tất cả các trường hợp sử dụng nhưng nó chắc chắn làm cho mọi thứ dễ dàng hơn nhiều

Sử dụng kubectl
Có nhiều lựa chọn:

Sử dụng --from-literal để seed config data
Các cặp khóa-giá trị sau được đặt vào ConfigMap  foo_env=barhello_env=world
$ kubectl create configmap config4 --from-literal=foo_env=bar --from-literal=hello_env=world

Sử dụng --from-file
$ kubectl create configmap config5 --from-file=/config/app-config.properties
Điều này sẽ tạo ra một ConfigMap (config5) với
  • Một khóa có cùng tên của file, tức là app-config.properties trong trường hợp này
  • Và, giá trị như nội dung của file
Có thể chọn sử dụng một khóa khác (không phải tên file) để ghi đè hành vi mặc định
$ kubectl create configmap config6 --from-file=CONFIG_DATA=/config/app-config.properties
Trong trường hợp này, CONFIG_DATA sẽ là khóa

Từ các file trong một thư mục
Có thể nhập dữ liệu từ nhiều file (trong một thư mục) vào một ConfigMap
$ kubectl create configmap config7 --from-file=/home/foo/config/

Sau cùng sẽ có
  • Nhiều khóa giống như tên file riêng lẻ
  • Giá trị sẽ là nội dung của file tương ứng
Những điều nên biết
Dưới đây là danh sách (không đầy đủ) về những điều nên ghi nhớ khi sử dụng ConfigMaps:
  • Khi xác định các biến environment ConfigMaps, có thể sử dụng chúng trong phần lệnh trong Pod spec, tức là spec.containers.command bằng cách sử dụng định dạng $(VARIABLE_NAME)
  • Cần đảm bảo rằng ConfigMap được tham chiếu trong Pod đã được tạo - nếu không, Pod sẽ không khởi động. Cách duy nhất để giải quyết vấn đề này là đánh dấu ConfigMap optional.
  • Một trường hợp khác có thể ngăn Pod khởi động là tham chiếu một khóa không tồn tại trong ConfigMap.
Tham khảo ConfigMap API

Nguồn: https://dev.to/
 
Top