Kubernetes 基础、Pod/Deployment/Service — 语法详解与实战案例
一、引入
Kubernetes(简称 K8s)是目前最主流的容器编排平台,用于自动化部署、扩展和管理容器化应用。掌握 K8s 基础,是迈向云原生架构的关键一步。
本章重点:
- Kubernetes 核心概念与架构
- Pod:最小部署单元
- Deployment:声明式应用管理
- Service:服务发现与负载均衡
- 综合实战:部署 Web 应用 + MySQL
✅ 本章默认你已安装 Kubernetes 集群(如使用 kubeadm、minikube 或云厂商托管集群)。
二、Kubernetes 基础概念
1. 核心组件
| 组件 | 作用 |
|---|---|
kubectl | 命令行工具,与集群交互 |
kube-apiserver | API 入口,接收所有操作请求 |
kube-scheduler | 调度 Pod 到合适的 Node |
kube-controller-manager | 控制器管理(如 Deployment、Node) |
kubelet | Node 上的代理,管理 Pod 生命周期 |
kube-proxy | 实现 Service 的网络代理和负载均衡 |
etcd | 分布式键值存储,保存集群状态 |
2. 基本对象
| 对象 | 作用 |
|---|---|
Pod | 最小部署单元,包含一个或多个容器 |
Deployment | 管理 Pod 副本,支持滚动更新、回滚 |
Service | 为 Pod 提供稳定访问入口和负载均衡 |
Namespace | 资源隔离(如 dev/test/prod) |
ConfigMap | 存储配置数据 |
Secret | 存储敏感数据(如密码、密钥) |
三、Pod — 最小部署单元
1. Pod 基本结构
apiVersion: v1
kind: Pod
metadata:
name: my-pod
labels:
app: myapp
spec:
containers:
- name: my-container
image: nginx:latest
ports:
- containerPort: 80
📘 案例1:创建并管理 Pod
# 文件:pod-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: web
spec:
containers:
- name: nginx-container
image: nginx:1.25
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
# 1. 创建 Pod
kubectl apply -f pod-demo.yaml
# 2. 查看 Pod 状态
kubectl get pods
# 输出:
# NAME READY STATUS RESTARTS AGE
# nginx-pod 1/1 Running 0 10s
# 3. 查看 Pod 详细信息
kubectl describe pod nginx-pod
# 4. 查看 Pod 日志
kubectl logs nginx-pod
# 5. 进入 Pod 容器
kubectl exec -it nginx-pod -- /bin/bash
# 6. 删除 Pod
kubectl delete pod nginx-pod
⚠️ Pod 是临时的,删除后不会自动重建!
四、Deployment — 声明式应用管理
1. Deployment 基本结构
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deployment
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: my-container
image: nginx:latest
📘 案例2:创建 Deployment
# 文件:deployment-demo.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
# 1. 创建 Deployment
kubectl apply -f deployment-demo.yaml
# 2. 查看 Deployment
kubectl get deployments
# 输出:
# NAME READY UP-TO-DATE AVAILABLE AGE
# nginx-deployment 3/3 3 3 30s
# 3. 查看关联的 Pod
kubectl get pods -l app=nginx
# 4. 扩容到 5 个副本
kubectl scale deployment nginx-deployment --replicas=5
# 5. 查看扩容结果
kubectl get pods -l app=nginx
# 6. 更新镜像(触发滚动更新)
kubectl set image deployment/nginx-deployment nginx=nginx:1.26
# 7. 查看更新状态
kubectl rollout status deployment/nginx-deployment
# 8. 查看更新历史
kubectl rollout history deployment/nginx-deployment
# 9. 回滚到上一个版本
kubectl rollout undo deployment/nginx-deployment
# 10. 删除 Deployment
kubectl delete deployment nginx-deployment
✅ Deployment 会自动管理 Pod,确保副本数符合预期!
五、Service — 服务发现与负载均衡
1. Service 类型
| 类型 | 作用 |
|---|---|
ClusterIP | 集群内部访问(默认) |
NodePort | 通过 Node IP + 端口访问 |
LoadBalancer | 云厂商负载均衡器(外部访问) |
ExternalName | 映射到外部 DNS 名称 |
📘 案例3:创建 Service
# 文件:service-demo.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80 # Service 端口
targetPort: 80 # Pod 端口
type: NodePort # 类型:NodePort
# 1. 创建 Service(确保已有 Deployment)
kubectl apply -f service-demo.yaml
# 2. 查看 Service
kubectl get services
# 输出:
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
# nginx-service NodePort 10.96.123.123 <none> 80:30080/TCP 10s
# 3. 访问应用(通过 Node IP + NodePort)
curl http://<NodeIP>:30080
# 4. 查看 Endpoints(Service 关联的 Pod)
kubectl get endpoints nginx-service
# 5. 删除 Service
kubectl delete service nginx-service
💡
NodePort范围默认 30000-32767,可在 kube-apiserver 中配置。
📘 案例4:ClusterIP Service(内部访问)
# 文件:clusterip-service.yaml
apiVersion: v1
kind: Service
metadata:
name: mysql-service
spec:
selector:
app: mysql
ports:
- protocol: TCP
port: 3306
targetPort: 3306
type: ClusterIP
# 在集群内其他 Pod 中访问:
# mysql://mysql-service:3306
六、综合性实战案例
▶ 案例5:部署 WordPress + MySQL 应用
# 文件:wordpress-stack.yaml
# 功能:部署 WordPress + MySQL,通过 Service 暴露
---
# 1. MySQL Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-deployment
labels:
app: mysql
spec:
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
env:
- name: MYSQL_ROOT_PASSWORD
value: "wordpress123"
- name: MYSQL_DATABASE
value: "wordpress"
ports:
- containerPort: 3306
volumeMounts:
- name: mysql-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-storage
emptyDir: {}
---
# 2. MySQL Service
apiVersion: v1
kind: Service
metadata:
name: mysql-service
spec:
selector:
app: mysql
ports:
- protocol: TCP
port: 3306
targetPort: 3306
type: ClusterIP
---
# 3. WordPress Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress-deployment
labels:
app: wordpress
spec:
replicas: 2
selector:
matchLabels:
app: wordpress
template:
metadata:
labels:
app: wordpress
spec:
containers:
- name: wordpress
image: wordpress:6.5
env:
- name: WORDPRESS_DB_HOST
value: "mysql-service:3306"
- name: WORDPRESS_DB_USER
value: "root"
- name: WORDPRESS_DB_PASSWORD
value: "wordpress123"
- name: WORDPRESS_DB_NAME
value: "wordpress"
ports:
- containerPort: 80
volumeMounts:
- name: wordpress-storage
mountPath: /var/www/html
volumes:
- name: wordpress-storage
emptyDir: {}
---
# 4. WordPress Service
apiVersion: v1
kind: Service
metadata:
name: wordpress-service
spec:
selector:
app: wordpress
ports:
- protocol: TCP
port: 80
targetPort: 80
type: NodePort
# 1. 部署整个应用
kubectl apply -f wordpress-stack.yaml
# 2. 查看所有资源
kubectl get all -o wide
# 3. 获取 WordPress 访问地址
NODE_IP=$(kubectl get nodes -o jsonpath='{.items[0].status.addresses[0].address}')
NODE_PORT=$(kubectl get service wordpress-service -o jsonpath='{.spec.ports[0].nodePort}')
echo "🌐 WordPress 访问地址: http://$NODE_IP:$NODE_PORT"
# 4. 查看 Pod 状态
kubectl get pods -l app=wordpress
kubectl get pods -l app=mysql
# 5. 查看日志
kubectl logs -l app=wordpress --tail=10
# 6. 进入 MySQL 容器
kubectl exec -it $(kubectl get pods -l app=mysql -o jsonpath='{.items[0].metadata.name}') -- mysql -uroot -pwordpress123
# 7. 删除整个应用
kubectl delete -f wordpress-stack.yaml
▶ 案例6:健康检查与资源限制实战
# 文件:health-resource-demo.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: health-check-demo
spec:
replicas: 2
selector:
matchLabels:
app: health-demo
template:
metadata:
labels:
app: health-demo
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
# 资源限制
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
# 健康检查
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3
# 1. 部署
kubectl apply -f health-resource-demo.yaml
# 2. 查看 Pod 状态(READY 列显示就绪副本数)
kubectl get pods
# 3. 查看事件(健康检查失败会记录)
kubectl describe pod -l app=health-demo
# 4. 模拟故障(进入容器删除 index.html)
POD_NAME=$(kubectl get pods -l app=health-demo -o jsonpath='{.items[0].metadata.name}')
kubectl exec -it $POD_NAME -- rm /usr/share/nginx/html/index.html
# 5. 观察 Pod 重启(livenessProbe 失败)
kubectl get pods -w
# 6. 恢复文件
kubectl exec -it $POD_NAME -- touch /usr/share/nginx/html/index.html
# 7. 清理
kubectl delete -f health-resource-demo.yaml
▶ 案例7:多环境部署(Namespace + ConfigMap)
# 文件:multi-env-demo.yaml
---
# 1. 创建命名空间
apiVersion: v1
kind: Namespace
metadata:
name: dev
---
apiVersion: v1
kind: Namespace
metadata:
name: prod
---
# 2. Dev 环境 ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config-dev
namespace: dev
data:
APP_ENV: "development"
DATABASE_URL: "mysql://dev-db:3306/myapp"
---
# 3. Prod 环境 ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config-prod
namespace: prod
data:
APP_ENV: "production"
DATABASE_URL: "mysql://prod-db:3306/myapp"
---
# 4. Dev Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
namespace: dev
spec:
replicas: 2
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: app
image: nginx:1.25
envFrom:
- configMapRef:
name: app-config-dev
ports:
- containerPort: 80
---
# 5. Prod Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
namespace: prod
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: app
image: nginx:1.25
envFrom:
- configMapRef:
name: app-config-prod
ports:
- containerPort: 80
---
# 6. Dev Service
apiVersion: v1
kind: Service
metadata:
name: app-service
namespace: dev
spec:
selector:
app: myapp
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIP
---
# 7. Prod Service
apiVersion: v1
kind: Service
metadata:
name: app-service
namespace: prod
spec:
selector:
app: myapp
ports:
- protocol: TCP
port: 80
targetPort: 80
type: NodePort
# 1. 部署多环境
kubectl apply -f multi-env-demo.yaml
# 2. 查看命名空间
kubectl get namespaces
# 3. 查看 Dev 环境资源
kubectl get all -n dev
# 4. 查看 Prod 环境资源
kubectl get all -n prod
# 5. 查看 ConfigMap
kubectl get configmap -n dev
kubectl get configmap -n prod
# 6. 进入 Dev Pod 查看环境变量
DEV_POD=$(kubectl get pods -n dev -o jsonpath='{.items[0].metadata.name}')
kubectl exec -n dev $DEV_POD -- env | grep APP_ENV
# 7. 清理
kubectl delete -f multi-env-demo.yaml
七、小结
✅ 本章你已掌握:
- Kubernetes 基础:核心组件与对象
- Pod:最小部署单元,临时性容器组
- Deployment:声明式管理,支持扩缩容、滚动更新、回滚
- Service:服务发现与负载均衡(ClusterIP/NodePort)
- 综合实战:WordPress 部署、健康检查、多环境管理
📌 Kubernetes 最佳实践:
- 使用 Deployment 而非直接管理 Pod
- 为容器设置资源请求和限制
- 使用健康检查(liveness/readiness)确保服务可用
- 使用 Namespace 隔离不同环境
- 使用 ConfigMap/Secret 管理配置和敏感数据
- 服务间通过 Service 名称进行 DNS 解析
掌握本章内容后,你将能部署和管理生产级 Kubernetes 应用,为微服务架构、云原生转型打下坚实基础!

3973

被折叠的 条评论
为什么被折叠?



