目录
一:Replication controller 和 Replicaset
1:Replication controller
2:标签与标签选择器
3:ReplicaSet
二:无状态应用管理 Deployment
三:有状态应用管理 statefulset
四:守护进程集 Daemonset
1:什么是 Daemonset
2:定义一个 Daemonset
3:创建 DaemonSet
4:查看 DaemonSet
5:查看 pod 所在的节点
6:删除 DaemonSet
五:CronJob
Replication Controller(复制控制器,RC)
RC 用来确保 Pod 副本数达到期望值,这样可以确保一个或多个同类 Pod 总是可用的。
如果存在的 Pod 数量大于设定的值,Replication Controller 将终止额外的 Pod,如果太少,Replication Controller 将会启动更多的 Pod 用于保证达到期望值。与手动创建 Pod 不同的是,用 Replication Controller 维护的 Pod 在失败、删除或终止时会自动替换。因此,即使应用程序只需要一个 Pod,也应该使用 Replication Controller 或其他方式管理。
Replication Controller 类似于进程管理程序,但是 Replication Controller 不是监视单个节点上的各个进程,而是监视多个节点上的多个 Pod。
Replication Controller 的使用如下列示例。
编辑Replicationcontroller 文件
vim replicationcontroller-nginx.yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: nginx
spec:
replicas: 3
selector:
app: nginx
template:
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
创建Replicationcontroller
kubectl apply -f replicationcontroller-nginx.yaml
kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-9g78r 1/1 Running 0 11m
nginx-bbtqj 1/1 Running 0 11m
nginx-w28bq 1/1 Running 0 11m
kubectl get rc
NAME DESIRED CURRENT READY AGE
nginx 3 3 3 116s
删除一个 pod 并立即查看 pod 状态
kubectl delete pod nginx-9878r -n default
kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-bbtqj 1/1 Running 0 12m
nginx-qqjs4 0/1 ContainerCreating 0 2s
nginx-w28bq 1/1 Running 0 12m
删除Replicationcontroller
kubectl delete -f replicationcontroller-nginx.yaml
类别 | 内容 |
---|---|
标签 | |
定义 | 用于标识Kubernetes对象的一组键值对,便于筛选或管理对象。 |
Key规则 | - 必须唯一 - 不超过63个字符 - 以字母或数字开头和结尾 - 可包含字母、数字、 - 、_ 、. 等字符- 前缀可选,格式为DNS子域名(如 kubernetes.io/ ),用/ 分隔前缀与标签名。 |
Value规则 | - 若不为空,不超过63个字符 - 以字母或数字开头和结尾 - 可包含字母、数字、 - 、_ 、. 等字符。 |
标签选择器 | |
基于等式的选择器 | - 操作符:= 、== (相等)、!= (不等)- 示例: date=day1,name!=build (选择date 为day1 且name 不为build 的对象)。 |
基于集合的选择器 | - 操作符:in 、notin 、exists - 示例: - date in (day1, day2, day3) - name notin (build, pipeline) - test (存在test 标签)- !test (不存在test 标签)。 |
示例对比 | |
基于等式的选择器示例 | yaml |
基于集合的选择器示例 | yaml |
注意事项 | - matchLabels 是{key: value} 的简单映射,等价于matchExpressions 中的{key: key, operator: In, values: [value]} 。- 所有条件需同时满足才能匹配。 |
ReplicaSet(复制集,RS)是支持基于集合的标签选择器的下一代 Replication Controller,它主要用于 Deployment 协调创建、删除和更新 Pod。ReplicaSet 与 Replication Controller 的唯一区别是支持更灵活的标签选择器。
在实际应用中,虽然 ReplicaSet 可以单独使用,但一般建议使用 Deployment 来自动管理 ReplicaSet,除非自定义的 Pod 不需要更新或有其他特殊编排需求。
编辑 Replicaset 文件
# replicaset-example.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: frontend
labels:
app: guestbook
tier: frontend
spec:
replicas: 3
selector:
matchLabels:
tier: frontend
matchExpressions:
- {key: tier, operator: In, values: [frontend]}
template:
metadata:
labels:
app: guestbook
tier: frontend
spec:
containers:
- name: php-redis
image: nginx:1.7.9
resources:
requests:
cpu: 100m
memory: 100Mi
env:
- name: GET_HOSTS_FROM
value: dns
ports:
- containerPort: 80
创建 RS
kubectl create -f replicaset-example.yaml
kubectl get pod
kubectl delete -f replicaset-example.yaml
无状态服务的定义
无状态服务(Stateless Service)是指处理请求时不依赖其他请求或本地存储的状态,所有必要信息都包含在请求中或从外部存储(如数据库)获取。服务器本身不保留任何与请求相关的数据。
无状态服务的特点
数据管理
不在本地存储持久化数据,多个实例共享相同的外部数据源(如数据库或分布式缓存)。
请求处理
同一请求的多个实例返回的响应完全一致。
实例关系
实例之间无依赖关系,动态启停某个Pod不会影响其他Pod。
示例
常见的无状态服务包括Nginx、Tomcat、Web应用等。
Kubernetes 相关资源
ReplicaSet
确保指定数量的Pod副本始终运行。
ReplicationController(旧版)
功能类似ReplicaSet,但逐步被淘汰。
Deployment(推荐)
管理ReplicaSet,提供声明式更新、滚动升级、回滚等高级功能,适合生产环境。
无状态Pod的特性
创建与命名
Pod的创建没有固定顺序,名称随机生成。
重启后Pod的名称和IP会发生变化。
存储
多个Pod共享外部存储(如PVC或分布式文件系统)。
扩缩容
扩容时随机创建Pod,缩容时随机删除Pod(因所有实例无状态差异)。
Deployment 的核心优势
声明式管理
通过YAML定义Pod和ReplicaSet,由Kubernetes自动维护状态。
滚动更新与回滚
支持无缝升级版本,失败时可快速回滚到上一版本。
自动扩缩容
根据负载动态调整Pod数量(结合HPA)。
故障恢复
自动替换异常Pod,确保服务可用性。
无状态服务的应用场景
微服务架构
如Spring Cloud、Dubbo等服务,适合无状态化部署。
静态资源服务
Web前端、API网关等。
实时计算任务
无状态数据处理(如日志分析、实时流计算)。
创建 Deployment
vim nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
name: nginx-deployment
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- name: nginx
containerPort: 80
- app: nginx 使用 label 标记 pod
- spec: 定义 pod 的详细信息
- name: nginx 表示 pod 运行一个名字为 nginx 的容器
- image: 运行此 pod 使用的镜像
- port: 容器用于发送和接收流量的端口
使用 kubectl create 创建此 Deployment
kubectl create -f nginx-deployment.yaml
查看 Deployment 的状态
kubectl get deploy
使用 rollout 查看整个 Deployment 的创建过程状态
kubectl rollout status deployment/nginx-deployment
查看这个 Deployment 对应的 RS
kubectl get rs -1 app=nginx
查看此 Deployment 创建的 pod
kubectl get pods --show-labels
更新 Deployment
(1) 更新pod的image
kubectl set image deployment nginx-deployment nginx=nginx:1.9.1 --record
kubectl set image deployment nginx-deployment nginx=nginx:1.12.0 --record
(2) 查看更新过程
kubectl rollout status deployment.v1.apps/nginx-deployment
(3) 此时的RS有新的和旧的
kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-6cf9b75cdd 0 0 0 3m57s
nginx-deployment-7569c477b6 0 0 0 3m8s
nginx-deployment-96bfc8b67 2 2 2 3m4s
(4) 通过 describe 查看 deployment 的详细信息
kubectl describe deploy nginx-deployment
回滚 deplovment
(1) 多更新几次 deployment
kubectl set image deployment nginx-deployment nginx=dotballo/canary:v1 --record
kubectl set image deployment nginx-deployment nginx=dotballo/canary:v2 --record
(2) 查看更新历史
kubectl rollout history deployment/nginx-deployment
备注:
最后的一个版本是当前版本
(3) 查看某次更新的详情
kubect1 rollout history deployment/nginx-deployment --revision=2
(4) 回滚到指定版本
kubect1 rollout undo deployment/nginx-deployment --to-revision=2
查看回滚结果:
kubect1 rollout history deployment/nginx-deployment
(5) 回滚到上次版本
kubect1 rollout undo deployment/nginx-deployment
查看回滚结果:
kubect1 rollout history deployment/nginx-deployment
扩容 deployment
调整 pod 的副本数
kubectl scale deployment.v1.apps/nginx-deployment --replicas=3
查看扩容结果:
kubectl get pods
删除 Deployment
kubectl delete -f nginx-deployment.yaml
特性 | 无状态服务(Deployment) | 有状态服务(StatefulSet) |
---|---|---|
定义 | 不依赖本地状态,请求可被任意实例处理,数据存储在外部(如DB、Redis)。 | 依赖本地状态,Pod 有唯一标识,数据持久化存储,适用于分布式数据库、消息队列等。 |
适用场景 | Web 服务(Nginx、Tomcat)、无状态微服务、API 网关。 | 数据库(MySQL、MongoDB)、消息队列(Kafka、RabbitMQ)、协调服务(ZooKeeper、ETCD)。 |
Pod 特性 | ||
命名规则 | 随机生成(如 web-1234 ),重启后变化。 |
固定序号(如 mysql-0 、mysql-1 ),名称不变。 |
网络标识 | 动态 IP 和 DNS,重启后可能变化。 | 固定 DNS( ),Pod 重新调度后仍可访问。 |
存储 | 无本地存储,依赖外部存储(如云存储、数据库)。 | 每个 Pod 绑定独立的 PV(持久卷),数据持久化,重启后仍挂载原存储。 |
扩缩容行为 | ||
扩容 | 随机创建新 Pod,无顺序要求。 | 按顺序创建(如先 mysql-0 ,再 mysql-1 )。 |
缩容 | 随机删除 Pod,无数据风险。 | 按逆序删除(先删 mysql-1 ,再 mysql-0 ),需手动清理 PVC 避免数据残留。 |
更新策略 | 支持滚动更新(RollingUpdate),可一键回滚。 | 按顺序更新(先更新从节点,再更新主节点),需确保数据兼容性。 |
典型控制器 | Deployment (管理 ReplicaSet )。 |
StatefulSet (管理有状态 Pod)。 |
高可用与数据一致性 | 无状态,请求可被任意实例处理,适合水平扩展。 | 需考虑数据一致性(如主从同步、选举机制),Pod 故障可能导致数据不一致。 |
运维复杂度 | 简单,适合快速扩缩容和自动化运维。 | 复杂,需管理存储、备份、节点拓扑关系。 |
编写 statefulset 资源文件
(1) 定义一个 statefulset 资源文件
vim redis-statefulset.yaml
apiVersion: v1
kind: Service
metadata:
name: redis-svc
spec:
selector:
app: redis-sts
ports:
- port: 6379
protocol: TCP
targetPort: 6379
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: redis-sts
spec:
serviceName: redis-svc
replicas: 2
selector:
matchLabels:
app: redis-sts
template:
metadata:
labels:
app: redis-sts
spec:
containers:
- image: redis:5-alpine
name: redis
ports:
- containerPort: 6379
备注:
(2) 创建 statefulSet
kubectl create -f redis-statefulset.yaml
(3) 查看 statefilset 状态
kubectl get sts
(4) 查看群集状态
kubectl get service
kubectl get po -1 app=redis-sts
NAME READY STATUS RESTARTS AGE
redis-sts-0 1/1 Running 0 5m38s
redis-sts-1 1/1 Running 0 4m55s
注意 NAME 列,名称是 sts 的 name-序号,这里序号越小则说明创建的越早从 AGE 列也可以看出来,这就解决了有状态应用中的启动顺序问题,比如可以让 redis-sts-0作为redis 的主节点,redis-sts-1作为从节点
statefulset扩容
(1) 扩容,将副本数修改为 3
kubectl scale sts redis-sts --replicas=3
ku get pod
NAME READY STATUS RESTARTS AGE
redis-sts-0 1/1 Running 0 7m50s
redis-sts-1 1/1 Running 0 7m7s
redis-sts-2 1/1 Running 0 6s
缩容
(1) 打开第二个终端,动态显示缩容流程
kubectl get pods -w -l app=redis-sts
备注:
-w: 动态监听所有的 pod
(2) 在原来第一个终端修改副本数为 2
19
kubectl patch sts redis-sts -p '{"spec":{"replicas":2}}'
注意:
此时可以查看第二个终端上的变化
(3)在第一个终端上查看最终结果
kubectl get pods -1 app=redis-sts
非级联删除 statefulset
删除 statefulset 有两种方式:级联删除和非级联删除。
使用非级联方式删除 statefulset 时,statefulset 的 Pod 不会被删除。使用级联方式删除Statefulset 时,statefulset 和它的Pod 都会被删除。
(1)采用非级联删除
kubectl delete statefulset redis-sts --cascade=false
查看删除结果:
kubectl get sts
(2)查看管理的 pod
kubectl get po
发现 pod 并没有被删除
(3)删除 pod
kubectl delete po redis-sts-0
kubectl delete po redis-sts-1
级联删除 statefulset
(1) 先创建出 statefulset
kubectl create -f redis-statefulset.yaml
(2) 级联删除
kubectl delete statefulset redis-sts
查看
kubectl get po
两个 pod 全都没了
(3) 删除 redis 服务
kubectl delete -f redis-statefulset.yaml
有时候我们需要在每个 Kubernetes 节点或符合条件的节点上都部署某个应用,那么就可以使用Kubernetes 的 Daemonset 调度 Pod。Daemonset 确保全部(或符合条件)的节点上运行一个 Pod 副本当有新的节点加入集群时,也会为他们新增一个 Pod,当节点从集群中移除时,这些 Pod 会被回收,删除Daemonset 将会删除它创建的所有的 Pod。
cat daemonset-nginx.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: pod-controlled
namespace: dev
labels:
controller: daemonset
spec:
selector:
matchLabels:
app: nginx-pod
template:
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
kubectl create namespace dev
kubectl create -f daemonset-nginx.yaml
kubectl get ds -n dev -o wide
NAME DESTRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE CONTAINERS IMAGES SELECTOR
pod-controller 3 3 3 3 3 3m8s nginx nginx:latest app=nginx-pod
kubectl get pod -n dev -o wide
kubectl delete ds pod-controller -n dev
Cronjob(计划任务,缩写为 cj)用于以时间为基准的周期性地执行任务,这些自动化任务和运行在 Linux 系统上的 cronJob 一样。
创建 CronJob
(1)编辑 Cronjob 文件
cat cronjob-example.yaml
apiVersion: batch/v1 #1.21 版本以上 改为 batch/v1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * * "
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox:v1
args:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailure
备注:
这个案例会在每分钟执行一次计划任务,
并输出当前时间和“Hello from the Kubernetes cluster
(2) 创建 Cronjob
kubectl create -f cronjob-example.yaml
(3) 查看创建结果
kubectl get cj
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
hello */1 * * * False 0 485 945
等待一会后可以查看生成的 pod
kubectl get jobs
NAME COMPLETIONS DURATION AGE
hello-27743514 1/1 20s 74s
hello-27743515 0/1 14s 14s
(4) 查看生成的 pod,并查看 pod 的执行日志
kubect1 get pod
kubect1 logs -f hello-27743522-crnf8
Sat Oct 1 08:02:16 UTC 2022
Hello from the Kubernetes cluster
(5) 删除 Cronjob
kubect1 delete cronjob hello