Kubernetes 实战练习指南

发布于:2025-09-10 ⋅ 阅读:(20) ⋅ 点赞:(0)

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-pod
  namespace: k8s-labs
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.20
    ports:
    - 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-deployment
  namespace: k8s-labs
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.20
        ports:
        - containerPort: 80
        resources:
          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-clusterip
  namespace: k8s-labs
spec:
  type: ClusterIP
  selector:
    app: web-app
  ports:
  - port: 80
    targetPort: 80
EOF

kubectl 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-nodeport
  namespace: k8s-labs
spec:
  type: NodePort
  selector:
    app: web-app
  ports:
  - port: 80
    targetPort: 80
    nodePort: 30080
EOF

kubectl 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-config
  namespace: 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/mydb
    logging.level.root=INFO
    server.port=8080
EOF

# 2. 创建Secret
cat > app-secret.yaml << EOF
apiVersion: v1
kind: Secret
metadata:
  name: app-secret
  namespace: 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-pod
  namespace: k8s-labs
spec:
  containers:
  - name: test-container
    image: busybox
    command: ["sleep", "3600"]
    env:
    - name: DATABASE_HOST
      valueFrom:
        configMapKeyRef:
          name: app-config
          key: database_host
    - name: DATABASE_USER
      valueFrom:
        secretKeyRef:
          name: app-secret
          key: database_user
    envFrom:
    - configMapRef:
        name: app-config
    volumeMounts:
    - name: config-volume
      mountPath: /etc/config
    - name: secret-volume
      mountPath: /etc/secrets
  volumes:
  - name: config-volume
    configMap:
      name: app-config
  - name: secret-volume
    secret:
      secretName: app-secret
EOF

kubectl 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: 1Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Delete
  storageClassName: local-storage
  local:
    path: /tmp/k8s-data
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - $(kubectl get nodes -o jsonpath='{.items[0].metadata.name}')
EOF

# 2. 创建目录(在节点上)
kubectl get nodes -o wide  # 查看节点
# 如果是单节点集群,在本地执行:
sudo mkdir -p /tmp/k8s-data

kubectl apply -f local-pv.yaml

# 3. 创建PersistentVolumeClaim
cat > local-pvc.yaml << EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: local-pvc
  namespace: k8s-labs
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: local-storage
  resources:
    requests:
      storage: 500Mi
EOF

kubectl apply -f local-pvc.yaml

# 4. 创建使用存储的Pod
cat > storage-pod.yaml << EOF
apiVersion: v1
kind: Pod
metadata:
  name: storage-test-pod
  namespace: k8s-labs
spec:
  containers:
  - name: test-container
    image: busybox
    command: ["sleep", "3600"]
    volumeMounts:
    - name: storage-volume
      mountPath: /data
  volumes:
  - name: storage-volume
    persistentVolumeClaim:
      claimName: local-pvc
EOF

kubectl 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-app
  namespace: k8s-labs
spec:
  replicas: 2
  selector:
    matchLabels:
      app: health-app
  template:
    metadata:
      labels:
        app: health-app
    spec:
      containers:
      - name: app
        image: nginx:1.20
        ports:
        - containerPort: 80
        livenessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 10
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 5
        resources:
          requests:
            memory: "64Mi"
            cpu: "100m"
          limits:
            memory: "128Mi"
            cpu: "200m"
---
apiVersion: v1
kind: Service
metadata:
  name: health-app-service
  namespace: k8s-labs
spec:
  selector:
    app: health-app
  ports:
  - port: 80
    targetPort: 80
EOF

kubectl 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: mysql
  namespace: k8s-labs
spec:
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:5.7
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: "rootpassword"
        - name: MYSQL_DATABASE
          value: "webapp"
        - name: MYSQL_USER
          value: "webuser"
        - name: MYSQL_PASSWORD
          value: "webpassword"
        ports:
        - containerPort: 3306
        volumeMounts:
        - name: mysql-storage
          mountPath: /var/lib/mysql
      volumes:
      - name: mysql-storage
        emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
  name: mysql-service
  namespace: k8s-labs
