Kubernetes 入门——从 Docker 到容器编排

Kubernetes 入门——从 Docker 到容器编排

作者: CaoZH
日期: 2024-08-15
本文为原创教程


当你用 Docker Compose 管理三五台服务器时,一切都很美好。但当你的服务增长到几十个、需要自动扩缩容、滚动更新、服务发现时,Docker Compose 就不够用了。这时候你需要 Kubernetes(K8s)

Kubernetes 是 2024 年容器编排的事实标准,几乎所有的云平台都支持 K8s。本文带你从零理解 K8s 的核心概念并上手操作。

一、Kubernetes 是什么?

Kubernetes(简称 K8s)是 Google 开源的容器编排平台,用于自动部署、扩缩和管理容器化应用。

K8s 能做什么?

能力 说明
服务发现与负载均衡 自动分配 IP 和 DNS,负载均衡流量
自动扩缩容 根据 CPU/内存使用率自动增减副本
自动部署与回滚 滚动更新,出问题自动回滚到上个版本
自我修复 容器挂了自动重启,节点挂了自动迁移
配置管理 ConfigMap 和 Secret 管理配置和密钥
存储编排 自动挂载本地或云存储

二、核心概念

架构图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
┌─────────────────────────────────────────────────────┐
│ Master Node │
│ ┌──────────┐ ┌──────────┐ ┌──────────────────┐ │
│ │ API Server │ │ Scheduler │ │ Controller Manager │
│ └──────────┘ └──────────┘ └──────────────────┘ │
│ ┌──────────────────────────────────────────────┐ │
│ │ etcd(存储集群状态) │ │
│ └──────────────────────────────────────────────┘ │
└────────────────────────┬────────────────────────────┘

┌────────────────────────┼────────────────────────────┐
│ Worker Node 1 │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Pod │ │ Pod │ │ Pod │ │
│ │ (Container) │ │ (Container) │ │ (Container) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ ┌──────────────────┐ ┌──────────────────────────┐ │
│ │ kubelet │ │ kube-proxy │ │
│ └──────────────────┘ └──────────────────────────┘ │
└──────────────────────────────────────────────────────┘

核心资源

资源 说明 类比
Pod 最小的部署单元,包含一个或多个容器 豆荚
Deployment 管理 Pod 的声明式更新 副本控制器
Service 稳定的网络入口,负载均衡到 Pod 负载均衡器
Ingress 七层 HTTP 路由规则 网关
ConfigMap 非敏感配置 配置文件
Secret 敏感信息(密码、密钥) 保险箱
PersistentVolume 持久化存储 硬盘

三、搭建本地环境

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 安装 kubectl(K8s 命令行工具)
curl -LO "https://dl.k8s.io/release/v1.30.0/bin/linux/amd64/kubectl"
chmod +x kubectl
sudo mv kubectl /usr/local/bin/

# 安装 Minikube(本地单节点 K8s 集群)
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube

# 启动集群
minikube start --driver=docker

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

四、部署第一个应用

1. 创建 Deployment

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3 # 3 个副本
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "100m"
limits:
memory: "128Mi"
cpu: "200m"
1
2
3
4
5
6
7
# 部署
kubectl apply -f deployment.yaml

# 查看
kubectl get deployments
kubectl get pods -o wide
kubectl describe pod nginx-deployment-xxx

2. 创建 Service

1
2
3
4
5
6
7
8
9
10
11
12
# service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
type: NodePort
1
2
3
4
5
kubectl apply -f service.yaml
kubectl get services

# 暴露到本地
minikube service nginx-service

3. 滚动更新

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 更新镜像版本
kubectl set image deployment/nginx-deployment nginx=nginx:1.25

# 查看更新状态
kubectl rollout status deployment/nginx-deployment

# 查看更新历史
kubectl rollout history deployment/nginx-deployment

# 回滚到上一个版本
kubectl rollout undo deployment/nginx-deployment

# 回滚到指定版本
kubectl rollout undo deployment/nginx-deployment --to-revision=1

五、Ingress 配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080

六、ConfigMap 与 Secret

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
app.properties: |
app.name=myapp
app.version=1.0.0
log.level=INFO
database.url: jdbc:mysql://mysql-service:3306/myapp
---
apiVersion: v1
kind: Secret
metadata:
name: app-secret
type: Opaque
data:
db-password: cGFzc3dvcmQxMjM= # base64 编码
api-key: c2stdGVzdC1hcGkta2V5
1
2
3
4
5
6
7
# 创建
kubectl apply -f configmap.yaml

# 查看
kubectl get configmaps
kubectl get secrets
kubectl describe configmap app-config

在 Pod 中使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
apiVersion: v1
kind: Pod
metadata:
name: config-test
spec:
containers:
- name: app
image: nginx:alpine
env:
- name: DB_URL
valueFrom:
configMapKeyRef:
name: app-config
key: database.url
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: app-secret
key: db-password
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: app-config

七、常用 kubectl 命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 资源管理
kubectl get pods # 查看 Pod 列表
kubectl get pods -o wide # 显示更多信息
kubectl get all # 查看所有资源
kubectl describe pod my-pod # 查看 Pod 详情
kubectl logs -f my-pod # 查看日志
kubectl exec -it my-pod -- bash # 进入容器

# 调试
kubectl port-forward pod/my-pod 8080:80 # 端口转发
kubectl top pods # 查看资源使用
kubectl top nodes # 查看节点资源

# 删除资源
kubectl delete pod my-pod
kubectl delete deployment my-deployment
kubectl delete -f deployment.yaml

# 别名推荐(效率翻倍)
alias k='kubectl'
alias kg='kubectl get'
alias kd='kubectl describe'
alias kl='kubectl logs -f'
alias kx='kubectl exec -it'

八、总结

K8s 学习曲线确实陡峭,但掌握之后带来的收益巨大:

学习阶段 掌握内容
✅ 基础概念 Pod、Deployment、Service
✅ 网络 Service 类型、Ingress
✅ 配置 ConfigMap、Secret
✅ 存储 PV、PVC
✅ 运维 滚动更新、回滚、扩缩容

如果你是个人开发者,建议先用 MinikubeK3s 上手,不需要一开始就搞生产集群。


首发于 CaoZH 的笔记