前言
在 K8s 集群中,Pod 控制器是一种关键的组件,负责管理和控制Pod的生命周期。Pod 是 K8s 中最小的可部署单元,通常包含一个或多个容器,Pod 控制器则确保所需数量的 Pod 实例处于运行状态,并根据定义的规则进行自动扩展或缩减。本文将介绍 K8s 集群中 Pod 控制器的定义、类型以及 Pod 与控制器之间的关系。
目录
[一、Pod 控制器介绍](#一、Pod 控制器介绍)
[1. 概述及作用](#1. 概述及作用)
[2. pod 控制器的类型](#2. pod 控制器的类型)
[2.1 ReplicaSet](#2.1 ReplicaSet)
[2.2 Deployment](#2.2 Deployment)
[2.3 DaemonSet](#2.3 DaemonSet)
[2.4 StatefulSet](#2.4 StatefulSet)
[2.5 Jop](#2.5 Jop)
[2.6 CronJob](#2.6 CronJob)
[3. Pod 与控制器之间的关系](#3. Pod 与控制器之间的关系)
[二、控制器管理 Pod 示例](#二、控制器管理 Pod 示例)
[1. Deployment 部署无状态应用](#1. Deployment 部署无状态应用)
[2. SatefulSet 部署有状态应用](#2. SatefulSet 部署有状态应用)
[2.1 SatefulSet 三个组件](#2.1 SatefulSet 三个组件)
[2.2 实现 K8S 里 DNS 功能的插件](#2.2 实现 K8S 里 DNS 功能的插件)
[2.3 解析 kubernetes 和 nginx-service 名称](#2.3 解析 kubernetes 和 nginx-service 名称)
[2.4 查看 statefulset 的定义](#2.4 查看 statefulset 的定义)
[2.5 清单定义 StatefulSet](#2.5 清单定义 StatefulSet)
[2.5.1 定义资源清单](#2.5.1 定义资源清单)
[2.5.2 创建 statefulset](#2.5.2 创建 statefulset)
[2.5.3 删除 statefulset](#2.5.3 删除 statefulset)
[2.6 滚动更新](#2.6 滚动更新)
[3. DaemonSet 一次创建多节点](#3. DaemonSet 一次创建多节点)
一、Pod 控制器介绍
1. 概述及作用
概述:
Pod 控制器是一种 K8s 对象,设计用于管理和维护 Pod 实例。它们不是直接操作 Pod,而是通过与 K8s API 交互来间接控制 Pod,从而保证即使面对节点故障、Pod 终止或其他意外情况,也能维持应用的高可用性和期望的部署配置。
作用:
自动扩缩容
- 根据预设策略自动增加或减少Pod副本的数量,以应对负载变化或确保服务的高可用性。
自我修复
- 当检测到Pod由于各种原因(如节点故障、容器崩溃)不再运行时,控制器会自动创建新的Pod副本以替换故障实例,保持预期的Pod数量和配置。
滚动更新
- 在不中断服务的情况下,逐步将Pod升级到新版本的应用镜像,通过逐步替换旧Pod来平滑过渡。
版本控制
- 管理应用的多个版本,允许快速回滚到之前的版本。
有序部署和管理
- 对于有状态应用,如数据库,使用StatefulSet控制器来确保Pod按顺序创建和销毁,维护稳定的网络标识符和存储卷。
定时任务
- CronJob控制器能够根据预定的计划时间自动创建Job来执行一次性任务,适用于定期执行的任务,如数据备份、报表生成等。
资源组织和命名空间管理
- 帮助组织和隔离不同的应用或服务资源,便于团队协作和资源分配。
2. pod 控制器的类型
常见的 Pod 控制器类型包括 ReplicaSet、Deployment、DaemonSet、StatefulSet、Job 和 CronJob 等。
2.1 ReplicaSet
确保在任何给定时间都有指定数量的 Pod 副本在运行,确保 Pod 副本数量符合期望值,并且支持滚动式自动扩容和缩容功能。主要三个组件组成:
- 用户期望的 pod 副本数量
- 标签选择器,判断哪个 pod 归自己管理
- 当现存的 pod 数量不足,会根据 pod 资源模板进行新建
2.2 Deployment
它建立在 ReplicaSet 之上,提供了额外的功能,如滚动更新、暂停/恢复更新、版本回滚等。
2.3 DaemonSet
确保每个节点上都运行着一个指定的 Pod 实例,比如日志收集、监控代理等。当有新的节点加入集群时,DaemonSet 会自动在新节点上创建 Pod;节点从集群移除时,对应的 Pod 也会被清理。
2.4 StatefulSet
管理有状态应用设计,如数据库、需要持久化存储和稳定的网络标识(如: CEPH)。StatefulSet 中的每个 Pod 都有唯一的、持久的标识符和稳定的存储卷。它确保 Pod 按顺序启动和关闭(理论上是倒序),且在重启后仍能访问相同的存储资源,这对于维护数据一致性至关重要。
2.5 Jop
用于运行完成特定次数后终止的 Pod,即执行一次性或批处理任务。只要完成就立即退出,不需要重启或重建。
2.6 CronJob
周期性任务控制,基于时间调度来定期执行 Job,类似于Linux的cron定时任务,不需要持续后台运行。
3. Pod 与控制器之间的关系
Controllers (控制器)是管理和运行容器的 Pod 对象的实体,在集群中,Pod 通过 Label Selector (标签与选择器)进行相关联。它们通过控制器来实现应用的运维任务,例如伸缩和升级。
可以理解为:Pod 与控制器之间是一种管理和被管理的关系,控制器利用 K8s 的标签系统来识别和控制其管理的 Pod 集合,从而实现了应用的自动化运维和高可用性。
二、控制器管理 Pod 示例
1. Deployment 部署无状态应用
部署并维护一个由3个副本组成的 Nginx 服务,管理 Pod 和 ReplicaSet;应用场景:web服务。
① 定义 yaml 配置
bash
[root@master01 controller]# vim nginx-deployment.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.14
ports:
- containerPort: 80
② 创建控制器
bash
[root@master01 controller]# kubectl apply -f nginx-deployment.yaml
③ 获取集群中Pods、Deployments、以及 ReplicaSets 的信息
bash
[root@master01 controller]# kubectl get pod,deploy,rs
NAME READY STATUS RESTARTS AGE
pod/nfs-client-provisioner-5f7484cd44-ls45v 1/1 Running 0 14h
pod/nginx-deployment-d9d8cf5c7-j2c8p 1/1 Running 0 50s
pod/nginx-deployment-d9d8cf5c7-mf578 1/1 Running 0 50s
pod/nginx-deployment-d9d8cf5c7-xqh57 1/1 Running 0 50s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx-deployment 3/3 3 3 50s
# READY: 表示期望的Pod副本中有多少是Ready状态。3/3意味着所有3个副本都已准备就绪,可以接收请求。
# UP-TO-DATE: 表示已经更新到最新配置的Pod副本数量,这里也是3,说明没有正在进行的更新操作或所有Pod都已经是最新配置。
# AVAILABLE: 表示当前可用的Pod副本数量,同样为3,说明服务完全可用。
# AGE: 显示了Deployment被创建的时间,这里是50秒。
NAME DESIRED CURRENT READY AGE
replicaset.apps/nginx-deployment-d9d8cf5c7 3 3 3 50s
# DESIRED: 表示ReplicaSet期望维持的Pod副本数量,这里是3。
# CURRENT: 实际存在的Pod副本数量,也是3,符合期望。
# READY: 准备好提供服务的Pod副本数量,3个副本都已就绪。
④ 查看控制器配置
bash
kubectl edit deployment/nginx-deployment
labels:
app: nginx # Deployment资源的标签
replicas: 3 #期望的pod数量,默认是1
rollingUpdate:
maxSurge: 25% # 升级过程中会先启动的新Pod的数量不超过期望的Pod数量的25%,也可以是一个绝对值
maxUnavailable: 25% # 升级过程中在新的Pod启动好后销毁的旧Pod的数量不超过期望的Pod数量的25%,也可以是一个绝对值
type: RollingUpdate # 滚动升级
spec:
template:
labels:
app: nginx # Pod副本关联的标签
spec:
containers:
- image: nginx:1.14 #镜像名称
imagePullPolicy: IfNotPresent #镜像拉取策略
ports:
- containerPort: 80 #容器暴露的监听端口
restartPolicy: Always #容器重启策略
⑤ 查看历史版本
bash
[root@master01 controller]# kubectl rollout history deployment nginx-deployment
deployment.apps/nginx-deployment
REVISION CHANGE-CAUSE
1 <none>
小结:
deployment 部署无状态应用的管理 ReplicaSet 和 Pod 并创建 Pod,主要维护 Pod 副本数量与期望值相同;创建和删除 Pod 时,并行执行,升级时也会创建一部分再删除一部分。
2. SatefulSet 部署有状态应用
- 稳定的持久化存储,即 Pod 重新调度后还是能访问到相同的持久化数据,基于 PVC 来实现;
- 稳定的网络标志,即 Pod 重新调度后其 PodName 和 HostName 不变,基于 Headless Service(即无头模式,利用 DNS 来解析 Service,没有Cluster IP的Service)来实现;
- 有序部署,有序扩展,即 Pod 是有顺序的,在部署或者扩展的时候要依据定义的顺序依次进行(即从0到N-1,在下一个 Pod 运行之前所有之前的 Pod 必须都是 Running 和 Ready 状态),基于 init containers 来实现;
- 有序收缩,有序删除(即从N-1到0)。
常见的应用场景:数据库StatefulSets | Kubernetes
2.1 SatefulSet 三个组件
- Headless Service(无头服务):用于为Pod资源标识符生成可解析的DNS记录。
- volumeClaimTemplates(存储卷申请模板):基于静态或动态PV供给方式为Pod资源提供专有的固定存储。
- StatefulSet:用于管控Pod资源。
(1)为什么要有headless?
- 在deployment中,每一个pod是没有名称,是随机字符串,是无序的;
- 而statefulset中是要求有序的,每一个pod的名称必须是固定的;
当节点挂了,重建之后的标识符是不变的,每一个节点的节点名称是不能改变的。pod名称是作为pod识别的唯一标识符,必须保证其标识符的稳定并且唯一。
为了实现标识符的稳定,这时候就需要一个headless service 解析直达到pod,还需要给pod配置一个唯一的名称。
(2)为什么要有volumeClainTemplate?
大部分有状态副本集都会用到持久存储,比如分布式系统来说,由于数据是不一样的,每个节点都需要自己专用的存储节点;
- 在 deployment中pod模板中创建的存储卷是一个共享的存储卷,多个pod使用同一个存储卷;
- 而statefulset定义中的每一个pod都不能使用同一个存储卷,由此基于pod模板创建pod是不适应的,这就需要引入volumeClainTemplate,当在使用statefulset创建pod时,会自动生成一个PVC,从而请求绑定一个PV,从而有自己专用的存储卷。
2.2 实现 K8S 里 DNS 功能的插件
skyDNS:Kubernetes 1.3之前的版本
kubeDNS:Kubernetes 1.3至Kubernetes 1.11
CoreDNS:Kubernetes 1.11开始至今
2.3 解析 kubernetes 和 nginx-service 名称
创建一个service,然后用dns去测试解析。
① 定义 nginx-svc yaml
bash
[root@master01 controller]# vim nginx-service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-service
labels:
app: nginx
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
selector:
app: nginx
② 创建 nginx-svc
bash
[root@master01 controller]# kubectl apply -f nginx-service.yaml
service/nginx-service created
[root@master01 controller]# kubectl get svc
nginx-service NodePort 10.96.193.207 <none> 80:32037/TCP 7s
③ 定义一个dns-pod yaml
bash
[root@master01 controller]# vim dns-test.yaml
apiVersion: v1
kind: Pod
metadata:
name: dns-test
spec:
containers:
- name: busybox
image: busybox:1.28.4 #一个小型的Unix工具集合,常用于测试和基础任务
args:
- /bin/sh
- -c
- sleep 36000 #让容器运行后休眠36000秒
restartPolicy: Never #指定了Pod的重启策略
④ 创建 pod
bash
[root@master01 controller]# kubectl apply -f dns-test.yaml
[root@master01 controller]# kubectl get pod
NAME READY STATUS RESTARTS AGE
dns-test 1/1 Running 0 48s
⑤ 进入容器测试解析
bash
[root@master01 controller]# kubectl exec -it dns-test sh
/ # nslookup kubernetes
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: kubernetes
Address 1: 10.96.0.1 kubernetes.default.svc.cluster.local
/ # nslookup nginx-service
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: nginx-service
Address 1: 10.96.193.207 nginx-service.default.svc.cluster.local
2.4 查看 statefulset 的定义
bash
kubectl explain statefulset
kubectl explain statefulset.spec
FIELDS:
podManagementPolicy <string> #Pod管理策略
replicas <integer> #副本数量
revisionHistoryLimit <integer> #历史版本限制
selector <Object> -required- #选择器,必选项
serviceName <string> -required- #服务名称,必选项
template <Object> -required- #模板,必选项
updateStrategy <Object> #更新策略
volumeClaimTemplates <[]Object> #存储卷申请模板,必选项
2.5 清单定义 StatefulSet
如上所述,一个完整的 StatefulSet 控制器由一个 Headless Service、一个 StatefulSet 和一个 volumeClaimTemplate 组成。定义了一个Kubernetes StatefulSet资源和一个Headless Service(无头服务),用于部署一个有状态应用:
2.5.1 定义资源清单
bash
[root@master01 controller]# vim stateful-demo.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp-svc
labels:
app: myapp-svc
spec:
ports:
- port: 80
name: web
clusterIP: None #None表明这是一个无头服务,没有Cluster IP分配,直接返回关联Pod的IP列表
selector:
app: myapp-pod #用于选择带有此标签的Pods,与后续的StatefulSet关联
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: myapp
spec:
serviceName: myapp-svc
replicas: 3
selector:
matchLabels: #为Pod定义标签,与selector匹配
app: myapp-pod
template:
metadata:
labels:
app: myapp-pod
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
ports:
- containerPort: 80
name: web
volumeMounts:
- name: myappdata
mountPath: /usr/share/nginx/html #挂载卷myappdata到/usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: myappdata
annotations:
#动态PV创建时,使用annotations在PVC里声明一个StorageClass对象的标识进行关联
volume.beta.kubernetes.io/storage-class: nfs-client-storageclass
spec:
accessModes: ["ReadWriteOnce"] #定义访问模式
resources:
requests:
storage: 2Gi
由于 StatefulSet 资源依赖于一个实现存在的 Headless 类型的 Service 资源,所以需要先定义一个名为 myapp-svc 的 Headless Service 资源,用于为关联到每个 Pod 资源创建 DNS 资源记录。接着定义了一个名为 myapp 的 StatefulSet 资源,它通过 Pod 模板创建了 3 个 Pod 资源副本,并基于 volumeClaimTemplates 向前面创建的PV进行了请求大小为 2Gi 的专用存储卷。
2.5.2 创建 statefulset
bash
[root@master01 controller]# kubectl apply -f stateful-demo.yaml
查看创建的无头服务myapp-svc:
[root@master01 controller]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 14d
myapp-svc ClusterIP None <none> 80/TCP 32m
查看statefulset:
[root@master01 controller]# kubectl get sts
NAME READY AGE
myapp 3/3 24m
查看pvc绑定:
[root@master01 controller]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
myappdata-myapp-0 Bound pvc-d9b33a5b-076e-4a17-b457-03d7b50d08b7 2Gi RWO nfs-client-storageclass 25m
myappdata-myapp-1 Bound pvc-4748da6b-1c81-45c0-9b50-a20898cc5f11 2Gi RWO nfs-client-storageclass 5m51s
myappdata-myapp-2 Bound pvc-a4999f31-ab02-4640-913e-c6cf19ccf7a0 2Gi RWO nfs-client-storageclass 5m46s
查看pv绑定:
[root@master01 controller]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-4748da6b-1c81-45c0-9b50-a20898cc5f11 2Gi RWO Delete Bound default/myappdata-myapp-1 nfs-client-storageclass 8m14s
pvc-a4999f31-ab02-4640-913e-c6cf19ccf7a0 2Gi RWO Delete Bound default/myappdata-myapp-2 nfs-client-storageclass 8m9s
pvc-d9b33a5b-076e-4a17-b457-03d7b50d08b7 2Gi RWO Delete Bound default/myappdata-myapp-0 nfs-client-storageclass 8m26s
查看Pod信息:
[root@master01 controller]# kubectl get pods
NAME READY STATUS RESTARTS AGE
myapp-0 1/1 Running 0 27m
myapp-1 1/1 Running 0 8m39s
myapp-2 1/1 Running 0 8m34s
2.5.3 删除 statefulset
当删除的时候是从myapp-2开始进行删除的,关闭是逆向关闭(不过一般是同时删除);然后再次创建,观察 pod 创建详情:
bash
[root@master01 volumes]# kubectl get pod -w
NAME READY STATUS RESTARTS AGE
myapp-0 1/1 Running 0 32m
myapp-1 1/1 Running 0 12m
myapp-2 1/1 Running 0 12m
nfs-client-provisioner-5f7484cd44-ft5lv 1/1 Running 0 13m
myapp-1 1/1 Terminating 0 14m
myapp-2 1/1 Terminating 0 14m
myapp-0 1/1 Terminating 0 34m
myapp-1 0/1 Terminating 0 14m
myapp-2 0/1 Terminating 0 14m
myapp-0 0/1 Terminating 0 34m
myapp-1 0/1 Terminating 0 14m
myapp-1 0/1 Terminating 0 14m
myapp-2 0/1 Terminating 0 14m
myapp-2 0/1 Terminating 0 14m
myapp-0 0/1 Terminating 0 34m
myapp-0 0/1 Terminating 0 34m
myapp-0 0/1 Pending 0 0s
myapp-0 0/1 Pending 0 0s
myapp-0 0/1 ContainerCreating 0 0s
myapp-0 1/1 Running 0 2s
myapp-1 0/1 Pending 0 0s
myapp-1 0/1 Pending 0 0s
myapp-1 0/1 ContainerCreating 0 0s
myapp-1 1/1 Running 0 2s
myapp-2 0/1 Pending 0 0s
myapp-2 0/1 Pending 0 0s
myapp-2 0/1 ContainerCreating 0 0s
myapp-2 1/1 Running 0 2s
此时PVC依旧存在的,再重新创建pod时,依旧会重新去绑定原来的pvc:
bash
[root@master01 controller]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
myappdata-myapp-0 Bound pvc-d9b33a5b-076e-4a17-b457-03d7b50d08b7 2Gi RWO nfs-client-storageclass 36m
myappdata-myapp-1 Bound pvc-4748da6b-1c81-45c0-9b50-a20898cc5f11 2Gi RWO nfs-client-storageclass 17m
myappdata-myapp-2 Bound pvc-a4999f31-ab02-4640-913e-c6cf19ccf7a0 2Gi RWO nfs-client-storageclass 17m
2.6 滚动更新
StatefulSet 控制器将在 StatefulSet 中删除并重新创建每个 Pod。它将以与 Pod 终止相同的顺序进行(从最大的序数到最小的序数),每次更新一个 Pod。在更新其前身之前,它将等待正在更新的 Pod 状态变成正在运行并就绪。如下操作的滚动更新是按照2-0的顺序更新。
① 修改 yaml 定义
bash
[root@master01 controller]# vim stateful-demo.yaml
......
image: nginx:1.18.0 # 原来是1.14
......
② 更新 svc yaml
bash
[root@master01 controller]# kubectl apply -f stateful-demo.yaml
③ 查看滚动更新的过程
bash
[root@master01 volumes]# kubectl get pod -w
NAME READY STATUS RESTARTS AGE
myapp-0 1/1 Running 0 12s
myapp-1 1/1 Running 0 9s
myapp-2 1/1 Running 0 7s
nfs-client-provisioner-5f7484cd44-ft5lv 1/1 Running 0 29m
myapp-2 1/1 Terminating 0 51s
myapp-2 0/1 Terminating 0 52s
myapp-2 0/1 Terminating 0 53s
myapp-2 0/1 Terminating 0 53s
myapp-2 0/1 Pending 0 0s
myapp-2 0/1 Pending 0 0s
myapp-2 0/1 ContainerCreating 0 0s
myapp-2 1/1 Running 0 2s
myapp-1 1/1 Terminating 0 57s
myapp-1 0/1 Terminating 0 58s
myapp-1 0/1 Terminating 0 59s
myapp-1 0/1 Terminating 0 59s
myapp-1 0/1 Pending 0 0s
myapp-1 0/1 Pending 0 0s
myapp-1 0/1 ContainerCreating 0 0s
myapp-1 1/1 Running 0 2s
myapp-0 1/1 Terminating 0 64s
myapp-0 0/1 Terminating 0 65s
myapp-0 0/1 Terminating 0 66s
myapp-0 0/1 Terminating 0 66s
myapp-0 0/1 Pending 0 0s
myapp-0 0/1 Pending 0 0s
myapp-0 0/1 ContainerCreating 0 0s
myapp-0 1/1 Running 0 2s
④ 进入 dns-test Pod中,每一个 pod 自己的名称都是可以被解析的
bash
[root@master01 controller]# kubectl exec -it dns-test sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # nslookup myapp-svc
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: myapp-svc
Address 1: 10.244.2.40 myapp-0.myapp-svc.default.svc.cluster.local
Address 2: 10.244.2.39 myapp-1.myapp-svc.default.svc.cluster.local
Address 3: 10.244.1.201 myapp-2.myapp-svc.default.svc.cluster.local
/ # nslookup myapp-0.myapp-svc.default.svc.cluster.local
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: myapp-0.myapp-svc.default.svc.cluster.local
Address 1: 10.244.2.40 myapp-0.myapp-svc.default.svc.cluster.local
/ # nslookup myapp-1.myapp-svc.default.svc.cluster.local
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: myapp-1.myapp-svc.default.svc.cluster.local
Address 1: 10.244.2.39 myapp-1.myapp-svc.default.svc.cluster.local
/ # nslookup myapp-2.myapp-svc.default.svc.cluster.local
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
3. DaemonSet 一次创建多节点
DaemonSet 确保全部(或者一些)Node 上运行一个 Pod 的副本。当有 Node 加入集群时,也会为他们新增一个 Pod 。当有 Node 从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。
使用 DaemonSet 的一些典型用法:
- 运行集群存储 daemon,例如在每个 Node 上运行 glusterd、ceph。
- 在每个 Node 上运行日志收集 daemon,例如fluentd、logstash。
- 在每个 Node 上运行监控 daemon,例如 Prometheus Node Exporter、collectd、Datadog 代理、New Relic 代理,或 Ganglia gmond。
应用场景:Agent
官方案例(监控):https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/
示例:
bash
[root@master01 data]# vim ds.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: nginx-daemonset
labels:
app: nginx
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14
ports:
- containerPort: 80
[root@master01 data]# kubectl apply -f ds.yaml
DaemonSet会在每个node节点都创建一个Pod:
[root@master01 data]# kubectl get pod -o wide
nginx-daemonset-bqmtg 1/1 Running 0 15s 10.244.1.202 node01 <none> <none>
nginx-daemonset-n89xc 1/1 Running 0 15s 10.244.2.42 node02 <none> <none>
三、总结
1. Pod 控制器
① deployment 部署无状态应用的管理 RS 和 pod 创建 Pod ,主要是维护 pod 副本数量与期望状态相同;创建和删除 pod 时并行执行升级时是想创建一部分,再删除一部分;
② statefulset 部署有状态的应用,每个 pod 名称唯一且不变,每个 pod 拥有自己专属的持久化的存储(PVC 和 PV)在 k8s 集群内部可以通过{pod_name}.{service_name}.{namespace).svc.cluster.local 解析出 pod 的 IP(基于 headless service 和 coreDNS)创建和删除 pod 是有顺序的(串行执行的),升级时串行执行的,会删除旧的 pod,再创建新 pod;删除和升级是逆序执行的(先从标识符最大的 n-1开始,一直到最小的0);
③ Daemonset 理论上在 k8s 集群的所有 node 节点上创建相同的 pod(无论 node 节点什么时候加入到 k8s 集群),但是会收到 node 节点上污点影响;
④ 部署一次性任务的 pod,正常完成后容器立即退出并且不重启容器(restartpolicy 不设置Always),也不会重建,异常完成后重试任务,重建次数根据 backofflimit 配置指定(默认为6次);
⑤ cronjob 周期性的部署任务的 pod,正常完成后容器会立即退出并不会重启容器(restartPolicy 不设置 Always),也不会重键 pod schedule 配置周期的性的事件表(*****分时日月周)。
bash
无状态:
1)deployment 认为所有的pod都是一样的
2)不用考虑顺序的要求
3)不用考虑在哪个node节点上运行
4)可以随意扩容和缩容
有状态
1)实例之间有差别,每个实例都有自己的独特性,元数据不同,例如etcd,zookeeper
2)实例之间不对等的关系,以及依靠外部存储的应用。
常规service和无头服务区别
service:一组Pod访问策略,提供cluster-IP群集之间通讯,还提供负载均衡和服务发现。
Headless service:无头服务,不需要cluster-IP,而是直接以DNS记录的方式解析出被代理Pod的IP地址。