Các ứng dụng thường yêu cầu cài đặt cấu hình và thông tin nhạy cảm như thông tin đăng nhập đúng vào hàm. Kubernetes cung cấp hai tài nguyên được thiết kế riêng cho mục đích này: ConfigMap cho dữ liệu cấu hình chung và Bí mật cho thông tin nhạy cảm. Trong phần này, chúng ta sẽ khám phá cách tạo, quản lý và sử dụng các tài nguyên này một cách hiệu quả.
Tìm hiểu ConfigMap và những bí mật
Trước khi đi sâu vào chi tiết, hãy làm rõ mục đích của từng tài nguyên:
ConfigMaps lưu trữ dữ liệu không bí mật theo cặp khóa-giá trị. Chúng lý tưởng cho các cài đặt dành riêng cho môi trường, tệp cấu hình, đối số dòng lệnh, v.v.
Secrets lưu trữ thông tin nhạy cảm như mật khẩu, mã thông báo OAuth và khóa SSH. Chúng tương tự như ConfigMap nhưng được thiết kế đặc biệt cho dữ liệu bí mật.
Cả hai tài nguyên đều tách biệt cấu hình khỏi mã ứng dụng, tuân theo nguyên tắc lưu trữ cấu hình trong môi trường của phương pháp Ứng dụng Mười hai yếu tố.
Làm việc với ConfigMap
Hãy khám phá cách tạo và sử dụng ConfigMap để cung cấp cấu hình cho các ứng dụng của bạn.
Tạo ConfigMap
Có nhiều cách để tạo ConfigMap:
Từ giá trị theo nghĩa đen
kubectl create configmap app-config \
--from-literal=APP_ENV=production \
--from-literal=APP_DEBUG=false \
--from-literal=APP_PORT=8080
Từ tập tin
# Create a properties file
echo "app.env=production" > app.properties
echo "app.debug=false" >> app.properties
echo "app.port=8080" >> app.properties
# Create ConfigMap from the file
kubectl create configmap app-config --from-file=app.properties
Từ một thư mục
# Create a directory with configuration files
mkdir config
echo "This is a config file" > config/config.txt
echo "DB_HOST=localhost" > config/database.env
# Create ConfigMap from the directory
kubectl create configmap app-config --from-file=config/
Sử dụng YAML
Để kiểm soát nhiều hơn, bạn có thể xác định ConfigMap trong YAML:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
APP_ENV: production
APP_DEBUG: 'false'
APP_PORT: '8080'
config.json: |
{
"database": {
"host": "db.example.com",
"port": 5432
},
"cache": {
"enabled": true,
"ttl": 300
}
}
nginx.conf: |
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend;
}
}
Áp dụng cấu hình này với:
kubectl apply -f app-config.yaml
Đang xem ConfigMap
Liệt kê tất cả ConfigMap trong không gian tên hiện tại:
kubectl get configmaps
Xem chi tiết của một ConfigMap cụ thể:
kubectl describe configmap app-config
Để xem các giá trị thực tế:
kubectl get configmap app-config -o yaml
Sử dụng ConfigMap trong pod
ConfigMap có thể được sử dụng trong pod theo nhiều cách:
Là biến môi trường
apiVersion: v1
kind: Pod
metadata:
name: config-env-pod
spec:
containers:
- name: app
image: busybox
command: ['sh', '-c', 'echo $APP_ENV $APP_PORT && sleep 3600']
env:
- name: APP_ENV
valueFrom:
configMapKeyRef:
name: app-config
key: APP_ENV
- name: APP_PORT
valueFrom:
configMapKeyRef:
name: app-config
key: APP_PORT
Bạn cũng có thể tải tất cả các khóa từ ConfigMap dưới dạng biến môi trường:
apiVersion: v1
kind: Pod
metadata:
name: config-env-all-pod
spec:
containers:
- name: app
image: busybox
command: ['sh', '-c', 'env | grep APP && sleep 3600']
envFrom:
- configMapRef:
name: app-config
Dưới dạng tệp trong volume
apiVersion: v1
kind: Pod
metadata:
name: config-vol-pod
spec:
containers:
- name: app
image: busybox
command: ['sh', '-c', 'cat /config/config.json && sleep 3600']
volumeMounts:
- name: config-volume
mountPath: /config
volumes:
- name: config-volume
configMap:
name: app-config
Bạn cũng có thể gắn các phím cụ thể:
volumes:
- name: config-volume
configMap:
name: app-config
items:
- key: config.json
path: app/config.json
- key: nginx.conf
path: nginx/nginx.conf
Là đối số dòng lệnh
apiVersion: v1
kind: Pod
metadata:
name: config-arg-pod
spec:
containers:
- name: app
image: busybox
command: ['echo']
args: ['$(APP_PORT)']
env:
- name: APP_PORT
valueFrom:
configMapKeyRef:
name: app-config
key: APP_PORT
Làm việc với Bí mật
Bí mật tương tự như ConfigMap nhưng được thiết kế cho dữ liệu bí mật. Kubernetes cung cấp một số biện pháp bảo vệ bổ sung cho Bí mật:
- Bí mật được lưu trữ trong hệ thống tệp tạm thời (tmpfs) trong bộ nhớ, không được ghi vào đĩa
- Etcd mã hóa Bí mật (nếu bật mã hóa)
- Quyền truy cập vào Bí mật có thể bị hạn chế với RBAC
Tuy nhiên, điều quan trọng cần lưu ý là Bí mật được mã hóa theo base64, không được mã hóa theo mặc định. Để mã hóa thực sự ở trạng thái lưu trữ, bạn cần cấu hình mã hóa.
Tạo bí mật
Giống như ConfigMap, có nhiều cách để tạo Bí mật:
Từ giá trị theo nghĩa đen
kubectl create secret generic db-credentials \
--from-literal=username=admin \
--from-literal=password=s3cr3t
Từ tập tin
# Create files with sensitive data
echo -n "admin" > username.txt
echo -n "s3cr3t" > password.txt
# Create Secret from files
kubectl create secret generic db-credentials \
--from-file=username=username.txt \
--from-file=password=password.txt
Sử dụng YAML
Nếu bạn xác định Bí mật trong YAML, bạn cần mã hóa các giá trị trong base64:
echo -n "admin" | base64
# Output: YWRtaW4=
echo -n "s3cr3t" | base64
# Output: czNjcjN0
Sau đó tạo định nghĩa Bí mật:
apiVersion: v1
kind: Secret
metadata:
name: db-credentials
type: Opaque
data:
username: YWRtaW4=
password: czNjcjN0
Bạn cũng có thể sử dụng trường stringData, trường này chấp nhận các chuỗi chưa được mã hóa:
apiVersion: v1
kind: Secret
metadata:
name: db-credentials
type: Opaque
stringData:
username: admin
password: s3cr3t
Các loại bí mật
Kubernetes cung cấp các loại tích hợp cho các trường hợp sử dụng Bí mật phổ biến:
- Opaque (mặc định): Dữ liệu tùy ý do người dùng xác định
- kubernetes.io/tls: Chứng chỉ TLS và khóa riêng
- kubernetes.io/dockerconfigjson: Thông tin đăng ký Docker
- kubernetes.io/service-account-token: Mã thông báo tài khoản dịch vụ
- kubernetes.io/basic-auth: Thông tin xác thực cơ bản
- kubernetes.io/ssh-auth: Thông tin xác thực SSH
Ví dụ: để tạo Bí mật TLS:
kubectl create secret tls tls-secret --cert=path/to/tls.cert --key=path/to/tls.key
Đối với thông tin đăng ký Docker:
kubectl create secret docker-registry regcred \
--docker-server=registry.example.com \
--docker-username=username \
--docker-password=password \
--docker-email=email@example.com
Xem bí mật
Liệt kê tất cả Bí mật trong không gian tên hiện tại:
kubectl get secrets
Xem chi tiết về một Bí mật cụ thể:
kubectl describe secret db-credentials
Để xem các giá trị thực tế (chúng sẽ được mã hóa base64):
kubectl get secret db-credentials -o yaml
Để giải mã một giá trị cụ thể:
kubectl get secret db-credentials -o jsonpath='{.data.password}' | base64 --decode
Sử dụng Bí mật trong pod
Bí mật có thể được sử dụng trong pod tương tự như ConfigMap:
Là biến môi trường
apiVersion: v1
kind: Pod
metadata:
name: secret-env-pod
spec:
containers:
- name: app
image: postgres:13
env:
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
name: db-credentials
key: username
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
Bạn cũng có thể tải tất cả các khóa từ Bí mật:
envFrom:
- secretRef:
name: db-credentials
Dưới dạng tệp trong volume
apiVersion: v1
kind: Pod
metadata:
name: secret-vol-pod
spec:
containers:
- name: app
image: busybox
command: ['sh', '-c', 'cat /etc/credentials/username && sleep 3600']
volumeMounts:
- name: secret-volume
mountPath: /etc/credentials
volumes:
- name: secret-volume
secret:
secretName: db-credentials
Sử dụng bí mật đăng ký Docker
apiVersion: v1
kind: Pod
metadata:
name: private-image-pod
spec:
containers:
- name: app
image: registry.example.com/private/app:1.0
imagePullSecrets:
- name: regcred
Cập nhật ConfigMap và những bí mật
Khi bạn cập nhật ConfigMap hoặc Bí mật, các thay đổi sẽ không tự động được phản ánh trong pod đã sử dụng chúng.
Biến môi trường
Các biến môi trường được đặt từ ConfigMap hoặc Bí mật chỉ được đánh giá một lần tại thời điểm tạo pod. Để nhận các thay đổi, bạn cần khởi động lại pod.
Giá đỡ volume
Đối với các tệp được gắn volume, Kubernetes sẽ cập nhật các tệp được gắn trong vòng vài phút. Tuy nhiên, các ứng dụng cần theo dõi các thay đổi hoặc khởi động lại để phát hiện chúng.
Cập nhật chiến lược
Để cập nhật ứng dụng của bạn khi cấu hình thay đổi:
- Sử dụng triển khai với các bản cập nhật luân phiên:
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
- Trigger cập nhật bằng cách thay đổi thông số kỹ thuật pod:
# Create a new version of the ConfigMap
kubectl create configmap app-config-v2 --from-literal=APP_VERSION=2.0
# Update the deployment to use the new ConfigMap
kubectl set env deployment/app-deployment --from=configmap/app-config-v2
- Sử dụng ConfigMap bất biến và phiên bản chúng:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config-v2
immutable: true
data:
APP_VERSION: '2.0'
Quản lý bí mật một cách an toàn
Trong khi Kubernetes Secrets cung cấp chức năng cơ bản để xử lý dữ liệu nhạy cảm thì môi trường production thường yêu cầu các biện pháp bảo mật bổ sung:
1. Kích hoạt mã hóa ở phần còn lại
Định cấu hình mã hóa để lưu trữ etcd:
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
providers:
- aescbc:
keys:
- name: key1
secret: <base64-encoded-key>
- identity: {}
2. Sử dụng hệ thống quản lý bí mật bên ngoài
Tích hợp với các công cụ quản lý bí mật bên ngoài giúp tăng cường bảo mật. Các tùy chọn bao gồm:
- HashiCorp Vault: Sử dụng Trình điều khiển Vault hoặc trình điều khiển CSI
- Trình quản lý bí mật AWS: Sử dụng Toán tử bí mật bên ngoài hoặc ASCP
- Azure Key Vault: Sử dụng Nhà cung cấp AKV cho Trình điều khiển CSI lưu trữ bí mật
- Google Secret Manager: Sử dụng toán tử Trình quản lý bí mật
Ví dụ với Toán tử bí mật bên ngoài:
apiVersion: external-secrets.io/v1alpha1
kind: ExternalSecret
metadata:
name: database-credentials
spec:
refreshInterval: 1h
secretStoreRef:
name: vault-backend
kind: ClusterSecretStore
target:
name: db-credentials
data:
- secretKey: username
remoteRef:
key: database/credentials
property: username
- secretKey: password
remoteRef:
key: database/credentials
property: password
3. Triển khai các biện pháp kiểm soát RBAC
Hạn chế quyền truy cập vào Bí mật bằng Kiểm soát quyền truy cập dựa trên vai trò:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: secret-reader
namespace: default
rules:
- apiGroups: ['']
resources: ['secrets']
verbs: ['get', 'list']
resourceNames: ['db-credentials']
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-secrets
namespace: default
subjects:
- kind: User
name: jane
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: secret-reader
apiGroup: rbac.authorization.k8s.io
4. Sử dụng bí mật bị niêm phong
Bí mật bị niêm phong (của Bitnami) cho phép bạn mã hóa bí mật của mình để chúng có thể được lưu trữ an toàn trong git:
# Install kubeseal
brew install kubeseal # For macOS
# Encrypt a secret
kubectl create secret generic db-credentials \
--from-literal=username=admin \
--from-literal=password=s3cr3t \
--dry-run=client -o yaml | \
kubeseal --format yaml > sealed-secret.yaml
# Apply the sealed secret
kubectl apply -f sealed-secret.yaml
Các mẫu phổ biến và trường hợp sử dụng
Tệp cấu hình cho ứng dụng
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
application.yml: |
server:
port: 8080
spring:
datasource:
url: jdbc:postgresql://db:5432/app
username: ${DB_USER}
password: ${DB_PASSWORD}
jpa:
hibernate:
ddl-auto: update
---
apiVersion: v1
kind: Deployment
metadata:
name: app-deployment
spec:
replicas: 3
template:
spec:
containers:
- name: app
image: myapp:1.0
volumeMounts:
- name: config-volume
mountPath: /app/config
env:
- name: DB_USER
valueFrom:
secretKeyRef:
name: db-credentials
key: username
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
volumes:
- name: config-volume
configMap:
name: app-config
Cờ tính năng
apiVersion: v1
kind: ConfigMap
metadata:
name: feature-flags
data:
ENABLE_NEW_UI: 'true'
ENABLE_BETA_FEATURES: 'false'
MAINTENANCE_MODE: 'false'
---
apiVersion: v1
kind: Deployment
metadata:
name: app-deployment
spec:
template:
spec:
containers:
- name: app
image: myapp:1.0
envFrom:
- configMapRef:
name: feature-flags
Cấu hình dành riêng cho môi trường
Tạo ConfigMap cho từng môi trường và chọn môi trường thích hợp dựa trên nhãn:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config-dev
labels:
env: dev
data:
APP_ENV: development
API_URL: http://api-dev
---
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config-prod
labels:
env: prod
data:
APP_ENV: production
API_URL: http://api
---
apiVersion: v1
kind: Deployment
metadata:
name: app-deployment
spec:
template:
spec:
containers:
- name: app
image: myapp:1.0
envFrom:
- configMapRef:
name: app-config-prod # Change based on environment
Các phương pháp hay nhất cho ConfigMap và Bí mật
Tách cấu hình theo mối quan tâm: Tạo ConfigMap và Bí mật khác nhau cho các khía cạnh khác nhau của ứng dụng của bạn.
Phiên bản cấu hình của bạn: Sử dụng quy ước đặt tên bao gồm các phiên bản hoặc dấu thời gian.
Giữ bí mật ở mức tối thiểu: Chỉ lưu trữ những gì cần giữ bí mật trong Bí mật; sử dụng ConfigMap cho mọi thứ khác.
Xem xét cờ bất biến: Dành cho các cấu hình không nên thay đổi nếu không triển khai lại.
Sử dụng các khối được chiếu: Khi bạn cần kết hợp nhiều ConfigMap hoặc Bí mật:
volumes:
- name: all-config
projected:
sources:
- configMap:
name: app-config
- secret:
name: app-secrets
- configMap:
name: shared-config
Thiết lập các giá trị mặc định: Giúp ứng dụng của bạn có khả năng phục hồi khi thiếu cấu hình.
Xác thực cấu hình: Triển khai xác thực để sớm phát hiện các cấu hình sai.
DTài liệu hóa các tùy chọn cấu hình của bạn: Tạo tài liệu cho tất cả các cài đặt có sẵn.
Audit Truy cập bí mật: Giám sát và ghi nhật ký quyền truy cập vào cấu hình nhạy cảm.
Xem xét quy trình công việc GitOps: Sử dụng các công cụ như Flux hoặc ArgoCD với Bí mật được mã hóa.
Sử dụng DigitalOcean để quản lý cấu hình an toàn
Khi chạy Kubernetes trong môi trường production, việc quản lý cấu hình và bí mật đúng cách càng trở nên quan trọng hơn. DigitalOcean Kubernetes cung cấp một nền tảng đáng tin cậy với các tính năng giúp quản lý cấu hình an toàn:
- Tích hợp với sổ đăng ký container cho image riêng tư
- Hỗ trợ các hệ thống quản lý bí mật bên ngoài
- Etcd được mã hóa để lưu trữ an toàn
Đăng ký với DigitalOcean để nhận 200 USD tín dụng miễn phí và tận dụng các tính năng này cho ứng dụng của bạn.
Trong phần tiếp theo, chúng ta sẽ khám phá tính năng lưu trữ liên tục trong Kubernetes, cho phép ứng dụng của bạn lưu trữ dữ liệu ngoài vòng đời container.