目录
一、Replication Controller 和 ReplicaSet
1. Replication Controller
Replication Controller 的使用示例
2. 标签与标签选择器
标签
标签选择器
标签与标签选择器举例
3. ReplicaSet
定义 ReplicaSet 实例
二、无状态应用管理 Deployment
1. 什么是无状态
2. 无状态服务特点
3. 无状态服务的应用场景
4. 创建 Deployment
5. 更新 Deployment
6. 回滚 deployment
7. 扩容 deployment
8. 删除 Deployment
三、有状态应用管理 StatefulSet
1. 有状态服务的定义
2. 有状态服务的特征
3. 有状态服务的应用场景
4. 无状态服务和有状态服务的比较
5. 编写 statefulSet 资源文件
6. statefulset 扩容
7. 缩容
8. 非级联删除 statefulset
9. 级联删除 statefulset
四、守护进程集 DaemonSet
1. 什么是 DaemonSet
2. 定义一个 DaemonSet
3. 创建 DaemonSet
4. 查看 DaemonSet
5. 查看 pod 所在的节点
6. 删除 DaemonSet
五、CronJob
1. 创建 CronJob
Replication Controller(复制控制器,RC)用于确保 Pod 副本数达到期望值,保障一个或多个同类 Pod 始终可用。若 Pod 数量大于设定值,它会终止额外 Pod;若数量不足,则启动更多 Pod。与手动创建 Pod 不同,由 Replication Controller 维护的 Pod 在失败、删除或终止时会自动替换,因此即便应用只需一个 Pod,也建议用其或其他方式管理。它类似进程管理程序,但监视的是多个节点上的多个 Pod,而非单个节点上的各个进程。
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
kubectl apply -f replicationcontroller-nginx.yaml
kubectl get pod
结果显示创建了 3 个运行状态的 nginx Pod。
kubectl delete pod nginx-9g78r -n default
kubectl get pod
可见新的 Pod 被创建来替换删除的 Pod。
kubectl delete -f replicationcontroller-nginx.yaml
标签是附加在 K8S 对象上的一组键值对,用于方便地筛选或排除一组对象。在同一个对象下,标签的 Key 值必须唯一。标签名不得多于 63 个字符,须由字母或数字开头或结尾,可包含字母、数字、-、_、. 等字符;标签前缀可选,需以 DNS 子域名方式指定。标签值若不为空,长度不得多于 63 个字符,也须由字母或数字开头或结尾,可包含相应字符。
APIServer 支持基于等式和基于集合的两种标签选择器:
基于等式的标签选择器如selector: component: redis
;基于集合的标签选择器如通过matchLabels
和matchExpressions
组合选择。
ReplicaSet(复制集,RS)是支持基于集合的标签选择器的下一代 Replication Controller,主要用于 Deployment 协调创建、删除和更新 Pod,与 Replication Controller 的唯一区别是支持标签选择器。实际应用中,虽可单独使用 ReplicaSet,但一般建议用 Deployment 自动管理,除非自定义 Pod 无需更新或有其他编排需求。
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
kubectl create -f replicaset-example.yaml
无状态服务对单次请求的处理不依赖其他请求,处理一次请求所需信息要么在请求里,要么可从外部获取,服务器本身不存储任何信息。即服务无特殊状态,各请求统一无差别处理,请求携带服务端所需所有参数,服务端不存储与请求相关数据(不包括数据库存储信息)。启动服务时,若不依赖其之前运行状态或其他服务,即为无状态服务,反之则为有状态服务。
Deployment 用来管理 RS,并为 Pod 和 RS 提供声明性更新及许多新功能,生产环境中用 Deployment 替代 RS。它一般用于部署公司的无状态服务,因为企业内部以微服务为主,微服务实现无状态化是最佳实践,可利用其高级功能做到无缝迁移、自动扩容缩容、自动灾难恢复、一键回滚等。
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
kubectl create -f nginx-deployment.yaml
kubectl get deploy
kubectl rollout status deployment/nginx-deployment
kubectl get rs -l app=nginx
kubectl get pods --show-labels
通过 Deployment 部署应用后,若需更新配置文件或镜像版本,更改后会创建新的 RepliccaSet 并对 Pod 进行滚动升级。
kubectl set image deployment nginx-deployment nginx=nginx:1.9.1 --record
kubectl rollout status deployment.v1.apps/nginx-deployment
kubectl get rs
当更新版本不稳定或配置不合理时可回滚。
kubectl set image deployment nginx-deployment nginx=dotbalo/canary:v1 --record
kubectl set image deployment nginx-deployment nginx=dotbalo/canary:v2 --record
kubectl rollout history deployment/nginx-deployment
kubectl rollout history deployment/nginx-deployment --revision=2
kubectl rollout undo deployment/nginx-deployment --to-revision=2
kubectl rollout undo deployment/nginx-deployment
kubectl scale deployment.v1.apps/nginx-deployment --replicas=3
kubectl delete -f nginx-deployment.yaml
StatefulSet(有状态集,缩写为 sts)常用于部署有状态且需要有序启动的应用程序,如生产环境中的 Elasticsearch 集群、MongoDB 集群、RabbitMQ 集群、Redis 集群、Kafka 集群和 ZooKeeper 集群等。它管理着基于相同容器规范的 Pod,与 Deployment 不同的是,为每个 Pod 维护一个标识,这些 Pod 不可互换,每个都有持久标识符,重新调度时会保留。
有状态的 pod 用于运行有状态应用,其在数据卷上存储的数据非常重要,Statefulset 缩容时删除声明可能是灾难性的,缩容简单如减少 replicas 数值,因此释放特定持久卷时需手动删除对应持久卷声明。有状态服务需要在本地存储持久化数据,典型是分布式数据库应用,节点实例间有依赖拓扑关系,如主从关系,停止任一实例 pod 可能导致数据丢失或集群崩溃,也可以说是需要数据存储功能的服务或多线程类型的服务、队列等,还常用于实现事务,如商城购买商品的例子。
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
kubectl create -f redis-statefulset.yaml
kubectl get sts
kubectl get service
kubectl get po -l app=redis-sts
kubectl scale sts redis-sts --replicas=3
kubectl get pods -w -l app=redis-sts
kubectl patch sts redis-sts -p '{"spec":{"replicas":2}}'
kubectl delete statefulset redis-sts --cascade=false
kubectl create -f redis-statefulset.yaml
kubectl delete statefulset redis-sts
当需要在每个 Kubernetes 节点或符合条件的节点上都部署某个应用时,可使用 DaemonSet 调度 Pod。它确保全部(或符合条件)的节点上运行一个 Pod 副本,新节点加入集群时为其新增 Pod,节点移除时回收 Pod,删除 DaemonSet 会删除其创建的所有 Pod。
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: pod-controller
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 -owide
kubectl get pod -n dev -owide
kubectl delete ds pod-controller -n dev
apiVersion: 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
kubectl create -f cronjob-example.yaml
kubectl get cj
kubectl get jobs
kubectl get pod
kubectl logs -f hello-27743522-crnf8
kubectl delete cronjob hello