Course Content
1. DevOps overview
DevOps là gì
0/1
4. Kubernetes từ cơ bản đến nâng cao
0/20
8. Monitoring, Logging và Tracing
Khóa Học: DevOps Zero to Hero. (Đăng nhập để xem các video 1 cách miễn phí)

3) Tạo Deployment và tham chiếu đến Secret và Configmap:

Tham chiếu đến Secret chỉ định và biết chúng environment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app-container
        image: gitpod/openvscode-server:1.101.1
        env:
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: db-password
              key: password

Kiểm tra env trong pod:

kubectl  exec -it <pod name> -- bash

Biến tất cả các key/value trong secret thành Environment của Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app-container
        image: gitpod/openvscode-server:1.101.1
        envFrom:
        - secretRef:
            name: db-password

Biến tất cả các key/value trong Configmap thành Environment của Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app-container
        image: gitpod/openvscode-server:1.101.1
        envFrom:
        - configMapRef:
            name: app-config

Mount ConfigMap thành file trong Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app-container
        image: gitpod/openvscode-server:1.101.1
        volumeMounts:
        - name: config-volume
          # Đường dẫn đích trong container.
          # QUAN TRỌNG: Vì có `subPath` ở dưới, `/etc/config` sẽ trở thành một FILE, không phải một thư mục.
          # Nội dung của file /etc/config sẽ là nội dung của key `schedule.txt` trong ConfigMap.
          mountPath: /etc/config
          # Chỉ định chỉ mount một file/mục cụ thể từ Volume.
          # Tên `schedule.txt` này PHẢI KHỚP VỚI MỘT KEY trong phần `data` của ConfigMap `app-config`.
          subPath: schedule.txt
      volumes:
      - name: config-volume
        configMap:
          # Tham chiếu đến tên của ConfigMap sẽ được sử dụng làm nguồn dữ liệu cho Volume `config-volume`.
          name: app-config

Nếu trong configmap có nhiều Key/Value

kubectl create configmap multi-config --from-literal=database.conf=postgres://user:pass@localhost/db --from-literal=apt.conf=your_api_key_here


######
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app-container
        image: gitpod/openvscode-server:1.101.1
        volumeMounts:
        - name: config-volume
          mountPath: /etc/config  # Đường dẫn nơi các file sẽ được mount vào container
      volumes:
      - name: config-volume
        configMap:
          name: multi-config  # Tên của ConfigMap

Biến secret thành 1 file trong workload:

apiVersion: v1
kind: Secret
metadata:
  name: db-credentials
type: Opaque
data:
  username: YWRtaW4= # echo -n 'admin' | base64
  password: UzNjclN0UEBzc3cwcmQ= # echo -n 'S3cr3tP@ssw0rd' | base64

####
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-deployment-with-secret
spec:
  replicas: 2 # Bạn có thể tạo bao nhiêu Pod tùy ý
  selector:
    matchLabels:
      app: my-secret-app
  template: # Đây là phần định nghĩa cho Pod sẽ được tạo ra
    metadata:
      labels:
        app: my-secret-app # Label này phải khớp với selector ở trên
    spec: # Toàn bộ spec của Pod sẽ nằm ở đây
      containers:
      - name: my-app-container
        image: busybox
        # Lệnh này giữ cho container chạy để chúng ta có thể kiểm tra
        command: [ "sleep", "3600" ]
        volumeMounts:
        # Mount key 'username' từ Secret thành một file
        - name: secret-volume
          mountPath: /etc/db/username # Đường dẫn đầy đủ đến file username
          subPath: username           # Tên của key trong Secret
          
        # Mount key 'password' từ Secret thành một file khác
        - name: secret-volume
          mountPath: /etc/db/password # Đường dẫn đầy đủ đến file password
          subPath: password           # Tên của key trong Secret
          
      volumes:
      # Khai báo Volume sẽ sử dụng Secret
      - name: secret-volume
        secret:
          secretName: db-credentials # Tên của Secret cần sử dụng

####
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-deployment-with-secret
spec:
  replicas: 2 # Bạn có thể tạo bao nhiêu Pod tùy ý
  selector:
    matchLabels:
      app: my-secret-app
  template: # Đây là phần định nghĩa cho Pod sẽ được tạo ra
    metadata:
      labels:
        app: my-secret-app # Label này phải khớp với selector ở trên
    spec: # Toàn bộ spec của Pod sẽ nằm ở đây
      containers:
      - name: my-app-container
        image: busybox
        # Lệnh này giữ cho container chạy để chúng ta có thể kiểm tra
        command: [ "sleep", "3600" ]
        volumeMounts:
        - name: secret-volume
          mountPath: /etc/db/
          
      volumes:
      # Khai báo Volume sẽ sử dụng Secret
      - name: secret-volume
        secret:
          secretName: db-credentials # Tên của Secret cần sử dụng

 

 

4) Kiến thức thực tiễn

Câu hỏi đặt ra là: Khi chúng ta chỉnh sửa (edit) một ConfigMap hoặc Secret, có cần phải khởi động lại (terminate/restart) các Pod đang sử dụng nó không?

4.1) Khi ConfigMap/Secret được mount dưới dạng Volume

Đây là trường hợp phức tạp hơn và cần được chia thành hai tình huống:

4.1.a) Khi Mount toàn bộ Volume (Không dùng subPath)

Đây là trường hợp bạn mount toàn bộ ConfigMap/Secret vào một thư mục.

# Ví dụ: không có subPath
volumeMounts:
- name: config-volume
  mountPath: /etc/config
  • Hành vi: Kubernetes sẽ tự động cập nhật các file bên trong thư mục /etc/config khi ConfigMap/Secret thay đổi.

  • Cơ chế: Kubelet tạo ra một cấu trúc thư mục với các symlink (liên kết tượng trưng). Khi ConfigMap thay đổi, Kubelet sẽ cập nhật các symlink này để trỏ đến dữ liệu mới.

  • Cần khởi động lại Pod không? Không.

  • Lưu ý quan trọng:

    • Sẽ có một độ trễ ngắn (thường dưới một phút) để kubelet đồng bộ thay đổi.

    • Ứng dụng của bạn phải có khả năng phát hiện thay đổi và tải lại file cấu hình một cách linh động. Nếu ứng dụng chỉ đọc file cấu hình một lần khi khởi động, bạn vẫn phải khởi động lại Pod để nó nhận thay đổi.

4.1.b) Khi Mount bằng subPath (Mount một file cụ thể)

Đây là trường hợp bạn chỉ mount một key duy nhất từ ConfigMap/Secret thành một file.

# Ví dụ: có dùng subPath
volumeMounts:
- name: config-volume
  mountPath: /etc/config/schedule.txt
  subPath: schedule.txt
  • Hành vi: Dữ liệu được mount sẽ KHÔNG tự động cập nhật.

  • Cơ chế: Việc sử dụng subPath sẽ ngăn cản Kubelet sử dụng cơ chế symlink. Thay vào đó, nó tạo ra một file vật lý (inode) trực tiếp trên filesystem của container. File này sẽ không thay đổi ngay cả khi ConfigMap/Secret gốc đã được cập nhật.

  • Cần khởi động lại Pod không? Có. Bạn bắt buộc phải khởi động lại Pod để nó đọc lại dữ liệu mới từ ConfigMap/Secret.

4.2) Khi ConfigMap/Secret được dùng làm Biến môi trường (Environment Variables)

# Ví dụ: Dùng làm biến môi trường
env:
  - name: MY_SETTING
    valueFrom:
      configMapKeyRef:
        name: my-config
        key: my-key
  • Hành vi: Giá trị của biến môi trường sẽ KHÔNG tự động cập nhật.

  • Cơ chế: Biến môi trường chỉ được thiết lập một lần duy nhất khi container được khởi tạo.

  • Cần khởi động lại Pod không? Có.

Bảng tóm tắt (Summary Table) đã cập nhật

Kiểu Mount (Mount Type) Tự động cập nhật? (Auto Update?) Cần khởi động lại Pod? (Pod Restart Needed?) Ứng dụng cần tải lại động? (App Reload Needed?)
Volume (Toàn bộ thư mục)  (sau một lúc) Không  (Rất quan trọng!)
Volume (Dùng subPath) Không Không áp dụng (Vì Pod phải khởi động lại)
Biến môi trường (Env Variables) Không Không áp dụng
0% Complete