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

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 | 敏感数据 | 保险箱 |
| Ingress | HTTP 路由 | 大门口指引 |
| 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 dashboard2.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: Always3.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: 5bash
# 部署
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-app3.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: 30004.2 Headless Service(用于 StatefulSet)
yaml
apiVersion: v1
kind: Service
metadata:
name: database
spec:
clusterIP: None # Headless
selector:
app: postgres
ports:
- port: 54324.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.conf5.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: 5Giyaml
# 在 Pod 中使用
spec:
containers:
- name: database
image: postgres:16
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
volumes:
- name: data
persistentVolumeClaim:
claimName: data-pvc6.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 redis7.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 database7.3 创建自定义 Chart
bash
# 创建 Chart 骨架
helm create my-appmy-app/
├── Chart.yaml # Chart 元数据
├── values.yaml # 默认配置值
├── templates/
│ ├── deployment.yaml
│ ├── service.yaml
│ ├── ingress.yaml
│ └── _helpers.tpl # 模板辅助函数
└── charts/ # 依赖的子 Chartyaml
# 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: 256Miyaml
# 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: 512Mi8.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 / privileged8.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: 608.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 是云原生时代的基础设施,掌握它意味着具备了构建大规模容器化应用的能力。
相关阅读: