Docker与Kubernetes完全掌握第8篇:完全理解Pod、Deployment、Service
Docker & Kubernetes Complete Guide Part 8: Understanding Pod, Deployment, and Service
前言:掌握Kubernetes核心资源
要有效地使用Kubernetes,必须完全理解三个核心资源:Pod、Deployment和Service。这三者是在Kubernetes中部署和运营应用程序最基本的构建块。在本第8篇中,我们将详细介绍每个资源的概念、YAML编写方法以及实际使用模式。
1. 深入理解Pod
Pod是Kubernetes中可部署的最小单元。它包含一个或多个容器,同一Pod内的容器共享网络和存储。
1.1 Pod的特点
- 容器组:可以在一个Pod中放置多个容器
- 共享网络:同一Pod内的容器通过localhost通信
- 共享存储:可以通过卷共享数据
- 临时性:Pod可能随时被删除和重新创建
- 唯一IP:每个Pod在集群中有唯一的IP地址
1.2 Sidecar模式
Sidecar模式是将辅助容器与主容器一起部署的模式。用于日志收集、代理、配置管理等。
# sidecar-example.yaml
apiVersion: v1
kind: Pod
metadata:
name: web-with-sidecar
spec:
containers:
# 主应用程序容器
- name: web-app
image: nginx:1.25
ports:
- containerPort: 80
volumeMounts:
- name: shared-logs
mountPath: /var/log/nginx
# Sidecar:日志收集
- name: log-collector
image: busybox
command: ['sh', '-c', 'tail -F /var/log/nginx/access.log']
volumeMounts:
- name: shared-logs
mountPath: /var/log/nginx
volumes:
- name: shared-logs
emptyDir: {}
1.3 Init Container
Init Container是在主容器启动之前运行的初始化容器。用于等待数据库、创建配置文件、设置权限等。
# init-container-example.yaml
apiVersion: v1
kind: Pod
metadata:
name: app-with-init
spec:
initContainers:
# 第一个Init Container:等待数据库
- name: wait-for-db
image: busybox
command: ['sh', '-c', 'until nc -z mysql-service 3306; do echo waiting for db; sleep 2; done']
# 第二个Init Container:准备配置文件
- name: prepare-config
image: busybox
command: ['sh', '-c', 'cp /config-source/app.conf /config/app.conf']
volumeMounts:
- name: config-volume
mountPath: /config
- name: config-source
mountPath: /config-source
containers:
- name: main-app
image: my-app:latest
volumeMounts:
- name: config-volume
mountPath: /app/config
volumes:
- name: config-volume
emptyDir: {}
- name: config-source
configMap:
name: app-config
1.4 Pod YAML编写
让我们看一个完整的Pod YAML示例。
# complete-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: my-pod
labels:
app: web
environment: production
annotations:
description: "生产环境Web服务器"
spec:
# 重启策略
restartPolicy: Always # Always, OnFailure, Never
# 节点选择
nodeSelector:
disktype: ssd
# 容器定义
containers:
- name: web
image: nginx:1.25
# 端口设置
ports:
- name: http
containerPort: 80
protocol: TCP
# 资源限制
resources:
requests:
memory: "128Mi"
cpu: "250m"
limits:
memory: "256Mi"
cpu: "500m"
# 环境变量
env:
- name: ENV_NAME
value: "production"
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secrets
key: password
# 健康检查
livenessProbe:
httpGet:
path: /healthz
port: 80
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 80
initialDelaySeconds: 5
periodSeconds: 5
# 卷挂载
volumeMounts:
- name: data-volume
mountPath: /data
volumes:
- name: data-volume
persistentVolumeClaim:
claimName: my-pvc
2. 完全理解Deployment
Deployment管理Pod的声明式更新。通过ReplicaSet维护期望数量的Pod,并提供滚动更新和回滚功能。
2.1 Deployment与ReplicaSet的关系
Deployment创建和管理ReplicaSet。ReplicaSet维护指定数量的Pod副本。
- Deployment:高级抽象,管理更新策略
- ReplicaSet:维护Pod副本数量
- Pod:实际运行应用程序
2.2 Deployment YAML编写
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-deployment
labels:
app: web
spec:
# 副本数
replicas: 3
# 选择器(管理哪些Pod)
selector:
matchLabels:
app: web
# 更新策略
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # 可额外创建的Pod数
maxUnavailable: 0 # 不可用Pod的最大数
# Pod模板
template:
metadata:
labels:
app: web
version: v1
spec:
containers:
- name: web
image: nginx:1.25
ports:
- containerPort: 80
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "200m"
memory: "256Mi"
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 10
periodSeconds: 5
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 3
2.3 滚动更新
滚动更新在部署新版本Pod的同时逐步替换旧Pod。
# 更新镜像(触发滚动更新)
kubectl set image deployment/web-deployment web=nginx:1.26
# 检查更新状态
kubectl rollout status deployment/web-deployment
# 检查更新历史
kubectl rollout history deployment/web-deployment
# 查看特定修订版详情
kubectl rollout history deployment/web-deployment --revision=2
2.4 回滚
出现问题时可以轻松回滚到之前的版本。
# 回滚到上一版本
kubectl rollout undo deployment/web-deployment
# 回滚到特定修订版
kubectl rollout undo deployment/web-deployment --to-revision=2
# 回滚后检查状态
kubectl rollout status deployment/web-deployment
3. 扩缩容
Kubernetes支持手动扩缩容和自动扩缩容(HPA)。
3.1 手动扩缩容
# 调整副本数
kubectl scale deployment/web-deployment --replicas=5
# 检查当前状态
kubectl get deployment web-deployment
# 通过YAML修改进行扩缩容
kubectl edit deployment web-deployment
3.2 HPA (Horizontal Pod Autoscaler)
HPA基于CPU、内存使用量或自定义指标自动调整Pod数量。
# hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web-deployment
minReplicas: 2
maxReplicas: 10
metrics:
# 基于CPU的扩缩容
- 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: 10
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 15
- type: Pods
value: 4
periodSeconds: 15
selectPolicy: Max
# 创建HPA(命令方式)
kubectl autoscale deployment web-deployment --min=2 --max=10 --cpu-percent=70
# 检查HPA状态
kubectl get hpa
# HPA详细信息
kubectl describe hpa web-hpa
4. Service类型
Service为Pod集合提供稳定的网络端点。Pod的IP可能会改变,但Service的IP是固定的。
4.1 ClusterIP(默认)
提供只能在集群内部访问的虚拟IP。
# clusterip-service.yaml
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
type: ClusterIP # 默认值,可省略
selector:
app: web
ports:
- name: http
protocol: TCP
port: 80 # 服务端口
targetPort: 80 # Pod端口
使用场景:内部微服务间通信、数据库连接
4.2 NodePort
通过每个节点的特定端口允许外部访问。
# nodeport-service.yaml
apiVersion: v1
kind: Service
metadata:
name: web-nodeport
spec:
type: NodePort
selector:
app: web
ports:
- name: http
protocol: TCP
port: 80 # 服务端口
targetPort: 80 # Pod端口
nodePort: 30080 # 节点端口(30000-32767)
使用场景:开发/测试环境、无负载均衡器时需要外部访问
4.3 LoadBalancer
通过云提供商的负载均衡器获取外部IP。
# loadbalancer-service.yaml
apiVersion: v1
kind: Service
metadata:
name: web-loadbalancer
annotations:
# AWS示例
service.beta.kubernetes.io/aws-load-balancer-type: nlb
spec:
type: LoadBalancer
selector:
app: web
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
- name: https
protocol: TCP
port: 443
targetPort: 443
使用场景:生产环境的外部服务暴露
4.4 ExternalName
为外部服务提供DNS CNAME。
# externalname-service.yaml
apiVersion: v1
kind: Service
metadata:
name: external-db
spec:
type: ExternalName
externalName: db.example.com
使用场景:外部数据库、外部API服务连接
5. 标签和选择器
标签和选择器是组织和连接Kubernetes资源的核心机制。
5.1 标签(Labels)
标签是附加到资源上的键值对。
# 标签示例
metadata:
labels:
app: web
environment: production
version: v1.0.0
team: backend
tier: frontend
# 通过标签查询资源
kubectl get pods -l app=web
kubectl get pods -l 'environment in (production, staging)'
kubectl get pods -l app=web,environment=production
# 添加/修改标签
kubectl label pods my-pod new-label=new-value
# 删除标签
kubectl label pods my-pod new-label-
# 显示所有标签
kubectl get pods --show-labels
5.2 选择器(Selectors)
选择器基于标签选择资源。
# 等式选择器(Equality-based)
selector:
matchLabels:
app: web
environment: production
# 集合选择器(Set-based)
selector:
matchLabels:
app: web
matchExpressions:
- key: environment
operator: In
values:
- production
- staging
- key: version
operator: NotIn
values:
- v1.0.0
- key: team
operator: Exists
6. 实用命令汇总
6.1 Pod相关
# Pod查询
kubectl get pods
kubectl get pods -o wide
kubectl get pods -w # 实时监控
# Pod详细信息
kubectl describe pod my-pod
# 查看Pod日志
kubectl logs my-pod
kubectl logs my-pod -c container-name # 特定容器
kubectl logs my-pod -f # 实时日志
kubectl logs my-pod --previous # 之前容器的日志
# 进入Pod内部
kubectl exec -it my-pod -- /bin/bash
kubectl exec -it my-pod -c container-name -- /bin/sh
# 删除Pod
kubectl delete pod my-pod
kubectl delete pod my-pod --grace-period=0 --force # 强制删除
6.2 Deployment相关
# Deployment管理
kubectl create deployment nginx --image=nginx
kubectl get deployments
kubectl describe deployment my-deployment
# 更新和回滚
kubectl set image deployment/my-deployment container=image:tag
kubectl rollout status deployment/my-deployment
kubectl rollout history deployment/my-deployment
kubectl rollout undo deployment/my-deployment
# 扩缩容
kubectl scale deployment/my-deployment --replicas=5
# 暂停/恢复
kubectl rollout pause deployment/my-deployment
kubectl rollout resume deployment/my-deployment
6.3 Service相关
# Service管理
kubectl expose deployment my-deployment --port=80 --type=ClusterIP
kubectl get services
kubectl describe service my-service
# 查看服务端点
kubectl get endpoints my-service
# 端口转发(本地测试用)
kubectl port-forward service/my-service 8080:80
结论
在本第8篇中,我们深入探讨了Kubernetes的核心资源:Pod、Deployment和Service。Pod是容器组的基本单元,通过Sidecar模式和Init Container可以实现各种模式。Deployment提供Pod的声明式管理和滚动更新、回滚功能,还可以通过HPA实现自动扩缩容。Service为Pod提供稳定的网络访问,根据用途可以选择ClusterIP、NodePort、LoadBalancer等。
利用标签和选择器可以灵活地连接和管理这些资源。在下一篇中,我们将介绍ConfigMap、Secret、Volume等数据和配置管理。