spec:
  selector:
    app: mysql
  ports:
  - port: 3306
    targetPort: 3306
EOF

# 2. 创建后端应用配置
cat > backend-config.yaml << EOF
apiVersion: v1
kind: ConfigMap
metadata:
  name: backend-config
  namespace: k8s-labs
data:
  DATABASE_HOST: "mysql-service"
  DATABASE_NAME: "webapp"
  DATABASE_PORT: "3306"
---
apiVersion: v1
kind: Secret
metadata:
  name: backend-secret
  namespace: k8s-labs
type: Opaque
data:
  DATABASE_USER: d2VidXNlcg==        # webuser
  DATABASE_PASSWORD: d2VicGFzc3dvcmQ=  # webpassword
EOF

# 3. 创建后端应用(使用nginx模拟)
cat > backend-deployment.yaml << EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend
  namespace: k8s-labs
spec:
  replicas: 2
  selector:
    matchLabels:
      app: backend
  template:
    metadata:
      labels:
        app: backend
    spec:
      containers:
      - name: backend
        image: nginx:1.20
        ports:
        - containerPort: 80
        env:
        - name: DATABASE_HOST
          valueFrom:
            configMapKeyRef:
              name: backend-config
              key: DATABASE_HOST
        - name: DATABASE_USER
          valueFrom:
            secretKeyRef:
              name: backend-secret
              key: DATABASE_USER
        livenessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 10
        readinessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 5
---
apiVersion: v1
kind: Service
metadata:
  name: backend-service
  namespace: k8s-labs
spec:
  selector:
    app: backend
  ports:
  - port: 80
    targetPort: 80
EOF

# 4. 创建前端应用
cat > frontend-deployment.yaml << EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend
  namespace: k8s-labs
spec:
  replicas: 3
  selector:
    matchLabels:
      app: frontend
  template:
    metadata:
      labels:
        app: frontend
    spec:
      containers:
      - name: frontend
        image: nginx:1.20
        ports:
        - containerPort: 80
        volumeMounts:
        - name: nginx-config
          mountPath: /etc/nginx/conf.d
      volumes:
      - name: nginx-config
        configMap:
          name: nginx-config
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-config
  namespace: 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-service
  namespace: k8s-labs
spec:
  type: NodePort
  selector:
    app: frontend
  ports:
  - port: 80
    targetPort: 80
    nodePort: 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-test
  namespace: k8s-labs
spec:
  replicas: 1
  selector:
    matchLabels:
      app: hpa-test
  template:
    metadata:
      labels:
        app: hpa-test
    spec:
      containers:
      - name: php-apache
        image: k8s.gcr.io/hpa-example
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: 200m
          limits:
            cpu: 500m
---
apiVersion: v1
kind: Service
metadata:
  name: hpa-test-service
  namespace: k8s-labs
spec:
  selector:
    app: hpa-test
  ports:
  - port: 80
    targetPort: 80
EOF

kubectl 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:故障演练

🎉 总结

恭喜您完成所有练习!通过这些实战练习,您已经掌握了:

  1. 基础操作:Pod、Deployment、Service的创建和管理
  2. 配置管理:ConfigMap和Secret的使用
  3. 存储管理:持久化数据的处理
  4. 健康检查:应用可靠性保障
  5. 完整应用:多组件应用的部署
  6. 自动化:扩缩容和运维自动化

继续实践和探索,成为Kubernetes专家!🚀

📚 下一步学习建议

  1. 深入学习:Helm、Operator、Istio等高级工具
  2. 云原生生态:了解CNCF生态系统
  3. 生产实践:参与实际项目的K8s运维
  4. 社区参与:加入K8s社区,贡献开源项目

加油,K8s专家之路就在脚下!💪


网站公告

今日签到

点亮在社区的每一天
去签到