跳转到内容

Kubernetes 入门与生产部署实战 2026 | 容器编排完全指南

Kubernetes 入门与生产部署实战

Kubernetes(K8s)是容器编排的事实标准。当 Docker Compose 无法满足大规模容器管理需求时,K8s 提供了自动扩缩容、自愈、服务发现等强大能力。本文将从核心概念到生产部署,系统讲解 K8s 实战。


一、Kubernetes 核心概念

1.1 架构概览

┌─────────────────────────────────────────────────────────────┐
│                    Kubernetes Cluster                        │
│                                                              │
│  ┌──────────────────────┐    ┌──────────────────────────┐  │
│  │   Control Plane       │    │     Worker Nodes          │  │
│  │  (Master)             │    │                           │  │
│  │                       │    │  ┌─────────────────────┐  │  │
│  │  • API Server         │◄──►│  │ kubelet             │  │  │
│  │  • etcd               │    │  │ kube-proxy          │  │  │
│  │  • Scheduler          │    │  │ Container Runtime   │  │  │
│  │  • Controller Manager │    │  │   (containerd)      │  │  │
│  │  • Cloud Controller   │    │  │                     │  │  │
│  └──────────────────────┘    │  │   Pod → Pod → Pod   │  │  │
│                              │  └─────────────────────┘  │  │
│                              └──────────────────────────┘  │
└─────────────────────────────────────────────────────────────┘

1.2 核心对象

对象说明类比
Pod最小调度单位,包含一个或多个容器一间办公室
Deployment管理 Pod 的副本和更新办公室管理层
Service为 Pod 提供稳定的网络访问前台总机
ConfigMap配置数据配置文件
Secret敏感数据保险箱
IngressHTTP 路由大门口指引
Volume存储卷文件柜
Namespace资源隔离楼层

二、本地环境搭建

2.1 Minikube(推荐入门)

bash
# 安装 Minikube(macOS)
brew install minikube

# 启动集群
minikube start --driver=docker --kubernetes-version=v1.30.0

# 验证
kubectl get nodes
# NAME       STATUS   ROLES           AGE   VERSION
# minikube   Ready    control-plane   1m    v1.30.0

# 启动 Dashboard
minikube dashboard

2.2 kubectl 命令行工具

bash
# 安装
brew install kubectl

# 常用命令
kubectl get pods                    # 查看 Pod
kubectl get deployments             # 查看 Deployment
kubectl get services                # 查看 Service
kubectl get nodes                   # 查看节点
kubectl describe pod <pod-name>     # 查看详情
kubectl logs <pod-name>             # 查看日志
kubectl exec -it <pod-name> -- sh   # 进入容器
kubectl apply -f <file.yaml>        # 应用配置
kubectl delete -f <file.yaml>       # 删除资源
kubectl scale deployment <name> --replicas=3  # 扩缩容

三、Pod 与 Deployment

3.1 Pod 基本定义

yaml
# pod-simple.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
    app: nginx
spec:
  containers:
    - name: nginx
      image: nginx:1.25-alpine
      ports:
        - containerPort: 80
      resources:
        requests:
          cpu: 100m
          memory: 128Mi
        limits:
          cpu: 200m
          memory: 256Mi
      livenessProbe:
        httpGet:
          path: /
          port: 80
        initialDelaySeconds: 5
        periodSeconds: 10
      readinessProbe:
        httpGet:
          path: /
          port: 80
        initialDelaySeconds: 3
        periodSeconds: 5
  restartPolicy: Always

3.2 Deployment 部署

yaml
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
  namespace: production
  labels:
    app: web
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: web
          image: my-registry/web-app:v1.0.0
          ports:
            - containerPort: 3000
          env:
            - name: NODE_ENV
              value: production
            - name: DATABASE_URL
              valueFrom:
                secretKeyRef:
                  name: app-secrets
                  key: database-url
          resources:
            requests:
              cpu: 250m
              memory: 256Mi
            limits:
              cpu: 500m
              memory: 512Mi
          livenessProbe:
            httpGet:
              path: /health
              port: 3000
            initialDelaySeconds: 15
            periodSeconds: 10
            failureThreshold: 3
          readinessProbe:
            httpGet:
              path: /ready
              port: 3000
            initialDelaySeconds: 5
            periodSeconds: 5
bash
# 部署
kubectl apply -f deployment.yaml

# 查看部署状态
kubectl rollout status deployment/web-app

# 查看副本
kubectl get pods -l app=web

# 滚动更新(更新镜像版本)
kubectl set image deployment/web-app web=my-registry/web-app:v1.1.0

# 回滚
kubectl rollout undo deployment/web-app
kubectl rollout undo deployment/web-app --to-revision=2

# 查看历史
kubectl rollout history deployment/web-app

3.3 多容器 Pod(Sidecar 模式)

yaml
# sidecar.yaml
apiVersion: v1
kind: Pod
metadata:
  name: app-with-sidecar
