Kubernetes部署 kubernetes-deployment

掌握 Kubernetes 部署技能,高效管理容器化应用程序,实现多环境部署、自动扩展、滚动更新和蓝绿部署,保障服务的高可用性和安全性。

Docker/K8s 0 次安装 0 次浏览 更新于 3/4/2026

Kubernetes 部署

概览

掌握 Kubernetes 部署,用于大规模管理容器化应用程序,包括多容器服务、资源分配、健康检查和滚动部署策略。

使用场景

  • 容器编排和管理
  • 多环境部署(开发、测试、生产)
  • 自动扩展微服务
  • 滚动更新和蓝绿部署
  • 服务发现和负载均衡
  • 资源配额和限制管理
  • Pod 网络和安全策略

实施示例

1. 完整的部署与资源管理

# kubernetes-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-service
  namespace: production
  labels:
    app: api-service
    version: v1
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      app: api-service
  template:
    metadata:
      labels:
        app: api-service
        version: v1
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "8080"
    spec:
      # 服务账户用于 RBAC
      serviceAccountName: api-service-sa

      # 安全上下文
      securityContext:
        runAsNonRoot: true
        runAsUser: 1000
        fsGroup: 1000

      # Pod 调度
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
            - weight: 100
              podAffinityTerm:
                labelSelector:
                  matchExpressions:
                    - key: app
                      operator: In
                      values:
                        - api-service
                topologyKey: kubernetes.io/hostname

      # Pod 终止宽限期
      terminationGracePeriodSeconds: 30

      # 初始化容器
      initContainers:
        - name: wait-for-db
          image: busybox:1.35
          command: ['sh', '-c', 'until nc -z postgres-service 5432; do echo waiting for db; sleep 2; done']

      containers:
        - name: api-service
          image: myrepo/api-service:1.2.3
          imagePullPolicy: IfNotPresent

          # 端口
          ports:
            - name: http
              containerPort: 8080
              protocol: TCP
            - name: metrics
              containerPort: 9090
              protocol: TCP

          # 环境变量
          env:
            - name: NODE_ENV
              value: "production"
            - name: DATABASE_URL
              valueFrom:
                secretKeyRef:
                  name: api-secrets
                  key: database-url
            - name: LOG_LEVEL
              valueFrom:
                configMapKeyRef:
                  name: api-config
                  key: log-level
            - name: REPLICA_NUM
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name

          # 资源请求和限制
          resources:
            requests:
              memory: "256Mi"
              cpu: "100m"
            limits:
              memory: "512Mi"
              cpu: "500m"

          # 存活探针
          livenessProbe:
            httpGet:
              path: /health
              port: 8080
              scheme: HTTP
            initialDelaySeconds: 30
            periodSeconds: 10
            timeoutSeconds: 5
            failureThreshold: 3

          # 就绪探针
          readinessProbe:
            httpGet:
              path: /ready
              port: 8080
              scheme: HTTP
            initialDelaySeconds: 10
            periodSeconds: 5
            timeoutSeconds: 3
            failureThreshold: 2

          # 卷挂载
          volumeMounts:
            - name: config
              mountPath: /etc/config
              readOnly: true
            - name: cache
              mountPath: /var/cache
            - name: logs
              mountPath: /var/log

          # 安全上下文
          securityContext:
            allowPrivilegeEscalation: false
            readOnlyRootFilesystem: true
            capabilities:
              drop:
                - ALL

      # 卷
      volumes:
        - name: config
          configMap:
            name: api-config
        - name: cache
          emptyDir:
            sizeLimit: 1Gi
        - name: logs
          emptyDir:
            sizeLimit: 2Gi

---
apiVersion: v1
kind: Service
metadata:
  name: api-service
  namespace: production
spec:
  type: ClusterIP
  selector:
    app: api-service
  ports:
    - name: http
      port: 80
      targetPort: 8080
      protocol: TCP
    - name: metrics
      port: 9090
      targetPort: 9090
      protocol: TCP

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: api-config
  namespace: production
data:
  log-level: "INFO"
  max-connections: "100"

---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: api-service-hpa
  namespace: production
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: api-service
  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

2. 部署脚本

#!/bin/bash
# deploy-k8s.sh - 部署到 Kubernetes 集群

set -euo pipefail

NAMESPACE="${1:-production}"
DEPLOYMENT="${2:-api-service}"
IMAGE="${3:-myrepo/api-service:latest}"

echo "Deploying $DEPLOYMENT to namespace $NAMESPACE..."

# 检查集群连接
kubectl cluster-info

# 如果不存在则创建命名空间
kubectl create namespace "$NAMESPACE" --dry-run=client -o yaml | kubectl apply -f -

# 应用配置
kubectl apply -f kubernetes-deployment.yaml -n "$NAMESPACE"

# 等待滚动更新
echo "Waiting for deployment to rollout..."
kubectl rollout status deployment/"$DEPLOYMENT" -n "$NAMESPACE" --timeout=5m

# 验证 Pod 是否运行
echo "Verification:"
kubectl get pods -n "$NAMESPACE" -l "app=$DEPLOYMENT"

# 检查服务
kubectl get svc -n "$NAMESPACE" -l "app=$DEPLOYMENT"

echo "Deployment complete!"

3. 服务账户和 RBAC

apiVersion: v1
kind: ServiceAccount
metadata:
  name: api-service-sa
  namespace: production

---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: api-service-role
  namespace: production
rules:
  - apiGroups: [""]
    resources: ["configmaps"]
    verbs: ["get", "list"]
  - apiGroups: [""]
    resources: ["secrets"]
    verbs: ["get"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: api-service-rolebinding
  namespace: production
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: api-service-role
subjects:
  - kind: ServiceAccount
    name: api-service-sa
    namespace: production

部署模式

滚动更新

  • 逐步替换旧的 Pod 为新的 Pod
  • 零停机部署
  • 失败时自动回滚

蓝绿部署

  • 维护两个相同的环境
  • 立即切换流量
  • 更容易的回滚能力

金丝雀发布

  • 首先部署到一部分用户
  • 在全面推出前监控指标
  • 减少不良部署的风险

最佳实践

✅ 应该做

  • 使用资源请求和限制
  • 实施健康检查(存活性、就绪性)
  • 使用 ConfigMaps 进行配置
  • 应用安全上下文限制
  • 使用服务账户和 RBAC
  • 实施 Pod 反亲和性
  • 使用命名空间进行隔离
  • 启用 Pod 安全策略

❌ 不应该做

  • 在生产中使用最新镜像标签
  • 以 root 用户运行容器
  • 设置无限制的资源使用
  • 跳过就绪探针
  • 无资源限制地部署
  • 在容器镜像中混合配置
  • 使用默认服务账户

资源