Docker + Kubernetes 容器化部署实战:从本地开发到生产环境的完整流程

梦幻星辰1
梦幻星辰1 2026-02-12T23:09:09+08:00
0 0 0

引言

在现代软件开发中,容器化技术已经成为构建和部署应用的标准实践。Docker作为容器化技术的领军者,与Kubernetes这一容器编排平台的结合,为开发者提供了一套完整的现代化应用部署解决方案。本文将从本地开发环境开始,详细介绍从Docker镜像构建、Kubernetes集群部署、CI/CD流水线搭建到监控告警配置的完整容器化部署流程。

1. 环境准备与基础概念

1.1 技术栈概述

在开始实际操作之前,我们需要了解本次实践涉及的核心技术:

  • Docker:容器化平台,用于创建、部署和运行应用程序容器
  • Kubernetes:容器编排平台,用于自动化部署、扩展和管理容器化应用
  • CI/CD:持续集成/持续部署,自动化软件交付流程
  • Helm:Kubernetes包管理器,简化应用部署

1.2 开发环境准备

# 检查Docker版本
docker --version

# 检查Kubernetes版本
kubectl version --client

# 安装minikube(用于本地测试)
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube

2. Docker镜像构建实践

2.1 创建Dockerfile

让我们以一个简单的Node.js应用为例,展示如何构建Docker镜像:

# Dockerfile
FROM node:16-alpine

# 设置工作目录
WORKDIR /app

# 复制package.json和package-lock.json
COPY package*.json ./

# 安装依赖
RUN npm ci --only=production

# 复制应用代码
COPY . .

# 暴露端口
EXPOSE 3000

# 创建非root用户
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001

# 更改文件所有者
USER nextjs

# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:3000/health || exit 1

# 启动应用
CMD ["npm", "start"]

2.2 构建和推送镜像

# 构建镜像
docker build -t myapp:latest .

# 标签镜像
docker tag myapp:latest registry.example.com/myapp:latest

# 推送到镜像仓库
docker push registry.example.com/myapp:latest

# 验证镜像
docker images | grep myapp

2.3 镜像优化最佳实践

# 优化后的Dockerfile
FROM node:16-alpine AS builder

WORKDIR /app

# 先复制package文件
COPY package*.json ./
RUN npm ci --only=production

# 复制源代码
COPY . .

# 生产环境镜像
FROM node:16-alpine

# 创建非root用户
RUN addgroup -g 1001 -S nodejs && \
    adduser -S nextjs -u 1001

WORKDIR /app

# 从builder镜像复制依赖
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/package.json ./package.json

# 暴露端口
EXPOSE 3000

# 更改用户
USER nextjs

# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:3000/health || exit 1

# 启动命令
CMD ["npm", "start"]

3. Kubernetes集群部署

3.1 创建Kubernetes集群

# 启动minikube集群
minikube start --driver=docker --cpus=2 --memory=4096

# 查看集群状态
kubectl cluster-info

# 查看节点
kubectl get nodes

3.2 部署应用

创建应用部署文件:

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
  labels:
    app: myapp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: registry.example.com/myapp:latest
        ports:
        - containerPort: 3000
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m"
          limits:
            memory: "128Mi"
            cpu: "500m"
        livenessProbe:
          httpGet:
            path: /health
            port: 3000
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /ready
            port: 3000
          initialDelaySeconds: 5
          periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
  name: myapp-service
spec:
  selector:
    app: myapp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 3000
  type: LoadBalancer

部署应用:

# 应用部署
kubectl apply -f deployment.yaml

# 查看部署状态
kubectl get deployments
kubectl get pods
kubectl get services

# 查看Pod详细信息
kubectl describe pod <pod-name>

3.3 配置管理

创建ConfigMap和Secret:

# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: myapp-config
data:
  DATABASE_URL: "mongodb://db:27017/myapp"
  API_KEY: "secret-key"
---
apiVersion: v1
kind: Secret
metadata:
  name: myapp-secret
type: Opaque
data:
  DATABASE_PASSWORD: cGFzc3dvcmQxMjM=  # base64编码的密码

在Deployment中使用配置:

# 更新deployment.yaml中的容器配置
spec:
  containers:
  - name: myapp
    image: registry.example.com/myapp:latest
    envFrom:
    - configMapRef:
        name: myapp-config
    - secretRef:
        name: myapp-secret

4. CI/CD流水线搭建

4.1 Jenkins CI/CD配置

// Jenkinsfile
pipeline {
    agent any
    
    environment {
        DOCKER_REGISTRY = 'registry.example.com'
        APP_NAME = 'myapp'
        IMAGE_TAG = "${env.BUILD_NUMBER}"
    }
    
    stages {
        stage('Checkout') {
            steps {
                git branch: 'main', url: 'https://github.com/user/myapp.git'
            }
        }
        
        stage('Build') {
            steps {
                script {
                    docker.build("${DOCKER_REGISTRY}/${APP_NAME}:${IMAGE_TAG}")
                }
            }
        }
        
        stage('Test') {
            steps {
                sh 'npm test'
            }
        }
        
        stage('Security Scan') {
            steps {
                sh 'npm audit'
            }
        }
        
        stage('Push') {
            steps {
                script {
                    docker.withRegistry("https://${DOCKER_REGISTRY}", 'docker-hub-credentials') {
                        docker.image("${DOCKER_REGISTRY}/${APP_NAME}:${IMAGE_TAG}").push()
                    }
                }
            }
        }
        
        stage('Deploy') {
            steps {
                script {
                    sh "kubectl set image deployment/myapp-deployment myapp=${DOCKER_REGISTRY}/${APP_NAME}:${IMAGE_TAG}"
                }
            }
        }
    }
    
    post {
        success {
            echo 'Pipeline completed successfully'
        }
        failure {
            echo 'Pipeline failed'
        }
    }
}

4.2 GitHub Actions配置

# .github/workflows/ci-cd.yml
name: CI/CD Pipeline

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  build:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v2
    
    - name: Setup Node.js
      uses: actions/setup-node@v2
      with:
        node-version: '16'
        
    - name: Install dependencies
      run: npm ci
      
    - name: Run tests
      run: npm test
      
    - name: Build Docker image
      run: |
        docker build -t myapp:${{ github.sha }} .
        
    - name: Login to Docker Hub
      uses: docker/login-action@v1
      with:
        username: ${{ secrets.DOCKER_USERNAME }}
        password: ${{ secrets.DOCKER_PASSWORD }}
        
    - name: Push to Docker Hub
      run: |
        docker tag myapp:${{ github.sha }} myapp:${{ github.sha }}
        docker push myapp:${{ github.sha }}
        
    - name: Deploy to Kubernetes
      run: |
        echo ${{ secrets.KUBECONFIG }} | base64 -d > kubeconfig
        export KUBECONFIG=kubeconfig
        kubectl set image deployment/myapp-deployment myapp=myapp:${{ github.sha }}

5. 高级部署策略

5.1 滚动更新策略

# deployment.yaml - 滚动更新配置
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  template:
    spec:
      containers:
      - name: myapp
        image: registry.example.com/myapp:latest
        ports:
        - containerPort: 3000

5.2 资源管理

# resource-requests.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
spec:
  replicas: 3
  template:
    spec:
      containers:
      - name: myapp
        image: registry.example.com/myapp:latest
        resources:
          requests:
            memory: "128Mi"
            cpu: "100m"
          limits:
            memory: "256Mi"
            cpu: "200m"

5.3 Ingress配置

# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: myapp-service
            port:
              number: 80

6. 监控与告警配置

6.1 Prometheus监控部署

# prometheus-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: prometheus
spec:
  replicas: 1
  selector:
    matchLabels:
      app: prometheus
  template:
    metadata:
      labels:
        app: prometheus
    spec:
      containers:
      - name: prometheus
        image: prom/prometheus:v2.37.0
        ports:
        - containerPort: 9090
        volumeMounts:
        - name: prometheus-config
          mountPath: /etc/prometheus/
      volumes:
      - name: prometheus-config
        configMap:
          name: prometheus-config
---
apiVersion: v1
kind: Service
metadata:
  name: prometheus
spec:
  selector:
    app: prometheus
  ports:
  - port: 9090
    targetPort: 9090
  type: ClusterIP

6.2 Grafana仪表板配置