spec:
  containers:
    # 主容器:Web 应用
    - name: web
      image: my-app:v1
      ports:
        - containerPort: 3000
      volumeMounts:
        - name: logs
          mountPath: /var/log/app

    # Sidecar:日志收集
    - name: log-collector
      image: fluent-bit:3.0
      volumeMounts:
        - name: logs
          mountPath: /var/log/app
          readOnly: true

  volumes:
    - name: logs
      emptyDir: {}

四、Service 与网络

4.1 Service 类型

yaml
# 1. ClusterIP(默认,集群内部访问)
apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  type: ClusterIP
  selector:
    app: web
  ports:
    - port: 80
      targetPort: 3000
---
# 2. NodePort(暴露到节点端口)
apiVersion: v1
kind: Service
metadata:
  name: web-nodeport
spec:
  type: NodePort
  selector:
    app: web
  ports:
    - port: 80
      targetPort: 3000
      nodePort: 30080
---
# 3. LoadBalancer(云负载均衡器)
apiVersion: v1
kind: Service
metadata:
  name: web-lb
spec:
  type: LoadBalancer
  selector:
    app: web
  ports:
    - port: 80
      targetPort: 3000

4.2 Headless Service(用于 StatefulSet)

yaml
apiVersion: v1
kind: Service
metadata:
  name: database
spec:
  clusterIP: None  # Headless
  selector:
    app: postgres
  ports:
    - port: 5432

4.3 Ingress 路由

yaml
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web-ingress
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/rate-limit: "100"
    cert-manager.io/cluster-issuer: "letsencrypt"
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - api.example.com
        - app.example.com
      secretName: tls-secret
  rules:
    - host: api.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: api-service
                port:
                  number: 80
    - host: app.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: web-service
                port:
                  number: 80

五、配置管理

5.1 ConfigMap

yaml
# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  # 简单键值
  LOG_LEVEL: "info"
  API_TIMEOUT: "5000"
  CACHE_TTL: "3600"

  # 配置文件
  nginx.conf: |
    server {
      listen 80;
      location / {
        proxy_pass http://backend:3000;
      }
    }
yaml
# 在 Deployment 中使用
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app
spec:
  template:
    spec:
      containers:
        - name: app
          image: my-app:v1
          envFrom:
            - configMapRef:
                name: app-config
          volumeMounts:
            - name: config-volume
              mountPath: /etc/nginx/conf.d
      volumes:
        - name: config-volume
          configMap:
            name: app-config
            items:
              - key: nginx.conf
                path: default.conf

5.2 Secret

bash
# 创建 Secret
kubectl create secret generic app-secrets \
  --from-literal=database-url="postgresql://user:pass@db:5432/myapp" \
  --from-literal=api-key="sk-xxxxxxxxxxxx" \
  --from-literal=jwt-secret="my-jwt-secret"
yaml
# secret.yaml(Base64 编码)
apiVersion: v1
kind: Secret
metadata:
  name: app-secrets
type: Opaque
data:
  database-url: cG9zdGdyZXNxbDovL3VzZXI6cGFzc0BkYjo1NDMyL215YXBw
  api-key: c2steHh4eHh4eHh4eHh4eHg=
  jwt-secret: bXktand0LXNlY3JldA==
yaml
# 在 Pod 中使用
spec:
  containers:
    - name: app
      env:
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: app-secrets
              key: database-url
        - name: API_KEY
          valueFrom:
            secretKeyRef:
              name: app-secrets
              key: api-key

六、存储管理

6.1 PersistentVolume 与 PVC

yaml
# pv.yaml — 持久卷
apiVersion: v1
kind: PersistentVolume
metadata:
  name: data-pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: standard
  hostPath:
    path: /mnt/data
---
# pvc.yaml — 持久卷声明
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: data-pvc
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: standard
  resources:
    requests:
      storage: 5Gi
yaml
# 在 Pod 中使用
spec:
  containers:
    - name: database
      image: postgres:16
      volumeMounts:
        - name: data
          mountPath: /var/lib/postgresql/data
  volumes:
    - name: data
      persistentVolumeClaim:
        claimName: data-pvc

6.2 StorageClass(动态 provisioning)

yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast-ssd
provisioner: kubernetes.io/aws-ebs
parameters:
  type: gp3
  fsType: ext4
reclaimPolicy: Retain
allowVolumeExpansion: true
volumeBindingMode: WaitForFirstConsumer

七、Helm 包管理

7.1 安装 Helm

bash
# 安装
brew install helm

# 添加仓库
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update

# 搜索
helm search repo redis

7.2 使用 Helm Chart

bash
# 安装 Redis
helm install my-redis bitnami/redis \
  --namespace database \
  --create-namespace \
  --set auth.password="my-password" \
  --set replica.replicaCount=3

# 查看已安装的 Chart
helm list -n database

# 升级
helm upgrade my-redis bitnami/redis \
  --set replica.replicaCount=5

# 卸载
helm uninstall my-redis -n database

