Kubernetes 实战练习指南
Kubernetes 实战练习指南
🎯 练习目标
通过循序渐进的实战练习,掌握Kubernetes核心概念和操作技能。每个练习都包含目标、步骤、验证和清理四个部分。
📚 练习前准备
环境要求
- 可用的Kubernetes集群(minikube、kind或云厂商集群)
- kubectl命令行工具
- 基础的Linux命令知识
验证环境
# 检查kubectl连接
kubectl cluster-info# 检查节点状态
kubectl get nodes# 创建练习命名空间
kubectl create namespace k8s-labs
kubectl config set-context --current --namespace=k8s-labs
🚀 入门级练习
练习1:创建和管理Pod
目标:学会创建、查看和删除Pod
步骤:
# 1. 创建一个简单的Pod
cat > nginx-pod.yaml << EOF
apiVersion: v1
kind: Pod
metadata:name: nginx-podnamespace: k8s-labslabels:app: nginx
spec:containers:- name: nginximage: nginx:1.20ports:- containerPort: 80
EOF# 2. 应用配置
kubectl apply -f nginx-pod.yaml# 3. 查看Pod状态
kubectl get pods
kubectl get pods -o wide# 4. 查看Pod详情
kubectl describe pod nginx-pod# 5. 查看Pod日志
kubectl logs nginx-pod# 6. 进入Pod内部
kubectl exec -it nginx-pod -- /bin/bash
# 在容器内执行: curl localhost
# 退出: exit
验证:
# Pod应该处于Running状态
kubectl get pod nginx-pod | grep Running# 能够访问nginx服务
kubectl port-forward nginx-pod 8080:80 &
curl http://localhost:8080
清理:
kubectl delete pod nginx-pod
pkill -f "port-forward"
练习2:使用Deployment管理应用
目标:学会创建Deployment并进行扩缩容、更新操作
步骤:
# 1. 创建Deployment
cat > nginx-deployment.yaml << EOF
apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-deploymentnamespace: k8s-labs
spec:replicas: 3selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginx:1.20ports:- containerPort: 80resources:requests:memory: "64Mi"cpu: "100m"limits:memory: "128Mi"cpu: "200m"
EOF# 2. 部署应用
kubectl apply -f nginx-deployment.yaml# 3. 查看Deployment和Pod
kubectl get deployments
kubectl get pods -l app=nginx# 4. 扩容到5个副本
kubectl scale deployment nginx-deployment --replicas=5
kubectl get pods -l app=nginx# 5. 更新镜像版本
kubectl set image deployment/nginx-deployment nginx=nginx:1.21
kubectl rollout status deployment/nginx-deployment# 6. 查看更新历史
kubectl rollout history deployment/nginx-deployment# 7. 回滚到上一版本
kubectl rollout undo deployment/nginx-deployment
kubectl rollout status deployment/nginx-deployment
验证:
# 检查副本数量
kubectl get deployment nginx-deployment# 检查Pod标签
kubectl get pods -l app=nginx --show-labels
清理:
kubectl delete deployment nginx-deployment
练习3:创建Service暴露应用
目标:学会创建不同类型的Service
步骤:
# 1. 先创建一个Deployment(如果前面删除了)
kubectl create deployment web-app --image=nginx:1.20 --replicas=3# 2. 创建ClusterIP Service
cat > clusterip-service.yaml << EOF
apiVersion: v1
kind: Service
metadata:name: web-clusteripnamespace: k8s-labs
spec:type: ClusterIPselector:app: web-appports:- port: 80targetPort: 80
EOFkubectl apply -f clusterip-service.yaml# 3. 测试ClusterIP Service
kubectl run -it --rm debug --image=busybox --restart=Never -- wget -qO- http://web-clusterip# 4. 创建NodePort Service
cat > nodeport-service.yaml << EOF
apiVersion: v1
kind: Service
metadata:name: web-nodeportnamespace: k8s-labs
spec:type: NodePortselector:app: web-appports:- port: 80targetPort: 80nodePort: 30080
EOFkubectl apply -f nodeport-service.yaml# 5. 查看Service信息
kubectl get services
kubectl describe service web-nodeport
验证:
# 检查端点
kubectl get endpoints# 测试NodePort访问(如果是minikube)
minikube ip # 获取IP
curl http://$(minikube ip):30080
清理:
kubectl delete service web-clusterip web-nodeport
kubectl delete deployment web-app
🎯 进阶级练习
练习4:ConfigMap和Secret使用
目标:学会使用ConfigMap和Secret管理应用配置
步骤:
# 1. 创建ConfigMap
cat > app-config.yaml << EOF
apiVersion: v1
kind: ConfigMap
metadata:name: app-confignamespace: k8s-labs
data:database_host: "mysql.example.com"database_port: "3306"log_level: "INFO"app.properties: |spring.datasource.url=jdbc:mysql://mysql.example.com:3306/mydblogging.level.root=INFOserver.port=8080
EOF# 2. 创建Secret
cat > app-secret.yaml << EOF
apiVersion: v1
kind: Secret
metadata:name: app-secretnamespace: k8s-labs
type: Opaque
data:database_user: YWRtaW4= # base64 encoded "admin"database_password: cGFzc3dvcmQ= # base64 encoded "password"
EOF# 3. 应用配置
kubectl apply -f app-config.yaml
kubectl apply -f app-secret.yaml# 4. 创建使用配置的Pod
cat > config-pod.yaml << EOF
apiVersion: v1
kind: Pod
metadata:name: config-test-podnamespace: k8s-labs
spec:containers:- name: test-containerimage: busyboxcommand: ["sleep", "3600"]env:- name: DATABASE_HOSTvalueFrom:configMapKeyRef:name: app-configkey: database_host- name: DATABASE_USERvalueFrom:secretKeyRef:name: app-secretkey: database_userenvFrom:- configMapRef:name: app-configvolumeMounts:- name: config-volumemountPath: /etc/config- name: secret-volumemountPath: /etc/secretsvolumes:- name: config-volumeconfigMap:name: app-config- name: secret-volumesecret:secretName: app-secret
EOFkubectl apply -f config-pod.yaml# 5. 验证配置加载
kubectl exec -it config-test-pod -- env | grep DATABASE
kubectl exec -it config-test-pod -- ls -la /etc/config
kubectl exec -it config-test-pod -- cat /etc/config/app.properties
kubectl exec -it config-test-pod -- ls -la /etc/secrets
验证:
# 检查环境变量
kubectl exec config-test-pod -- printenv | grep DATABASE# 检查挂载的文件
kubectl exec config-test-pod -- cat /etc/config/database_host
清理:
kubectl delete pod config-test-pod
kubectl delete configmap app-config
kubectl delete secret app-secret
练习5:持久化存储使用
目标:学会使用PV和PVC进行数据持久化
步骤:
# 1. 创建PersistentVolume(本地存储示例)
cat > local-pv.yaml << EOF
apiVersion: v1
kind: PersistentVolume
metadata:name: local-pv
spec:capacity:storage: 1GiaccessModes:- ReadWriteOncepersistentVolumeReclaimPolicy: DeletestorageClassName: local-storagelocal:path: /tmp/k8s-datanodeAffinity:required:nodeSelectorTerms:- matchExpressions:- key: kubernetes.io/hostnameoperator: Invalues:- $(kubectl get nodes -o jsonpath='{.items[0].metadata.name}')
EOF# 2. 创建目录(在节点上)
kubectl get nodes -o wide # 查看节点
# 如果是单节点集群,在本地执行:
sudo mkdir -p /tmp/k8s-datakubectl apply -f local-pv.yaml# 3. 创建PersistentVolumeClaim
cat > local-pvc.yaml << EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: local-pvcnamespace: k8s-labs
spec:accessModes:- ReadWriteOncestorageClassName: local-storageresources:requests:storage: 500Mi
EOFkubectl apply -f local-pvc.yaml# 4. 创建使用存储的Pod
cat > storage-pod.yaml << EOF
apiVersion: v1
kind: Pod
metadata:name: storage-test-podnamespace: k8s-labs
spec:containers:- name: test-containerimage: busyboxcommand: ["sleep", "3600"]volumeMounts:- name: storage-volumemountPath: /datavolumes:- name: storage-volumepersistentVolumeClaim:claimName: local-pvc
EOFkubectl apply -f storage-pod.yaml# 5. 测试数据持久化
kubectl exec -it storage-test-pod -- sh -c 'echo "Hello K8s Storage!" > /data/test.txt'
kubectl exec -it storage-test-pod -- cat /data/test.txt# 6. 删除Pod后重新创建,验证数据仍在
kubectl delete pod storage-test-pod
kubectl apply -f storage-pod.yaml
# 等待Pod启动
kubectl wait --for=condition=Ready pod/storage-test-pod
kubectl exec -it storage-test-pod -- cat /data/test.txt
验证:
# 检查PV和PVC状态
kubectl get pv
kubectl get pvc# 检查绑定关系
kubectl describe pvc local-pvc
清理:
kubectl delete pod storage-test-pod
kubectl delete pvc local-pvc
kubectl delete pv local-pv
sudo rm -rf /tmp/k8s-data
练习6:健康检查配置
目标:学会配置Liveness和Readiness探针
步骤:
# 1. 创建带健康检查的应用
cat > health-check-app.yaml << EOF
apiVersion: apps/v1
kind: Deployment
metadata:name: health-appnamespace: k8s-labs
spec:replicas: 2selector:matchLabels:app: health-apptemplate:metadata:labels:app: health-appspec:containers:- name: appimage: nginx:1.20ports:- containerPort: 80livenessProbe:httpGet:path: /port: 80initialDelaySeconds: 10periodSeconds: 10readinessProbe:httpGet:path: /port: 80initialDelaySeconds: 5periodSeconds: 5resources:requests:memory: "64Mi"cpu: "100m"limits:memory: "128Mi"cpu: "200m"
---
apiVersion: v1
kind: Service
metadata:name: health-app-servicenamespace: k8s-labs
spec:selector:app: health-appports:- port: 80targetPort: 80
EOFkubectl apply -f health-check-app.yaml# 2. 观察Pod启动过程
kubectl get pods -l app=health-app -w# 3. 检查健康检查状态
kubectl describe pod -l app=health-app# 4. 模拟应用故障
POD_NAME=$(kubectl get pods -l app=health-app -o jsonpath='{.items[0].metadata.name}')
kubectl exec -it $POD_NAME -- rm /usr/share/nginx/html/index.html# 5. 观察Pod重启
kubectl get pods -l app=health-app -w
验证:
# 检查探针配置
kubectl get pod $POD_NAME -o yaml | grep -A 10 "livenessProbe\|readinessProbe"# 查看重启次数
kubectl get pods -l app=health-app
清理:
kubectl delete -f health-check-app.yaml
🏆 高级练习
练习7:完整Web应用部署
目标:部署一个包含前端、后端和数据库的完整应用
步骤:
# 1. 创建MySQL数据库
cat > mysql-deployment.yaml << EOF
apiVersion: apps/v1
kind: Deployment
metadata:name: mysqlnamespace: k8s-labs
spec:selector:matchLabels:app: mysqltemplate:metadata:labels:app: mysqlspec:containers:- name: mysqlimage: mysql:5.7env:- name: MYSQL_ROOT_PASSWORDvalue: "rootpassword"- name: MYSQL_DATABASEvalue: "webapp"- name: MYSQL_USERvalue: "webuser"- name: MYSQL_PASSWORDvalue: "webpassword"ports:- containerPort: 3306volumeMounts:- name: mysql-storagemountPath: /var/lib/mysqlvolumes:- name: mysql-storageemptyDir: {}
---
apiVersion: v1
kind: Service
metadata:name: mysql-servicenamespace: k8s-labs
spec:selector:app: mysqlports:- port: 3306targetPort: 3306
EOF# 2. 创建后端应用配置
cat > backend-config.yaml << EOF
apiVersion: v1
kind: ConfigMap
metadata:name: backend-confignamespace: k8s-labs
data:DATABASE_HOST: "mysql-service"DATABASE_NAME: "webapp"DATABASE_PORT: "3306"
---
apiVersion: v1
kind: Secret
metadata:name: backend-secretnamespace: k8s-labs
type: Opaque
data:DATABASE_USER: d2VidXNlcg== # webuserDATABASE_PASSWORD: d2VicGFzc3dvcmQ= # webpassword
EOF# 3. 创建后端应用(使用nginx模拟)
cat > backend-deployment.yaml << EOF
apiVersion: apps/v1
kind: Deployment
metadata:name: backendnamespace: k8s-labs
spec:replicas: 2selector:matchLabels:app: backendtemplate:metadata:labels:app: backendspec:containers:- name: backendimage: nginx:1.20ports:- containerPort: 80env:- name: DATABASE_HOSTvalueFrom:configMapKeyRef:name: backend-configkey: DATABASE_HOST- name: DATABASE_USERvalueFrom:secretKeyRef:name: backend-secretkey: DATABASE_USERlivenessProbe:httpGet:path: /port: 80initialDelaySeconds: 10readinessProbe:httpGet:path: /port: 80initialDelaySeconds: 5
---
apiVersion: v1
kind: Service
metadata:name: backend-servicenamespace: k8s-labs
spec:selector:app: backendports:- port: 80targetPort: 80
EOF# 4. 创建前端应用
cat > frontend-deployment.yaml << EOF
apiVersion: apps/v1
kind: Deployment
metadata:name: frontendnamespace: k8s-labs
spec:replicas: 3selector:matchLabels:app: frontendtemplate:metadata:labels:app: frontendspec:containers:- name: frontendimage: nginx:1.20ports:- containerPort: 80volumeMounts:- name: nginx-configmountPath: /etc/nginx/conf.dvolumes:- name: nginx-configconfigMap:name: nginx-config
---
apiVersion: v1
kind: ConfigMap
metadata:name: nginx-confignamespace: k8s-labs
data:default.conf: |server {listen 80;server_name _;location /api/ {proxy_pass http://backend-service/;proxy_set_header Host \$host;proxy_set_header X-Real-IP \$remote_addr;}location / {root /usr/share/nginx/html;index index.html;try_files \$uri \$uri/ /index.html;}}
---
apiVersion: v1
kind: Service
metadata:name: frontend-servicenamespace: k8s-labs
spec:type: NodePortselector:app: frontendports:- port: 80targetPort: 80nodePort: 30081
EOF# 5. 按顺序部署所有组件
kubectl apply -f mysql-deployment.yaml
kubectl apply -f backend-config.yaml
kubectl apply -f backend-deployment.yaml
kubectl apply -f frontend-deployment.yaml# 6. 等待所有Pod就绪
kubectl wait --for=condition=Ready pod -l app=mysql --timeout=120s
kubectl wait --for=condition=Ready pod -l app=backend --timeout=120s
kubectl wait --for=condition=Ready pod -l app=frontend --timeout=120s# 7. 查看部署状态
kubectl get all
验证:
# 检查所有组件状态
kubectl get pods,svc# 测试前端访问
curl http://$(minikube ip):30081# 测试后端API
kubectl port-forward svc/backend-service 8080:80 &
curl http://localhost:8080
清理:
kubectl delete -f frontend-deployment.yaml
kubectl delete -f backend-deployment.yaml
kubectl delete -f backend-config.yaml
kubectl delete -f mysql-deployment.yaml
pkill -f "port-forward"
练习8:自动扩缩容配置
目标:配置HPA实现Pod自动扩缩容
步骤:
# 1. 确保metrics-server运行(minikube用户)
minikube addons enable metrics-server# 2. 创建测试应用
cat > hpa-test-app.yaml << EOF
apiVersion: apps/v1
kind: Deployment
metadata:name: hpa-testnamespace: k8s-labs
spec:replicas: 1selector:matchLabels:app: hpa-testtemplate:metadata:labels:app: hpa-testspec:containers:- name: php-apacheimage: k8s.gcr.io/hpa-exampleports:- containerPort: 80resources:requests:cpu: 200mlimits:cpu: 500m
---
apiVersion: v1
kind: Service
metadata:name: hpa-test-servicenamespace: k8s-labs
spec:selector:app: hpa-testports:- port: 80targetPort: 80
EOFkubectl apply -f hpa-test-app.yaml# 3. 创建HPA
kubectl autoscale deployment hpa-test --cpu-percent=50 --min=1 --max=10# 4. 查看HPA状态
kubectl get hpa# 5. 生成负载测试扩缩容
kubectl run -it --rm load-generator --image=busybox --restart=Never -- sh -c "while true; do wget -q -O- http://hpa-test-service; done"# 在另一个终端窗口观察扩缩容
kubectl get hpa -w
kubectl get pods -l app=hpa-test -w
验证:
# 查看HPA详情
kubectl describe hpa hpa-test# 查看Pod数量变化
kubectl get deployment hpa-test
清理:
kubectl delete hpa hpa-test
kubectl delete -f hpa-test-app.yaml
🎓 挑战练习
挑战1:蓝绿部署
目标:实现应用的蓝绿部署
提示:
- 创建两个版本的Deployment(blue和green)
- 使用Service标签选择器切换流量
- 验证新版本后切换流量
挑战2:多环境配置
目标:为同一应用配置开发、测试、生产三套环境
提示:
- 使用不同的Namespace
- 配置不同的资源限制
- 使用不同的ConfigMap和Secret
挑战3:故障演练
目标:模拟各种故障场景并排查
提示:
- 模拟Pod崩溃
- 模拟网络不通
- 模拟存储故障
- 模拟资源不足
📊 练习进度跟踪
入门级 ✅
- 练习1:Pod基本操作
- 练习2:Deployment管理
- 练习3:Service使用
进阶级 ✅
- 练习4:配置管理
- 练习5:存储使用
- 练习6:健康检查
高级 ✅
- 练习7:完整应用部署
- 练习8:自动扩缩容
挑战级 🎯
- 挑战1:蓝绿部署
- 挑战2:多环境配置
- 挑战3:故障演练
🎉 总结
恭喜您完成所有练习!通过这些实战练习,您已经掌握了:
- 基础操作:Pod、Deployment、Service的创建和管理
- 配置管理:ConfigMap和Secret的使用
- 存储管理:持久化数据的处理
- 健康检查:应用可靠性保障
- 完整应用:多组件应用的部署
- 自动化:扩缩容和运维自动化
继续实践和探索,成为Kubernetes专家!🚀
📚 下一步学习建议
- 深入学习:Helm、Operator、Istio等高级工具
- 云原生生态:了解CNCF生态系统
- 生产实践:参与实际项目的K8s运维
- 社区参与:加入K8s社区,贡献开源项目
加油,K8s专家之路就在脚下!💪