# grafana-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: grafana
spec:
  replicas: 1
  selector:
    matchLabels:
      app: grafana
  template:
    metadata:
      labels:
        app: grafana
    spec:
      containers:
      - name: grafana
        image: grafana/grafana:9.3.0
        ports:
        - containerPort: 3000
        env:
        - name: GF_SECURITY_ADMIN_PASSWORD
          valueFrom:
            secretKeyRef:
              name: grafana-secret
              key: admin-password
---
apiVersion: v1
kind: Service
metadata:
  name: grafana
spec:
  selector:
    app: grafana
  ports:
  - port: 3000
    targetPort: 3000
  type: ClusterIP

6.3 告警规则配置

# alert-rules.yaml
groups:
- name: myapp.rules
  rules:
  - alert: HighCPUUsage
    expr: rate(container_cpu_usage_seconds_total{container="myapp"}[5m]) > 0.8
    for: 2m
    labels:
      severity: page
    annotations:
      summary: "High CPU usage detected"
      description: "CPU usage is above 80% for more than 2 minutes"
      
  - alert: HighMemoryUsage
    expr: container_memory_usage_bytes{container="myapp"} > 268435456
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "High memory usage detected"
      description: "Memory usage is above 256MB for more than 5 minutes"

7. 安全最佳实践

7.1 Pod安全策略

# pod-security-policy.yaml
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: restricted
spec:
  privileged: false
  allowPrivilegeEscalation: false
  requiredDropCapabilities:
  - ALL
  volumes:
  - 'persistentVolumeClaim'
  - 'configMap'
  - 'secret'
  hostNetwork: false
  hostIPC: false
  hostPID: false
  runAsUser:
    rule: 'MustRunAsNonRoot'
  seLinux:
    rule: 'RunAsAny'
  supplementalGroups:
    rule: 'MustRunAs'
    ranges:
    - min: 1
      max: 65535
  fsGroup:
    rule: 'MustRunAs'
    ranges:
    - min: 1
      max: 65535

7.2 网络策略

# network-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: myapp-network-policy
spec:
  podSelector:
    matchLabels:
      app: myapp
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: frontend
    ports:
    - protocol: TCP
      port: 80
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          name: database
    ports:
    - protocol: TCP
      port: 5432

8. 性能优化与故障排除

8.1 性能监控命令

# 查看Pod资源使用情况
kubectl top pods

# 查看节点资源使用情况
kubectl top nodes

# 查看特定Pod的详细信息
kubectl describe pod <pod-name>

# 查看Pod日志
kubectl logs <pod-name>

# 实时查看日志
kubectl logs -f <pod-name>

8.2 故障排除技巧

# 检查部署状态
kubectl rollout status deployment/myapp-deployment

# 检查事件
kubectl get events --sort-by='.metadata.creationTimestamp'

# 检查配置
kubectl get configmap myapp-config -o yaml

# 检查Secret
kubectl get secret myapp-secret -o yaml

9. 生产环境部署最佳实践

9.1 环境变量管理

# production-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-production
spec:
  replicas: 5
  template:
    spec:
      containers:
      - name: myapp
        image: registry.example.com/myapp:latest
        env:
        - name: NODE_ENV
          value: "production"
        - name: LOG_LEVEL
          value: "info"
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: myapp-db-secret
              key: url
        resources:
          requests:
            memory: "256Mi"
            cpu: "200m"
          limits:
            memory: "512Mi"
            cpu: "500m"

9.2 自动扩缩容

# hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: myapp-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: myapp-deployment
  minReplicas: 3
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80

结论

通过本文的详细实践,我们完成了从本地开发到生产环境的完整容器化部署流程。从基础的Docker镜像构建,到Kubernetes集群部署,再到CI/CD流水线搭建和监控告警配置,每一个环节都体现了容器化技术的核心价值。

成功的容器化部署不仅仅是技术实现,更需要考虑安全性、可扩展性、可维护性等多个方面。通过合理的资源配置、完善的监控体系和自动化流程,我们可以确保应用在生产环境中稳定可靠地运行。

在实际项目中,建议根据具体业务需求调整资源配置、安全策略和监控指标。同时,持续优化和改进部署流程,建立完善的运维体系,是确保容器化应用长期成功的关键。

随着技术的不断发展,容器化技术将继续演进,但其核心理念——将应用及其依赖打包成轻量级、可移植的容器,以实现一致性和可重复性——将始终是现代软件开发的重要基础。

相关推荐
广告位招租

相似文章

    评论 (0)

    0/2000