7.3 创建自定义 Chart

bash
# 创建 Chart 骨架
helm create my-app
my-app/
├── Chart.yaml          # Chart 元数据
├── values.yaml         # 默认配置值
├── templates/
│   ├── deployment.yaml
│   ├── service.yaml
│   ├── ingress.yaml
│   └── _helpers.tpl    # 模板辅助函数
└── charts/             # 依赖的子 Chart
yaml
# values.yaml
replicaCount: 3
image:
  repository: my-app
  tag: latest
  pullPolicy: IfNotPresent
service:
  type: ClusterIP
  port: 80
ingress:
  enabled: true
  host: app.example.com
resources:
  limits:
    cpu: 500m
    memory: 512Mi
  requests:
    cpu: 250m
    memory: 256Mi
yaml
# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "my-app.fullname" . }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      app: {{ include "my-app.name" . }}
  template:
    metadata:
      labels:
        app: {{ include "my-app.name" . }}
    spec:
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          ports:
            - containerPort: {{ .Values.service.port }}
          resources:
            {{- toYaml .Values.resources | nindent 12 }}
bash
# 模板渲染(预览)
helm template my-app ./my-app

# 安装
helm install my-app ./my-app -n production

# 打包
helm package ./my-app

八、生产环境最佳实践

8.1 健康检查

yaml
spec:
  containers:
    - name: app
      # 存活探针:失败会重启容器
      livenessProbe:
        httpGet:
          path: /healthz
          port: 3000
        initialDelaySeconds: 15
        periodSeconds: 10
        failureThreshold: 3
        timeoutSeconds: 3

      # 就绪探针:失败会从 Service 摘除
      readinessProbe:
        httpGet:
          path: /readyz
          port: 3000
        initialDelaySeconds: 5
        periodSeconds: 5
        failureThreshold: 3

      # 启动探针:应用启动慢时使用
      startupProbe:
        httpGet:
          path: /startup
          port: 3000
        initialDelaySeconds: 0
        periodSeconds: 5
        failureThreshold: 30  # 最多等 150 秒启动

8.2 资源管理

yaml
spec:
  containers:
    - name: app
      resources:
        # 请求:调度依据
        requests:
          cpu: 250m      # 0.25 核
          memory: 256Mi
        # 限制:硬上限
        limits:
          cpu: 500m      # 0.5 核
          memory: 512Mi

8.3 安全加固

yaml
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
    fsGroup: 2000
  containers:
    - name: app
      securityContext:
        allowPrivilegeEscalation: false
        readOnlyRootFilesystem: true
        capabilities:
          drop: [ALL]
  # Pod Security Standards
  # restricted / baseline / privileged

8.4 HPA 自动扩缩容

yaml
# hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: web-app-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web-app
  minReplicas: 3
  maxReplicas: 20
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
    - type: Resource
      resource:
        name: memory
        target:
          type: Utilization
          averageUtilization: 80
  behavior:
    scaleDown:
      stabilizationWindowSeconds: 300
      policies:
        - type: Percent
          value: 50
          periodSeconds: 60

8.5 PodDisruptionBudget

yaml
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: web-app-pdb
spec:
  minAvailable: 2  # 至少保持 2 个可用
  selector:
    matchLabels:
      app: web

九、CI/CD 集成

9.1 GitHub Actions 部署到 K8s

yaml
# .github/workflows/deploy-k8s.yml
name: Deploy to K8s

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ap-northeast-1

      - name: Login to ECR
        uses: aws-actions/amazon-ecr-login@v2

      - name: Build and push
        env:
          ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
          IMAGE_TAG: ${{ github.sha }}
        run: |
          docker build -t $ECR_REGISTRY/web-app:$IMAGE_TAG .
          docker push $ECR_REGISTRY/web-app:$IMAGE_TAG

      - name: Configure kubectl
        run: |
          aws eks update-kubeconfig --name my-cluster --region ap-northeast-1

      - name: Deploy
        run: |
          kubectl set image deployment/web-app \
            web=$ECR_REGISTRY/web-app:${{ github.sha }} \
            -n production
          kubectl rollout status deployment/web-app -n production

十、总结

  • ✅ K8s 架构与核心概念(Pod、Deployment、Service)
  • ✅ 本地开发环境搭建(Minikube + kubectl)
  • ✅ Pod 与 Deployment 部署(滚动更新、回滚、Sidecar)
  • ✅ Service 与 Ingress 网络路由
  • ✅ 配置管理(ConfigMap、Secret)
  • ✅ 存储管理(PV、PVC、StorageClass)
  • ✅ Helm 包管理(安装 Chart、自定义 Chart)
  • ✅ 生产最佳实践(健康检查、资源管理、安全加固、HPA、PDB)
  • ✅ CI/CD 集成(GitHub Actions 自动部署)

Kubernetes 是云原生时代的基础设施,掌握它意味着具备了构建大规模容器化应用的能力。


相关阅读: