🎯 Practice objective__HTMLTAG_68___
- Deploy application with ConfigMaps (env vars and volume mount)
- Create and manage secure Secrets
- Install CSI driver and create StorageClass
- Deploy PostgreSQL with StatefulSet and PersistentVolumeClaim
- Create volume snapshot and perform restore__HTMLTAG_79___
Preparation
kubectl create namespace lab3
kubectl config set-context --current --namespace=lab3
Lab 1: ConfigMaps
# Tạo ConfigMap từ literal values kubectl create configmap app-config \ --from-literal=APP_ENV=production \ --from-literal=APP_PORT=8080 \ --from-literal=LOG_LEVEL=info \ -n lab3Tạo ConfigMap từ file
cat > app.conf <<EOF [server] port = 8080 timeout = 30
[database] host = postgres-service port = 5432 name = myapp EOF
kubectl create configmap app-file-config --from-file=app.conf -n lab3
Xem ConfigMap
kubectl get configmaps -n lab3 kubectl describe configmap app-config -n lab3
# Deploy app sử dụng ConfigMap
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: config-demo
namespace: lab3
spec:
replicas: 1
selector:
matchLabels:
app: config-demo
template:
metadata:
labels:
app: config-demo
spec:
containers:
- name: app
image: nginx:1.27
env:
# Lấy từng key từ ConfigMap
- name: APP_ENV
valueFrom:
configMapKeyRef:
name: app-config
key: APP_ENV
- name: APP_PORT
valueFrom:
configMapKeyRef:
name: app-config
key: APP_PORT
# Lấy tất cả keys từ ConfigMap
envFrom:
- configMapRef:
name: app-config
volumeMounts:
- name: config-file
mountPath: /etc/app
volumes:
- name: config-file
configMap:
name: app-file-config
EOF
# Verify env vars được inject
POD=$(kubectl get pods -n lab3 -l app=config-demo -o jsonpath='{.items[0].metadata.name}')
kubectl exec $POD -n lab3 -- env | grep APP
kubectl exec $POD -n lab3 -- cat /etc/app/app.conf
Lab 2: Secrets
# Tạo Secret kubectl create secret generic db-credentials \ --from-literal=POSTGRES_USER=admin \ --from-literal=POSTGRES_PASSWORD=SuperSecret123 \ --from-literal=POSTGRES_DB=myapp \ -n lab3Secret được lưu dưới dạng base64 (không phải encrypted!)
kubectl get secret db-credentials -n lab3 -o yaml
Decode để xem value
kubectl get secret db-credentials -n lab3 -o jsonpath='{.data.POSTGRES_PASSWORD}' | base64 -d
Deploy app với Secret
cat <<EOF | kubectl apply -f - apiVersion: apps/v1 kind: Deployment metadata: name: postgres-client namespace: lab3 spec: replicas: 1 selector: matchLabels: app: postgres-client template: metadata: labels: app: postgres-client spec: containers: - name: app image: postgres:16 command: ["sleep", "infinity"] envFrom: - secretRef: name: db-credentials # Mount secret sebagai file volumeMounts: - name: secret-volume mountPath: /etc/secrets readOnly: true volumes: - name: secret-volume secret: secretName: db-credentials EOF
kubectl exec -n lab3 deploy/postgres-client -- env | grep POSTGRES kubectl exec -n lab3 deploy/postgres-client -- ls /etc/secrets
Lab 3: Immutable ConfigMap and Secret
cat <<EOF | kubectl apply -f - apiVersion: v1 kind: ConfigMap metadata: name: immutable-config namespace: lab3 data: key1: value1 immutable: true # không thể update sau khi tạo, chỉ có thể xóa và tạo lại EOFThử update sẽ bị lỗi
kubectl patch configmap immutable-config -n lab3 -p '{"data":{"key1":"new-value"}}'
Error: field is immutable
Lab 4: PersistentVolume and PVC with Local Storage
# Tạo local PV (demo, không dùng production) cat <<EOF | kubectl apply -f - apiVersion: v1 kind: PersistentVolume metadata: name: local-pv-1 spec: capacity: storage: 5Gi accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain storageClassName: local-storage local: path: /tmp/k8s-pv-1 nodeAffinity: required: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: - kind-worker # tên node của bạn --- apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: local-storage provisioner: kubernetes.io/no-provisioner volumeBindingMode: WaitForFirstConsumer --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: my-pvc namespace: lab3 spec: storageClassName: local-storage accessModes: - ReadWriteOnce resources: requests: storage: 2Gi EOF
kubectl get pv kubectl get pvc -n lab3
Lab 5: PostgreSQL with StatefulSet
cat <<EOF | kubectl apply -f - apiVersion: v1 kind: Service metadata: name: postgres namespace: lab3 spec: clusterIP: None # Headless selector: app: postgres ports: - port: 5432 --- apiVersion: apps/v1 kind: StatefulSet metadata: name: postgres namespace: lab3 spec: serviceName: postgres replicas: 1 selector: matchLabels: app: postgres template: metadata: labels: app: postgres spec: containers: - name: postgres image: postgres:16 ports: - containerPort: 5432 envFrom: - secretRef: name: db-credentials volumeMounts: - name: data mountPath: /var/lib/postgresql/data resources: requests: cpu: "250m" memory: "256Mi" limits: cpu: "1" memory: "512Mi" volumeClaimTemplates: - metadata: name: data spec: accessModes: ["ReadWriteOnce"] resources: requests: storage: 1Gi EOFTheo dõi StatefulSet
kubectl rollout status statefulset/postgres -n lab3
Test connection
kubectl exec -it postgres-0 -n lab3 -- psql -U admin -d myapp -c "CREATE TABLE test (id serial PRIMARY KEY, name text);" kubectl exec -it postgres-0 -n lab3 -- psql -U admin -d myapp -c "INSERT INTO test (name) VALUES ('hello kubernetes');" kubectl exec -it postgres-0 -n lab3 -- psql -U admin -d myapp -c "SELECT * FROM test;"
Lab 6: Verify Data Persistence__HTMLTAG_94___
# Xóa pod (StatefulSet sẽ tự tạo lại)
kubectl delete pod postgres-0 -n lab3
Chờ pod mới
kubectl get pods -n lab3 -w
Data vẫn còn sau khi pod restart
kubectl exec -it postgres-0 -n lab3 -- psql -U admin -d myapp -c "SELECT * FROM test;"
Kết quả: "hello kubernetes" vẫn còn
# Xóa pod (StatefulSet sẽ tự tạo lại)
kubectl delete pod postgres-0 -n lab3
Chờ pod mới
kubectl get pods -n lab3 -w
Data vẫn còn sau khi pod restart
kubectl exec -it postgres-0 -n lab3 -- psql -U admin -d myapp -c "SELECT * FROM test;"
Kết quả: "hello kubernetes" vẫn còn
Cleanup
kubectl delete namespace lab3
kubectl delete pv local-pv-1
kubectl config set-context --current --namespace=default