前言
官方解释:工作负载就是运行在Kubernetes上的应用程序。
而我们的程序,也就是工作负载可以由单个组件构成,也可以由多个组件同时构成。
最小单位——Pod
Docker的操作单位是container,而Kubernetes的操作单位是Pod。从前一节容器的介绍中,我们知道容器实际上是一个进程,那么Pod是什么呢?“Pod (就像在鲸鱼荚或者豌豆荚中)是一组(一个或多个) 容器; 这些容器共享存储、网络、以及怎样运行这些容器的声明。 Pod 中的内容总是并置(colocated)的并且一同调度,在共享的上下文中运行。”——这是官网上的解释,因此我们知道了,Pod实际上是1个或者1组容器的集合。且Pod中的容器其生命周期是一致(即被Kubernetes同时调度)。
在通常情况下,每一个Pod中都应该只有1个业务容器,除非多个容器之间具有强依赖关系。
Pod的结构如下
同一个Pod中的container共享IPC,UTS,Network,因此它们之间可以自由相互通信。
资源
在Kubernetes中我们可以看到很多的概念,我们均可以称之为资源(resource),可以通过kubectl api-resources查看,如下
第1列,表示resource名称
第2列,表示该resource的简写
第3列,表示该resource所处的API Group
第4列,表示该resource的使用范围是否限制在namespace中
第5列,表示该resource的类别
Pod也可以算是资源的一部分,但是实际使用中,我们往往不会直接去创建或者升级某个Pod,而是使用处于Pod之上,更高级的控制器来操作Pod。
以下讲解一下常用的控制器
Deployment
简写deploy,官方也建议使用。
当我们创建1个deployment的时候,Kubernetes会自动的创建1个rs去控制Pod,而deployment只控制rs。Deployment相对于rs和rc来讲,可以提供更强大的操作功能,比如滚动升级,状态回滚等。
下面来看一个deploy的示例,如下
[root@a file-yaml]$ cat busybox-httpd-deploy-v1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
## 定义该deployment的label
labels:
app: busybox-httpd
version: v1
name: busybox-httpd-v1
spec:
replicas: 1
## 定义该deployment所选择的pod label
selector:
matchLabels:
app: busybox-httpd
version: v1
template:
metadata:
## 定义该Pod的label
labels:
app: busybox-httpd
version: v1
spec:
containers:
## 定义pod中image
- image: registry.cn-xxx.aliyuncs.com/xxx/busyboxhttpd:v1
## 定义image的pull策略
imagePullPolicy: Always
## 定义container的名字
name: busybox-httpd
## 定义container暴露的端口
ports:
- name: v1
containerPort: 80
使用kubectl apply -f busybox-httpd-deploy-v1.yaml之后,就可以看到出现了3个resource,如下
如此,充分说明,deploy管理rs,而rs再操作pod。而且,也可以看到deploy,rs以及pod的label都包含我们定义的,除此之外,kubernetes还自动填写了1个hash的label。
StatefulSet
简写sts,使用deployment生成的pod都是无状态的,它们管理的pod的名字,IP,启停顺序都是随机,但是如果需要在Kubernetes部署一套zookeeper呢,那怎么办?我们可以使用statefulset来创建有状态的pod,使用statefulset所创建的pod,它们的ip都是固定的(即Pod在被删除后重新生成时,ip固定),名字也是有序的,
使用1个statefulset的yaml进行创建, statefuleset的yaml文件中必须要有serviceName字段,否则报错
如下
可以看到pod的创建是依次从0号开始的,然后知道我们所需要的replica数
随机杀死1个pod后,statefulset生成的pod仍然是之前的ip,如下
我们杀死1个由deploy生成的pod,然后对比下生成的pod的ip,如下
可以看到,由statefulset产生的pod的ip在生命周期内是固定不变的,而由deploy产生的pod的ip则是随机分配的,pod杀死后,新pod的ip是全新的。
DaemonSet
简写ds,生产环境中,除了有状态的pod和无状态的pod之外,往往有些工作只能在本机进行,比如收集宿主机监控信息的agent这种,就必须固定运行某个节点上,那么对于这种情况,我们可以使用daemonset来应对。
由daemonset创建的pod会确保每个node节点上都有1个pod( 当然了,可以通过taint,node selector,Affinity,Toleration来限制ds的范围 ),当node移除集群后,该节点上的pod自动消亡。
我们创建1个ds来做验证, daemonset中定义的restartpolicy必须为always ,如下
[root@a test]$ cat busybox-httpd-ds-v1.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
labels:
app: busybox-httpd
name: busybox-httpd
spec:
selector:
matchLabels:
app: busybox-httpd
template:
metadata:
labels:
app: busybox-httpd
spec:
containers:
- image: registry.cn-xx.aliyuncs.com/xx/busyboxhttpd:v1
imagePullPolicy: Always
name: busybox-httpd
ports:
- name: v1
containerPort: 80
imagePullSecrets:
- name: regcred-test
使用kubectl apply -f创建该ds后,使用kubectl get po -o wide可以看到ds所产生的pod会在每个node节点上都会出现1个( 因为本次测试kubernetes集群只有1个节点,所以只会显示1个 )
Job和Cronjob
简写job,除了ds,sts,deploy常用之外,还有1个比较特别的,就是job。见名知义,此类控制器产生的pod是为了完成任务的,类似linux中的job和cronjob一样。
job
先来看一个job的yaml如下
[root@a test]$ cat busybox-job.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: busybox-pi
spec:
template:
spec:
containers:
- image: registry.cn-xx.aliyuncs.com/xxx/busyboxhttpd:v1
name: busybox-pi
## 下面的command表示,计算pi的值,并且计算到小数点后1000位
command: ["sh", "-c", "echo 'scale=1000; 4*a(1)' | bc -l "]
## 该job运行失败后,永远不会重新创建pod,避免了某些情况下job无法完成的
## 时候,就疯狂创建pod,导致node节点上资源枯竭
restartPolicy: Never
imagePullSecrets:
- name: regcred-test
使用kubectl apply -f创建后,可以看到该job的创建过程
使用kubectl logs可以查看该job的输出日志
如上,确实看到了busybox镜像计算到了pi的第1000位,然后就结束了该pod的生命周期。
cronjob
再来看一下cronjob的
cronjob的定时任务写法和linux中的cronjob其实一样
其yaml文件如下
[root@a test]$ cat busybox-cronjob.yaml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: busybox-hello
spec:
## 每1分钟运行1次
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- image: registry.cn-xx.aliyuncs.com/xx/busyboxhttpd:v1
name: busybox-hello
command: ["sh", "-c", "echo hello"]
restartPolicy: Never
imagePullSecrets:
- name: regcred-test
使用kubectl apply -f只有,可以看到成功创建了job,且打印出了hello字段,如下
ReplicaSet
简写rs,是新一代的副本控制器,旧一代的副本控制器称之为ReplicaController(简写rc),相对于rc而严,rs所能支持的selector更复杂。
特殊Pod——StaticPod
在Kubernetes中,基本上所有的pod都会被各种控制器所管理,但是有1种pod不会被控制器管理,那就是static pod,这种pod由kubelet直接管理,且不会与api server通信,生命周期与kubernetes无关。
- 需要在kubelet的config文件中配置staticPodPath字段
- 在staticPodPath配置的目录下写入pod的yaml文件,如下
[root@a kubernetes]$ cat /etc/kubernetes/nginx-staticpod.yaml
apiVersion: v1
kind: Pod
metadata:
name: static-web
labels:
role: myrole
spec:
containers:
- name: web
image: nginx
ports:
- name: web
containerPort: 80
protocol: TCP
- 重启kubelet,查看pod
可以看到,虽然可以使用kubectl命令来删除该pod,但是该pod会自动重启,即便是使用docker rm删除也会被自动重启
参考文档 Kubernetes官方文档