大佬教程收集整理的这篇文章主要介绍了linux12k8s --> 06Pod详解,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
每个Pod中都可以包含一个或者多个容器c;这些容器可以分为两类:
# 主容器 pause
# 业务容器 user container1 user container2
这里是Pod内部的通讯c;Pod的之间的通讯采用虚拟二层网络技术来实现c;我们当前环境用的是FlAnnel。
1、k8s集群中部署的最小单元
2、Pod最主要的功能管理是将一个业务或者一个调用链的所有服务(容器)
3、包含多个容器(一组容器的集合)
4、一个Pod中容器共享网络命名空间c;Pod是短暂的
Pod是在集群中运行部署应用或服务的最小单元c;他是可以支持很多容器的。Pod的设计理念是支持多个容器在一个Pod中共享网络地址和文件系统c;可以通过进程间通信和文件共享这种简单高效的方式组合完成服务。
比如:你运行一个操作系统发行版的软件仓库c;一个nginx容器用来发布软件c;另一个容器专门用来从源仓库做同步c;这两个容器的镜像不太可能是一个团队开发的c;但是他们一块工作才能提供一个微服务c;这种情况下c;不同的团队各自开发构建自己的容器镜像c;在部署的时候组合成一个微服务对外提供服务。这就是k8s中的Pod。
目前k8s中业务主要可以分为长期伺服型(long-running)、批处理型(batch)、节点后台支撑型(node-daemon)和有状态应用型(stateful application);分别对应的小机器人控制器为Deployment、Job、DaemonSet 和 StatefulSet。
# Pod是k8s中最小部署单元c;用来管理一个调用链的容器c;它之中的主容器(pause)为整个调用链的容器提供基础网络c;共享存储c;监控业务容器的运行状态
1、k8s中的命名规范
1、必须小写 2、必须以字母开头 3、名称当中只能够包含字母、数字和中划线(-)
apiVersion: v1 #必选c;版本号c;例如v1
kind: Pod #必选c;资源类型c;例如 Pod
metadata: #必选c;元数据
name: String #必选c;Pod名称
Annotations: #选做c;描述信息
nginx: nginx
namespace: String #Pod所属的命名空间,默认为"default"
labels: #自定义标签列表
- name: String
spec: #必选c;Pod中容器的详细定义
containers: #必选c;Pod中容器列表
- name: String #必选c;容器名称
image: String #必选c;容器的镜像名称
imagePullPolicy: [ Always|Never|IfNotPresent ] #获取镜像的策略
command: [String] #容器的启动命令列表c;如不指定c;使用打包时使用的启动命令
args: [String] #容器的启动命令参数列表
workingDir: String #容器的工作目录
volumeMounts: #挂载到容器内部的存储卷配置
- name: String #引用pod定义的共享存储卷的名称c;需用volumes[]部分定义的的卷名
mountPath: String #存储卷在容器内mount的绝对路径c;应少于512字符
readOnly: Boolean #是否为只读模式
ports: #需要暴露的端口库号列表
- name: String #端口的名称
containerPort: 80 #容器需要监听的端口号
hostPort: int #容器所在主机需要监听的端口号c;默认与Container相同
protocol: String #端口协议c;支持TCP和UDPc;默认TCP
env: #容器运行前需设置的环境变量列表
- name: String #环境变量名称
value: String #环境变量的值
resources: #资源限制和请求的设置
limits: #资源限制的设置
cpu: String #Cpu的限制c;单位为core数c;将用于docker run --cpu-shares参数
memory: String #内存限制c;单位可以为Mib/Gibc;将用于docker run --memory参数
requests: #资源请求的设置
cpu: String #Cpu请求c;容器启动的初始可用数量
memory: String #内存请求,容器启动的初始可用数量
lifecycle: #生命周期钩子
postStart: #容器启动后立即执行此钩子,如果执行失败,会根据重启策略进行重启
preStop: #容器终止前执行此钩子,无论结果如何,容器都会终止
livenessProbe: #对Pod内各容器健康检查的设置c;当探测无响应几次后将自动重启该容器
exec: #对Pod容器内检查方式设置为exec方式
command: [String] #exec方式需要制定的命令或脚本
httpGet: #对Pod内个容器健康检查方法设置为httpGetc;需要制定Path、port
path: String
port: number
host: String
scheR_782_11845@e: String
httpHeaders:
- name: String
value: String
tcpSocket: #对Pod内个容器健康检查方式设置为tcpSocket方式
port: number
initialDelaySeconds: 0 #容器启动完成后首次探测的时间c;单位为秒
timeoutSeconds: 0 #对容器健康检查探测等待响应的超时时间c;单位秒c;默认1秒
periodSeconds: 0 #对容器监控检查的定期探测时间设置c;单位秒c;默认10秒一次
successThreshold: 0
failureThreshold: 0
securityContext:
privileged: false
restartPolicy: [Always | Never | OnFailure] #Pod的重启策略
nodename: <String> #设置Nodename表示将该Pod调度到指定到名称的node节点上
nodeSELEctor: obeject #设置NodeSELEctor表示将该Pod调度到包含这个label的node上
imagePullSecrets: #Pull镜像时使用的secret名称c;以key:secretkey格式指定
- name: String
hostNetwork: false #是否使用主机网络模式c;默认为falsec;如果设置为truec;表示使用宿主机网络
volumes: #在该pod上定义共享存储卷列表
- name: String #共享存储卷名称 (volumes类型有很多种)
emptyDir: {} #类型为emtyDir的存储卷c;与Pod同生命周期的一个临时目录。为空值
hostPath: String #类型为hostPath的存储卷c;表示挂载Pod所在宿主机的目录
path: String #Pod所在宿主机的目录c;将被用于同期中mount的目录
secret: #类型为secret的存储卷c;挂载集群与定义的secret对象到容器内部
scretname: String
items:
- key: String
path: String
configMap: #类型为configMap的存储卷c;挂载预定义的configMap对象到容器内部
name: String
items:
- key: String
path: String
# 在这里c;可通过一个命令来查看每种资源的可配置项
# kubectl explain 资源类型 查看某种资源可以配置的一级属性
# kubectl explain 资源类型.属性 查看属性的子属性
[root@k8s-m-01 ~]# kubectl explain pod
KIND: Pod
VERSION: v1
FIELDS:
apiVersion <String>
kind <String>
metadata <Object>
spec <Object>
status <Object>
[root@k8s-m-01 ~]# kubectl explain pod.metadata
KIND: Pod
VERSION: v1
resourcE: metadata <Object>
FIELDS:
Annotations <map[String]String>
clusterName <String>
creationtimestamp <String>
deletionGracePeriodSeconds <Integer>
deletiontimestamp <String>
finalizers <[]String>
generatename <String>
generation <Integer>
labels <map[String]String>
managedFields <[]Object>
name <String>
namespace <String>
ownerReferences <[]Object>
resourceVersion <String>
selfLink <String>
uid <String>
# kubectl explain Pod #查apiVersion版本号 v1
[root@k8s-m-01 ~]# vim pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
containers:
- name: nginx
image: nginx
- name: tomcat
image: tomcat
# 1、nginx php MySQL
# 2、 制作镜像
# 3、创建nginx配置文件c;然后构建镜像
# 4、编写配置清单c;部署
[root@k8s-m-01 ~]# vim wordpress.yaml
apiVersion: v1
kind: Pod
metadata:
name: wordpress
spec:
containers:
- name: nginx
image: nginx
- name: php
image: alvinos/php:v2-fpm-mysql
- name: mysql
image: mysql:5.7
env:
- name: MYSQL_ROOT_password
value: "123"
# k8s部署一个yaml的应用:kubectl apply -f [配置清单]
[root@k8s-m-01 ~]# kubectl apply -f pod.yaml
pod/test-pod create
ImgPullErr : # 镜像拉取失败
ContainerCreaTing : # 容器创建中
# 扩展 1、进入不是默认空间的容器
[root@k8s-m-01 ~]# kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
pc-deployment-5c767764f5-fq47c 1/1 Running 2 78m
[root@k8s-m-01 ~]# kubectl exec -it pc-deployment-5c767764f5-fq47c -n dev -c nginx -- bash
root@pc-deployment-5c767764f5-fq47c:/# curl localhost
<h1>Welcome to nginx!</h1>
# 2、权限问题
[root@k8s-m-01 ~]# ll -a
drwxr-xr-x 3 root root 33 Jul 30 14:43 .kube
# 必须要有这个文件c;否则无法创建删除pod
在kubernetes中基本所有资源的一级属性都是一样的c;主要包含5部分:
apiVersion <String> 版本c;由kubernetes内部定义c;版本号必须可以用 kubectl api-versions 查询到
kind <String> 类型c;由kubernetes内部定义c;版本号必须可以用 kubectl api-resources 查询到
在上面的属性中c;spec是接下来研究的重点c;继续看下它的常见子属性:
# 命令格式: kubectl run (pod控制器名称) [参数]
# --image 指定Pod的镜像
# --port 指定端口
# --namespace 指定namespace
[root@k8s-m-01 ~]# kubectl run nginx --image=nginx:latest --port=80 --namespace dev
deployment.apps/nginx created
# 1、查看Pod基本信息
[root@k8s-m-01 ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 43s
# 2、查看Pod的详细信息
[root@k8s-m-01 ~]# kubectl describe pod nginx -n dev
Name: nginx
Namespace: dev
Priority: 0
Node: node1/192.168.5.4
Start Time: Wed, 08 May 2021 09:29:24 +0800
Labels: pod-template-hash=5ff7956ff6
run=nginx
Annotations: <none>
Status: Running
IP: 10.244.1.23
IPs:
IP: 10.244.1.23
Controlled By: ReplicaSet/nginx
Containers:
nginx:
Container ID: docker://4c62b8c0648d2512380f4ffa5da2c99d16e05634979973449c98e9b829f6253c
Image: nginx:latest
Image ID: docker-pullable://nginx@sha256:485b610fefec7ff6c463ced9623314a04ed67e3945b9c08d7e53a47f6d108dc7
Port: 80/TCP
Host Port: 0/TCP
State: Running
Started: Wed, 08 May 2021 09:30:01 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-hwvvw (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
Podscheduled True
Volumes:
default-token-hwvvw:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-hwvvw
Optional: false
QoS Class: BestEffort
Node-SELEctors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From message
---- ------ ---- ---- -------
Normal scheduled <unknown> default-scheduler successfully assigned dev/nginx-5ff7956ff6-fg2db to node1
Normal Pulling 4m11s kubelet, node1 Pulling image "nginx:latest"
Normal Pulled 3m36s kubelet, node1 successfully pulled image "nginx:latest"
Normal Created 3m36s kubelet, node1 Created container nginx
Normal Started 3m36s kubelet, node1 Started container nginx
# 1、获取pod IP
[root@k8s-m-01 ~]# kubectl get pods -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE ...
nginx 1/1 Running 0 190s 10.244.1.23 node1 ...
# 2、访问POD
[root@k8s-m-01 ~]# curl http://10.244.1.23:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
</head>
<body>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
# 1、删除指定Pod
[root@k8s-m-01 ~]# kubectl delete pod nginx -n dev
pod "nginx" deleted
# 2、此时c;显示删除Pod成功c;但是再查询c;发现又新产生了一个
[root@k8s-m-01 ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 21s
# 这是因为当前Pod是由Pod控制器创建的c;控制器会监控Pod状况c;一旦发现Pod死亡c;会立即重建
# 此时要想删除Podc;必须删除Pod控制器
# 3、先来查询一下当前namespace下的Pod控制器
[root@k8s-m-01 ~]# kubectl get deploy -n dev
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 1/1 1 1 9m7s
# 4、接下来c;删除此PodPod控制器
[root@k8s-m-01 ~]# kubectl delete deploy nginx -n dev
deployment.apps "nginx" deleted
# 5、稍等片刻c;再查询Podc;发现Pod被删除了
[root@k8s-m-01 ~]# kubectl get pods -n dev
No resources found in dev namespace.
创建一个pod-nginx.yamlc;内容如下:
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: dev
spec:
containers:
- image: nginx:latest
name: pod
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
然后就可以执行对应的创建和删除命令了:
# 创建:kubectl create -f pod-nginx.yaml
# 删除:kubectl delete -f pod-nginx.yaml
# 1、创建容器使用dockerc;一个docker对应一个容器,一个容器有进程,一个容器运行一个应用程序
# 2、pod是多进程c;运行多个应用程序
# 3、一个Pod有多个容器c;每个容器里面运行一个应用程序
# 4、Pod存在未来亲密性应用
1、两个应用之间进行交互
2、网络之间调用
3、两个应用需要频繁调用
1、共享网络 === 》 容器本身之间相互隔离的
2、共享存储
# 1、共享网络
通过Pause容器c;把其他业务容器加入Pause容器里面c;让所有业务中在同一个名称空间中c;可以实现网络共享
# 2、共享存储
引入数据卷概念volumes,用数据卷进行持久化数据存储
主要来研究pod.spec.containers
属性c;这也是pod配置中最为关键的一项配置。
[root@k8s-m-01 ~]# kubectl explain pod.spec.containers
KIND: Pod
VERSION: v1
resourcE: containers <[]Object> # 数组c;代表可以有多个容器
FIELDS:
name <String> # 容器名称
image <String> # 容器需要的镜像地址
imagePullPolicy <String> # 镜像拉取策略
command <[]String> # 容器的启动命令列表c;如不指定c;使用打包时使用的启动命令
args <[]String> # 容器的启动命令需要的参数列表
env <[]Object> # 容器环境变量的配置
ports <[]Object> # 容器需要暴露的端口号列表
resources <Object> # 资源限制和资源请求的设置
创建pod-base.yaml文件c;内容如下:
apiVersion: v1
kind: Pod
metadata:
name: pod-base
namespace: dev
labels:
user: heima
spec:
containers:
- name: nginx
image: nginx
- name: busybox
image: busybox:1.30
上面定义了一个比较简单Pod的配置c;里面有两个容器:
# 1、创建Pod
[root@master pod]# kubectl apply -f pod-base.yaml
pod/pod-base created
# 2、查看Pod状况
# READY 1/2 : 表示当前Pod中有2个容器c;其中1个准备就绪c;1个未就绪
# RESTARTS : 重启次数c;因为有1个容器故障了c;Pod一直在重启试图恢复它
[root@master pod]# kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
pod-base 1/2 Running 4 95s
# 3、可以通过describe查看内部的详情
# 此时已经运行起来了一个基本的Podc;虽然它暂时有问题
[root@master pod]# kubectl describe pod pod-base -n dev
创建pod-imagepullpolicy.yaml文件c;内容如下:
apiVersion: v1
kind: Pod
metadata:
name: pod-imagepullpolicy
namespace: dev
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: Always # 用于设置镜像拉取策略
- name: busybox
image: busybox:1.30
imagePullPolicyc;用于设置镜像拉取策略c;kubernetes支持配置三种拉取策略:
# 1、IfNotPresent:(默认值)
本地有则使用本地镜像c;本地没有则从远程仓库拉取镜像(本地有就本地c;本地没远程下载)
# 2. Always:
创建Pod都会重新从远程仓库拉取一次镜像(一直远程下载)
# 3. Never:
只使用本地镜像c;从不去远程仓库拉取c;本地没有就报错 (一直使用本地)
# 1、20版本后默认的是Onfailure :当容器终止且退出码部位0c;则kubetle则重新启动容器
默认值说明:
如果镜像tag为具体版本号c; 默认策略是:IfNotPresent
如果镜像tag为:latest(最终版本) c;默认策略是always
# 1、创建Pod
[root@master pod]# kubectl create -f pod-imagepullpolicy.yaml
pod/pod-imagepullpolicy created
# 2、查看Pod详情
# 此时明显可以看到nginx镜像有一步Pulling image "nginx"的过程
[root@master pod]# kubectl describe pod pod-imagepullpolicy -n dev
......
Events:
Type Reason Age From message
---- ------ ---- ---- -------
Normal scheduled <unknown> default-scheduler successfully assigned dev/pod-imagePullPolicy to k8s-n-01
Normal Pulling 32s kubelet, k8s-n-01 Pulling image "nginx"
Normal Pulled 26s kubelet, k8s-n-01 successfully pulled image "nginx"
Normal Created 26s kubelet, k8s-n-01 Created container nginx
Normal Started 25s kubelet, k8s-n-01 Started container nginx
Normal Pulled 7s (x3 over 25s) kubelet, k8s-n-01 Container image "busybox:1.30" already present on machine
Normal Created 7s (x3 over 25s) kubelet, k8s-n-01 Created container busybox
Normal Started 7s (x3 over 25s) kubelet, k8s-n-01 Started container busybox
# 在前面的案例中c;一直有一个问题没有解决c;就是的busybox容器一直没有成功运行c;那么到底是什么原因导致这个容器的故障呢?
原来busybox并不是一个程序c;而是类似于一个工具类的集合c;kubernetes集群启动管理后c;它会自动关闭。
# 解决方法就是让其一直在运行c;这就用到了command配置。
apiVersion: v1
kind: Pod
metadata:
name: pod-command
namespace: dev
spec:
containers:
- name: nginx
image: nginx
- name: busybox
image: busybox:1.30
command: ["/bin/sh","-c","touch /tmp/Hello.txt;while true;do /bin/echo $(date +%T) >> /tmp/Hello.txt; sleep 3; done;"]
# 注:
"/bin/sh","-c", 使用sh执行命令
touch /tmp/Hello.txt; 创建一个/tmp/Hello.txt 文件
while true;do /bin/echo $(date +%T) >> /tmp/Hello.txt; sleep 3; done; 每隔3秒向文件中写入当前时间
# 1、创建Pod
[root@master pod]# kubectl create -f pod-command.yaml
pod/pod-command created
# 2、查看Pod状态
# 此时发现两个pod都正常运行了
[root@master pod]# kubectl get pods pod-command -n dev
NAME READY STATUS RESTARTS AGE
pod-command 2/2 Runing 0 2s
# 3、进入pod中的busybox容器c;查看文件内容
# 补充一个命令: kubectl exec pod名称 -n 命名空间 -it -c 容器名称 /bin/sh 在容器内部执行命令
# 使用这个命令就可以进入某个容器的内部c;然后进行相关操作了
# 可以查看txt文件的内容
[root@master pod]# kubectl exec pod-command -n dev -it -c busybox /bin/sh
/ # tail -f /tmp/Hello.txt
13:35:35
13:35:38
13:35:41
通过上面发现command已经可以完成启动命令和传递参数的功能c;为什么这里还要提供一个args选项c;用于传递参数呢?这其实跟docker有点关系c;kubernetes中的command、args两项其实是实现覆盖Dockerfile中ENTRYPOINT的功能。
# 1 如果command和args均没有写c;那么用Dockerfile的配置。
# 2 如果command写了c;但args没有写c;那么Dockerfile默认的配置会被忽略c;执行输入的command
# 3 如果command没写c;但args写了c;那么Dockerfile中配置的ENTRYPOINT的命令会被执行c;使用当前args的参数
# 4 如果command和args都写了c;那么Dockerfile的配置被忽略c;执行command并追加上args参数
apiVersion: v1
kind: Pod
metadata:
name: pod-env
namespace: dev
spec:
containers:
- name: busybox
image: busybox:1.30
command: ["/bin/sh","-c","while true;do /bin/echo $(date +%T);sleep 60; done;"]
env: # 设置环境变量列表
- name: "username"
value: "admin"
- name: "password"
value: "123456"
# 1、创建Pod
[root@k8s-m-01 ~]# kubectl create -f pod-env.yaml
pod/pod-env created
# 2、进入容器c;输出环境变量
[root@k8s-m-01 ~]# kubectl exec pod-env -n dev -c busybox -it /bin/sh
/ # echo $username
admin
/ # echo $password
123456
这种方式不是很推荐c;推荐将这些配置单独存储在配置文件中c;这种方式将在后面介绍。
端口设置就是containers的ports选项
[root@k8s-m-01 ~]# kubectl explain pod.spec.containers.ports
KIND: Pod
VERSION: v1
resourcE: ports <[]Object>
FIELDS:
name <String> # 端口名称c;如果指定c;必须保证name在pod中是唯一的
containerPort<Integer> # 容器要监听的端口(0<x<65536)
hostPort <Integer> # 容器要在主机上公开的端口c;如果设置c;主机上只能运行容器的一个副本(一般省略)
hostIP <String> # 要将外部端口绑定到的主机IP(一般省略)
protocol <String> # 端口协议。必须是UDP、TCP或SCTP。默认为“TCP”。
apiVersion: v1
kind: Pod
metadata:
name: pod-ports
namespace: dev
spec:
containers:
- name: nginx
image: nginx
ports: # 设置容器暴露的端口列表
- name: nginx-port
containerPort: 80
protocol: TCP
# 1、创建Pod
[root@k8s-m-01 ~]# kubectl create -f pod-ports.yaml
pod/pod-ports created
# 2、查看pod
# 在下面可以明显看到配置信息
[root@k8s-m-01 ~]# kubectl get pod pod-ports -n dev -o yaml
......
spec:
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: nginx
ports:
- containerPort: 80
name: nginx-port
protocol: TCP
......
访问容器中的程序需要使用的是podIp:containerPort
容器中的程序要运行c;肯定是要占用一定资源的c;比如Cpu和内存等c;如果不对某个容器的资源做限制c;那么它就可能吃掉大量资源c;导致其它容器无法运行。
针对这种情况c;kubernetes提供了对内存和cpu的资源进行配额的机制c;这种机制主要通过resources选项实现c;他有两个子选项:
可以通过上面两个选项设置资源的上下限。
apiVersion: v1
kind: Pod
metadata:
name: pod-resources
namespace: dev
spec:
containers:
- name: nginx
image: nginx
resources: # 资源配额
limits: # 限制资源(上限)
cpu: "2" # CPU限制c;单位是core数
memory: "10Gi" # 内存限制
requests: # 请求资源(下限)
cpu: "1" # CPU限制c;单位是core数
memory: "10Mi" # 内存限制
cpu:core数c;可以为整数或小数
@H_183_5@memory: 内存大小c;可以使用Gi、Mi、G、M等形式
# 1、运行Pod
[root@k8s-m-01 ~]# kubectl create -f pod-resources.yaml
pod/pod-resources created
# 2、查看发现pod运行正常
[root@k8s-m-01 ~]# kubectl get pod pod-resources -n dev
NAME READY STATUS RESTARTS AGE
pod-resources 1/1 Running 0 39s
# 3、停止(删除)Pod
[root@k8s-m-01 ~]# kubectl delete -f pod-resources.yaml
pod "pod-resources" deleted
# 4、编辑podc;修改resources.requests.memory的值为10Gi
[root@k8s-m-01 ~]# vim pod-resources.yaml
# 5、再次启动pod
[root@k8s-m-01 ~]# kubectl create -f pod-resources.yaml
pod/pod-resources created
# 6、查看Pod状态c;发现Pod启动失败
[root@k8s-m-01 ~]# kubectl get pod pod-resources -n dev -o wide
NAME READY STATUS RESTARTS AGE
pod-resources 0/2 Pending 0 20s
# 7、查看pod详情会发现c;如下提示
[root@k8s-m-01 ~]# kubectl describe pod pod-resources -n dev
......
Warning Failedscheduling <unknown> default-scheduler 0/2 nodes are available: 2 Insufficient memory.(内存不足)
我们一般将pod对象从创建至终的这段时间范围称为pod的生命周期c;它主要包含下面的过程:
pod创建过程
运行初始化容器(init container)过程
运行主容器(main container)
pod终止过程
1、创建pod,并调度到合适的节点上
2、创建pause基础主容器c;提供共享名称空间 # (info容器) == 根容器 == 主容器
3、从上到下依次创建业务容器
4、启动业务容器c;启动那一刻会同时运行主容器上定义的Poststart钩子事件
5、持续存活状态监测、就绪状态监测
6、结束时c;执行prestop钩子事件
7、终止业务容器c;在终止主容器
8、销毁Pod
# 1、挂起(Pending):
API Server 创建了 pod 资源对象已存入 etcd 中c;但它尚未被调度完成c;或者仍处于从仓库下载镜像的过程中。
# 2、运行中(Running):
Pod 已经被调度至某节点c;并且所有容器都已经被 kubelet 创建完成
# 3、成功(Succeeded):
Pod 中的所有容器都已经成功终止并且不会被重启。
# 4、失败(Failed):
Pod 中的所有容器都已终止了c;并且至少有一个容器是因为失败终止。即容器以非 0 状态退出或者被系统禁止。
# 5、未知(Unknown):
Api Server 无法正常获取到 Pod 对象的状态信息c;通常是由于无法与所在工作节点的kubelet 通信所致。
===================================================================================================
# 6、ImgPullErr : (不常用)
镜像拉取失败
# 7、ContainerCreaTing : (不常用)
容器创建中
kubernetes在集群启动之后c;集群中的各个组件也都是以Pod方式运行的。可以通过下面命令查看:
[root@k8s-m-01 ~]# kubectl get pod -n kube-system
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-6955765f44-68g6v 1/1 Running 0 2d1h
kube-system coredns-6955765f44-cs5r8 1/1 Running 0 2d1h
kube-system etcd-master 1/1 Running 0 2d1h
kube-system kube-apiserver-master 1/1 Running 0 2d1h
kube-system kube-controller-manager-master 1/1 Running 0 2d1h
kube-system kube-flAnnel-ds-amd64-47r25 1/1 Running 0 2d1h
kube-system kube-flAnnel-ds-amd64-ls5lh 1/1 Running 0 2d1h
kube-system kube-proxy-685tk 1/1 Running 0 2d1h
kube-system kube-proxy-87spt 1/1 Running 0 2d1h
kube-system kube-scheduler-master 1/1 Running 0 2d1h
1. 用户通过kubectl或其他api客户端提交需要创建的Pod信息给apiServer
2. apiServer开始生成Pod对象的信息c;并将信息存入etcdc;然后返回确认信息至客户端
3. apiServer开始反映etcd中的Pod对象的变化c;其它组件使用watch机制来跟踪检查apiServer上的变动
4. scheduler发现有新的Pod对象要创建c;开始为Pod分配主机并将结果信息更新至apiServer
5. node节点上的kubelet发现有pod调度过来c;尝试调用docker启动容器c;并将结果回送至apiServer
6. apiServer将接收到的pod状态信息存入etcd中
1. 用户向apiServer发送删除pod对象的命令
2. apiServcer中的pod对象信息会随着时间的推移而更新c;在宽限期内(默认30s)c;pod被视为dead
3. 将pod标记为terminaTing状态(正在删除状态)
4. kubelet在监控到pod对象转为terminaTing状态的同时启动pod关闭过程
5. 端点控制器监控到pod对象的关闭行为时将其从所有匹配到此端点的service资源的端点列表中移除
6. 如果当前pod对象定义了preStop钩子处理器c;则在其标记为terminaTing后即会以同步的方式启动执行
7. pod对象中的容器进程收到停止信号
8. 宽限期结束后c;若pod中还存在仍在运行的进程c;那么pod对象会收到立即终止的信号
9. kubelet请求apiServer将此pod资源的宽限期设置为0从而完成删除操作c;此时pod对于用户已不可见
初始化容器是在pod的主容器启动之前要运行的容器c;主要是做一些主容器的前置工作c;它具有两大特征:
1. 初始化容器必须运行完成直至结束c;若某初始化容器运行失败c;那么kubernetes需要重启它直到成功完成
2. 初始化容器必须按照定义的顺序执行c;当且仅当前一个成功之后c;后面的一个才能运行
初始化容器有很多的应用场景c;下面列出的是最常见的几个:
1、提供主容器镜像中不具备的工具程序或自定义代码
2、初始化容器要先于应用容器串行启动并运行完成c;因此可用于延后应用容器的启动直至其依赖的条件得到满足
案例c;模拟下面这个需求:
假设要以主容器来运行nginxc;但是要求在运行nginx之前先要能够连接上R_782_11845@ysql和redis所在服务器
为了简化测试c;事先规定好mysql(192.168.15.201)
和redis(192.168.15.202)
服务器的地址
apiVersion: v1
kind: Pod
metadata:
name: pod-initcontainer
namespace: dev
spec:
containers:
- name: main-container
image: nginx:1.17.1
ports:
- name: nginx-port
containerPort: 80
initContainers:
- name: test-mysql
image: busybox:1.30
command: ['sh', '-c', 'until ping 192.168.15.201 -c 1 ; do echo waiTing for mysql...; sleep 2; done;']
- name: test-redis
image: busybox:1.30
command: ['sh', '-c', 'until ping 192.168.15.202 -c 1 ; do echo waiTing for rEIDs...; sleep 2; done;']
# 1、创建pod
[root@k8s-m-01 ~]# kubectl create -f pod-initcontainer.yaml
pod/pod-initcontainer created
# 2、查看pod状态
# 发现pod卡在启动第一个初始化容器过程中c;后面的容器不会运行
root@master ~]# kubectl describe pod pod-initcontainer -n dev
........
Events:
Type Reason Age From message
---- ------ ---- ---- -------
Normal scheduled 49s default-scheduler successfully assigned dev/pod-initcontainer to k8s-n-01
Normal Pulled 48s kubelet, k8s-n-01 Container image "busybox:1.30" already present on machine
Normal Created 48s kubelet, k8s-n-01 Created container test-mysql
Normal Started 48s kubelet, k8s-n-01 Started container test-mysql
# 3、动态查看pod
[root@k8s-m-01 ~]# kubectl get pods pod-initcontainer -n dev -w
NAME READY STATUS RESTARTS AGE
pod-initcontainer 0/1 Init:0/2 0 15s
pod-initcontainer 0/1 Init:1/2 0 52s
pod-initcontainer 0/1 Init:1/2 0 53s
pod-initcontainer 0/1 PodInitializing 0 89s
pod-initcontainer 1/1 Running 0 90s
# 4、接下来新开一个sHellc;为当前服务器新增两个ipc;观察pod的变化
[root@k8s-m-01 ~]# ifconfig eth0:1 192.168.15.201 netmask 255.255.255.0 up
[root@k8s-m-01 ~]# ifconfig eth0:2 192.168.15.202 netmask 255.255.255.0 up
钩子函数能够感知自身生命周期中的事件c;并在相应的时刻到来时运行用户指定的程序代码。
kubernetes在主容器的启动之后和停止之前提供了两个钩子函数:
1、post start: # 容器创建之后执行c;如果失败了会重启容器
2、pre stop : # 容器终止之前执行c;执行完成之后容器将成功终止c;在其完成之前会阻塞删除容器的操作
钩子处理器支持使用下面三种方式定义动作:
Exec命令:在容器内执行一次命令
……
lifecycle:
postStart:
exec:
command:
- cat
- /tmp/healthy
……
TCPSocket:在当前容器尝试访问指定的socket
……
lifecycle:
postStart:
tcpSocket:
port: 8080
……
……
lifecycle:
postStart:
httpGet:
path: / #URI地址
port: 80 #端口号
host: 192.168.15.100 #主机地址
scheR_782_11845@e: http #支持的协议c;http或者https
……
接下来c;以exec方式为例c;演示下钩子函数的使用c;创建pod-hook-exec.yaml文件c;内容如下:
apiVersion: v1
kind: Pod
metadata:
name: pod-hook-exec
namespace: dev
spec:
containers:
- name: main-container
image: nginx:1.17.1
ports:
- name: nginx-port
containerPort: 80
lifecycle:
postStart:
exec: # 在容器启动的时候执行一个命令c;修改掉nginx的默认首页内容
command: ["/bin/sh", "-c", "echo postStart... > /usr/share/nginx/html/index.html"]
preStop:
exec: # 在容器停止之前停止nginx服务
command: ["/usr/sbin/nginx","-s","quit"]
# 1、创建pod
[root@k8s-m-01 ~]# kubectl create -f pod-hook-exec.yaml
pod/pod-hook-exec created
# 2、查看pod
[root@k8s-m-01 ~]# kubectl get pods pod-hook-exec -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE
pod-hook-exec 1/1 Running 0 29s 10.244.2.48 k8s-n-02
# 3、访问pod
[root@k8s-m-01 ~]# curl 10.244.2.48
postStart...
容器探测用于检测容器中的应用实例是否正常工作c;是保障业务可用性的一种传统机制。如果经过探测c;实例的状态不符合预期c;那么kubernetes就会把该问题实例" 摘除 "c;不承担业务流量。kubernetes提供了两种探针来实现容器探测c;分别是:
# 1、存活性检查 :
容器是否正常启动c;探测失败c;立即删除容器
# 2、就绪性检查 :
容器是否能够正常提供服务c;探测失败c;立即移除负载均衡
liveness probes: 存活性探针c;用于检测应用实例当前是否处于正常运行状态c;如果不是c;k8s会重启容器
readiness probes:就绪性探针c;用于检测应用实例当前是否可以接收请求c;如果不能c;k8s不会转发流量
上面两种探针目前均支持三种探测方式:
Exec命令:在容器内执行一次命令c;如果命令执行的退出码为0c;则认为程序正常c;否则不正常
……
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
……
TCPSocket:将会尝试访问一个用户容器的端口c;如果能够建立这条连接c;则认为程序正常c;否则不正常
……
livenessProbe:
tcpSocket:
port: 8080
……
httpGet:调用容器内Web应用的URLc;如果返回的状态码在200和399之间c;则认为程序正常c;否则不正常
……
livenessProbe:
httpGet:
path: / #URI地址
port: 80 #端口号
host: 127.0.0.1 #主机地址
scheR_782_11845@e: http #支持的协议c;http或者https
……
apiVersion: v1
kind: Pod
metadata:
name: pod-liveness-exec
namespace: dev
spec:
containers:
- name: nginx
image: nginx:1.17.1
ports:
- name: nginx-port
containerPort: 80
livenessProbe:
exec:
command: ["/bin/cat","/tmp/Hello.txt"] # 执行一个查看文件的命令
# 1、创建Pod
[root@k8s-m-01 ~]# kubectl create -f pod-liveness-exec.yaml
pod/pod-liveness-exec created
# 2、查看Pod详情
[root@k8s-m-01 ~]# kubectl describe pods pod-liveness-exec -n dev
......
Normal Created 20s (x2 over 50s) kubelet, k8s-n-01 Created container nginx
Normal Started 20s (x2 over 50s) kubelet, k8s-n-01 Started container nginx
Normal Killing 20s kubelet, k8s-n-01 Container nginx failed liveness probe, will be restarted
Warning Unhealthy 0s (x5 over 40s) kubelet, k8s-n-01 Liveness probe failed: cat: can't open '/tmp/Hello11.txt': No such file or directory
# 观察上面的信息@R_936_10585@nginx容器启动之后就进行了健康检查
# 检查失败之后c;容器被kill掉c;然后尝试进行重启(这是重启策略的作用c;后面讲解)
# 稍等一会之后c;再观察pod信息c;就可以看到RESTARTS不再是0c;而是一直增长
[root@k8s-m-01 ~]# kubectl get pods pod-liveness-exec -n dev
NAME READY STATUS RESTARTS AGE
pod-liveness-exec 0/1 CrashLoopBACkOff 2 3m19s
# 当然接下来c;可以修改成一个存在的文件c;比如/tmp/Hello.txtc;再试c;结果就正常了......
# command: ["/bin/ls","/tmp/"] #正确配置(查看文件的命令)
apiVersion: v1
kind: Pod
metadata:
name: pod-liveness-tcpsocket
namespace: dev
spec:
containers:
- name: nginx
image: nginx:1.17.1
ports:
- name: nginx-port
containerPort: 80
livenessProbe:
tcpSocket:
port: 8080 # 尝试访问8080端口
# 1、创建Pod
[root@k8s-m-01 ~]# kubectl create -f pod-liveness-tcpsocket.yaml
pod/pod-liveness-tcpsocket created
# 2、查看Pod详情
[root@k8s-m-01 ~]# kubectl describe pods pod-liveness-tcpsocket -n dev
......
Normal scheduled 31s default-scheduler successfully assigned dev/pod-liveness-tcpsocket to k8s-n-02
Normal Pulled <invalid> kubelet, k8s-n-02 Container image "nginx:1.17.1" already present on machine
Normal Created <invalid> kubelet, k8s-n-02 Created container nginx
Normal Started <invalid> kubelet, k8s-n-02 Started container nginx
Warning Unhealthy <invalid> (x2 over <invalid>) kubelet, k8s-n-02 Liveness probe failed: dial tcp 10.244.2.44:8080: connect: connection refused
# 观察上面的信息c;发现尝试访问8080端口,但是失败了
# 稍等一会之后c;再观察pod信息c;就可以看到RESTARTS不再是0c;而是一直增长
[root@k8s-m-01 ~]# kubectl get pods pod-liveness-tcpsocket -n dev
NAME READY STATUS RESTARTS AGE
pod-liveness-tcpsocket 0/1 CrashLoopBACkOff 2 3m19s
# 当然接下来c;可以修改成一个可以访问的端口c;比如80c;再试c;结果就正常了......
# port: 80 (正确配置)
apiVersion: v1
kind: Pod
metadata:
name: pod-liveness-httpget
namespace: dev
spec:
containers:
- name: nginx
image: nginx:1.17.1
ports:
- name: nginx-port
containerPort: 80
livenessProbe:
httpGet: # 其实就是访问http://127.0.0.1:80/Hello
scheR_782_11845@e: http #支持的协议c;http或者https
port: 80 #端口号
path: /Hello #URI地址
# 1、创建Pod
[root@k8s-m-01 ~]# kubectl create -f pod-liveness-httpget.yaml
pod/pod-liveness-httpget created
# 2、查看Pod详情
[root@k8s-m-01 ~]# kubectl describe pod pod-liveness-httpget -n dev
.......
Normal Pulled 6s (x3 over 64s) kubelet, k8s-n-01 Container image "nginx:1.17.1" already present on machine
Normal Created 6s (x3 over 64s) kubelet, k8s-n-01 Created container nginx
Normal Started 6s (x3 over 63s) kubelet, k8s-n-01 Started container nginx
Warning Unhealthy 6s (x6 over 56s) kubelet, k8s-n-01 Liveness probe failed: http probe failed with statuscode: 404
Normal Killing 6s (x2 over 36s) kubelet, k8s-n-01 Container nginx failed liveness probe, will be restarted
# 3、观察上面信息c;尝试访问路径c;但是未找到,出现404错误
# 稍等一会之后c;再观察pod信息c;就可以看到RESTARTS不再是0c;而是一直增长
[root@k8s-m-01 ~]# kubectl get pod pod-liveness-httpget -n dev
NAME READY STATUS RESTARTS AGE
pod-liveness-httpget 1/1 Running 5 3m17s
# 当然接下来c;可以修改成一个可以访问的路径pathc;比如/c;再试c;结果就正常了......
# path: / (正确配置)
至此c;已经使用liveness Probe演示了三种探测方式c;但是查看livenessProbe的子属性c;会发现除了这三种方式c;还有一些其他的配置c;在这里一并解释下:
[root@k8s-m-01 ~]# kubectl explain pod.spec.containers.livenessProbe
FIELDS:
exec <Object>
tcpSocket <Object>
httpGet <Object>
initialDelaySeconds <Integer> # 容器启动后等待多少秒执行第一次探测
timeoutSeconds <Integer> # 探测超时时间。默认1秒c;最小1秒
periodSeconds <Integer> # 执行探测的频率。默认是10秒c;最小1秒
failureThreshold <Integer> # 连续探测失败多少次才被认定为失败。默认是3。最小值是1
successThreshold <Integer> # 连续探测成功多少次才被认定为成功。默认是1
下面稍微配置两个c;演示下效果即可:
[root@k8s-m-01 ~]# more pod-liveness-httpget.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-liveness-httpget
namespace: dev
spec:
containers:
- name: nginx
image: nginx:1.17.1
ports:
- name: nginx-port
containerPort: 80
livenessProbe:
httpGet:
scheR_782_11845@e: http
port: 80
path: /
initialDelaySeconds: 30 # 容器启动后30s开始探测
timeoutSeconds: 5 # 探测超时时间为5s
# 1. Always: (默认)
当容器失效时c;由 kubelet 自动重启该容器。
# 2. OnFailure:
当容器终止运行且退出码不为 0 时c;由 kubelet 自动重启该容器
# 3. Never:
不论容器运行状态如何c;kubelet 都不会重启该容器。
kubelet 重启失效容器的时间间隔以 sync-frequency 乘以 2n 来计算;例如 1、2、4、8 倍等c;最长延时5min c;并且在成功重启后的 10 min 后重置该时间。
Pod 的重启策略与控制方式息息相关c;当前可用于管理 Pod 的控制器包括 ReplicationController、Job、DaemonSet 及直接通过 kubelet 管理(静态 Pod)。每种控制器对 Pod 的重启策略要求如下:
# 1.RC 和 DaemonSet:必须设置为 Alwaysc;需要保证该容器持续运行。
# 2.Job 和 CronJob:OnFailure 或 Neverc;确保容器执行完成后不再重启。
# 3.kubelet:在 Pod 失效时自动重启它c;不论将 RestartPolicy 设置为什么值c;也不会对 Pod 进行健康检查。
重启策略适用于pod对象中的所有容器c;首次需要重启的容器c;将在其需要时立即进行重启c;随后再次需要重启的操作将由kubelet延迟一段时间后进行c;且反复的重启操作的延迟时长以此为10s、20s、40s、80s、160s和300sc;300s是最大延迟时长。
Pod 重启策略( RestartPolicy )应用于 Pod 内的所有容器c;井且仅在 Pod 所处的 Node 上由 kubelet 进行判断和重启操作。
当某个容器异常退出或者健康检查失败时c; kubelet 将根据 RestartPolicy 设置来进行相应的操作。Pod 的重启策略包括:Always、OnFailure 和 Neverc;默认值为 Always
apiVersion: v1
kind: Pod
metadata:
name: pod-restartpolicy
namespace: dev
spec:
containers:
- name: nginx
image: nginx:1.17.1
ports:
- name: nginx-port
containerPort: 80
livenessProbe:
httpGet:
scheR_782_11845@e: http
port: 80
path: /Hello
restartPolicy: Never # 设置重启策略为Never (默认Always)
# 1、创建Pod
[root@k8s-m-01 ~]# kubectl create -f pod-restartpolicy.yaml
pod/pod-restartpolicy created
# 2、查看Pod详情c;发现nginx容器失败
[root@k8s-m-01 ~]# kubectl describe pods pod-restartpolicy -n dev
......
Warning Unhealthy 15s (x3 over 35s) kubelet, k8s-n-01 Liveness probe failed: http probe failed with statuscode: 404
Normal Killing 15s kubelet, k8s-n-01 Container nginx failed liveness probe
# 3、多等一会c;再观察pod的重启次数c;发现一直是0c;并未重启
[root@k8s-m-01 ~]# kubectl get pods pod-restartpolicy -n dev
NAME READY STATUS RESTARTS AGE
pod-restartpolicy 0/1 Running 0 5min42s
Pod中可以同时运行多个进程(作为容器运行)协同工作。
同一个 Pod 中的容器会自动的分配到同一个 node上。同一个 Pod 中的容器共享资源、网络环境和依赖c;所以它们总是被同时调度。在一个 Pod 中同时运行多个容器是一种比较高级的用法。只有当你的容器需要紧密配合协作的时候才考虑用这种模式。
Pod 在设计⽀持就不是作为持久化实体的。在调度失败、节点故障、缺少资源或者节点维护的状态下都会死
掉会被驱逐。通常c;我们是需要借助类似于 Docker 存储卷这样的资源来做 Pod 的数据持久
在默认情况下c;一个Pod在哪个Node节点上运行c;是由scheduler组件采用相应的算法计算出来的c;这个过程是不受人工控制的。但是在实际使用中c;这并不满足的需求c;因为很多情况下c;我们想控制某些Pod到达某些节点上c;那么应该怎么做呢?这就要求了解kubernetes对Pod的调度规则c;kubernetes提供了四大类调度方式:
定向调度c;指的是利用在pod上声明nodename或者nodeSELEctorc;以此将Pod调度到期望的node节点上。注意c;这里的调度是强制的c;这就意味着即使要调度的目标Node不存在c;也会向上面进行调度c;只不过pod运行失败而已。
Nodename用于强制约束将Pod调度到指定的Name的Node节点上。这种方式c;其实是直接跳过scheduler的调度逻辑c;直接将Pod调度到指定名称的节点。
创建一个pod-nodename.yaml文件
[root@k8s-m-01 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-m-01 Ready control-plane,master 4d18h v1.21.3
k8s-n-01 Ready <none> 4d18h v1.21.3
k8s-n-02 Ready <none> 4d18h v1.21.3
apiVersion: v1
kind: Pod
metadata:
name: pod-nodename
namespace: dev
spec:
containers:
- name: nginx
image: nginx:1.17.1
nodename: k8s-n-01 # 指定调度到k8s-n-01节点上(node的主机名称)
# 1、创建Pod
[root@k8s-m-01 ~]# kubectl create -f pod-nodename.yaml
pod/pod-nodename created
# 2、查看Pod调度到NODE属性c;确实是调度到了k8s-n-01节点上
[root@k8s-m-01 ~]# kubectl get pods pod-nodename -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE ......
pod-nodename 1/1 Running 0 56s 10.244.1.87 k8s-n-01 ......
# 3、接下来c;删除podc;修改nodename的值为node3(并没有node3节点)
[root@k8s-m-01 ~]# kubectl delete -f pod-nodename.yaml
pod "pod-nodename" deleted
[root@k8s-m-01 ~]# vim pod-nodename.yaml
[root@k8s-m-01 ~]# kubectl create -f pod-nodename.yaml
pod/pod-nodename created
# 4、再次查看c;发现已经向Node3节点调度c;但是由于不存在Node3节点c;所以pod无法正常运行
[root@k8s-m-01 ~]# kubectl get pods pod-nodename -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE ......
pod-nodename 0/1 Pending 0 6s <none> node3 ......
NodeSELEctor用于将pod调度到添加了指定标签的node节点上。它是通过kubernetes的label-SELEctor机制实现的c;也就是说c;在pod创建之前c;会由scheduler使用MatchNodeSELEctor调度策略进行label匹配c;找出目标nodec;然后将pod调度到目标节点c;该匹配规则是强制约束。
[root@k8s-m-01 ~]# kubectl label nodes k8s-n-01 nodeenv=pro
node/k8s-n-02 labeled
[root@k8s-m-01 ~]# kubectl label nodes k8s-n-02 nodeenv=test
node/k8s-n-02 labeled
apiVersion: v1
kind: Pod
metadata:
name: pod-nodeSELEctor
namespace: dev
spec:
containers:
- name: nginx
image: nginx:1.17.1
nodeSELEctor:
nodeenv: pro # 指定调度到具有nodeenv=pro标签的节点上
# 1、创建Pod
[root@k8s-m-01 ~]# kubectl create -f pod-nodeSELEctor.yaml
pod/pod-nodeSELEctor created
# 2、查看Pod调度到NODE属性c;确实是调度到了k8s-n-01节点上
[root@k8s-m-01 ~]# kubectl get pods pod-nodeSELEctor -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE ......
pod-nodeSELEctor 1/1 Running 0 47s 10.244.1.87 k8s-n-01 ......
# 3、接下来c;删除podc;修改nodeSELEctor的值为nodeenv: xxxx(不存在打有此标签的节点)
[root@k8s-m-01 ~]# kubectl delete -f pod-nodeSELEctor.yaml
pod "pod-nodeSELEctor" deleted
[root@k8s-m-01 ~]# vim pod-nodeSELEctor.yaml
[root@k8s-m-01 ~]# kubectl create -f pod-nodeSELEctor.yaml
pod/pod-nodeSELEctor created
# 4、再次查看c;发现pod无法正常运行,Node的值为none
[root@k8s-m-01 ~]# kubectl get pods -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE
pod-nodeSELEctor 0/1 Pending 0 2m20s <none> <none>
# 5、查看详情,发现node SELEctor匹配失败的提示
[root@k8s-m-01 ~]# kubectl describe pods pod-nodeSELEctor -n dev
.......
Events:
Type Reason Age From message
---- ------ ---- ---- -------
Warning Failedscheduling <unknown> default-scheduler 0/3 nodes are available: 3 node(s) didn't match node SELEctor.
Warning Failedscheduling <unknown> default-scheduler 0/3 nodes are available: 3 node(s) didn't match node SELEctor.
上一节c;介绍了两种定向调度的方式c;使用起来非常方便c;但是也有一定的问题c;那就是如果没有满足条件的Nodec;那么Pod将不会被运行c;即使在集群中还有可用Node列表也不行c;这就限制了它的使用场景。
基于上面的问题c;kubernetes还提供了一种亲和性调度(Affinity)。它在NodeSELEctor的基础之上的进行了扩展c;可以通过配置的形式c;实现优先选择满足条件的Node进行调度c;如果没有c;也可以调度到不满足条件的节点上c;使调度更加灵活。
Affinity主要分为三类:
nodeAffinity(node亲和性): 以node为目标c;解决pod可以调度到哪些node的问题
podAffinity(pod亲和性) : 以pod为目标c;解决pod可以和哪些已存在的pod部署在同一个拓扑域中的问题
podAntiAffinity(pod反亲和性) : 以pod为目标c;解决pod不能和哪些已存在pod部署在同一个拓扑域中的问题
关于亲和性(反亲和性)使用场景的说明:
亲和性:如果两个应用频繁交互c;那就有必要利用亲和性让两个应用的尽可能的靠近c;这样可以减少因网络通信而带来的性能损耗。
反亲和性:当应用的采用多副本部署时c;有必要采用反亲和性让各个应用实例打散分布在各个node上c;这样可以提高服务的高可用性。
首先来看一下NodeAffinity
的可配置项:
pod.spec.affinity.nodeAffinity
requiredDuringschedulingIgnoredDuringExecution Node节点必须满足指定的所有规则才可以c;相当于硬限制
nodeSELEctorTerms 节点选择列表
matchFields 按节点字段列出的节点选择器要求列表
matchExpressions 按节点标签列出的节点选择器要求列表(推荐)
key 键
values 值
operator 关系符 支持Exists, DoesnotExist, In, NoTin, Gt, Lt
preferredDuringschedulingIgnoredDuringExecution 优先调度到满足指定的规则的Nodec;相当于软限制 (倾向)
preference 一个节点选择器项c;与相应的权重相关联
matchFields 按节点字段列出的节点选择器要求列表
matchExpressions 按节点标签列出的节点选择器要求列表(推荐)
key 键
values 值
operator 关系符 支持In, NoTin, Exists, DoesnotExist, Gt, Lt
weight 倾向权重c;在范围1-100。
关系符的使用说明:
- matchExpressions:
- key: nodeenv # 匹配存在标签的key为nodeenv的节点
operator: Exists
- key: nodeenv # 匹配标签的key为nodeenv,且value是"xxx"或"yyy"的节点
operator: In
values: ["xxx","yyy"]
- key: nodeenv # 匹配标签的key为nodeenv,且value大于"xxx"的节点
operator: Gt
values: "xxx"
requiredDuringschedulingIgnoredDuringExecution
,创建pod-nodeaffinity-required.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-nodeaffinity-required
namespace: dev
spec:
containers:
- name: nginx
image: nginx:1.17.1
affinity: #亲和性设置
nodeAffinity: #设置node亲和性
requiredDuringschedulingIgnoredDuringExecution: # 硬限制
nodeSELEctorTerms:
- matchExpressions: # 匹配env的值在["xxx","yyy"]中的标签
- key: nodeenv
operator: In
values: ["xxx","yyy"]
# 1、创建pod
[root@k8s-m-01 ~]# kubectl create -f pod-nodeaffinity-required.yaml
pod/pod-nodeaffinity-required created
# 2、查看pod状态 (运行失败)
[root@k8s-m-01 ~]# kubectl get pods pod-nodeaffinity-required -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE ......
pod-nodeaffinity-required 0/1 Pending 0 16s <none> <none> ......
# 3、查看Pod的详情
# 发现调度失败c;提示node选择失败
[root@k8s-m-01 ~]# kubectl describe pod pod-nodeaffinity-required -n dev
......
Warning Failedscheduling <unknown> default-scheduler 0/3 nodes are available: 3 node(s) didn't match node SELEctor.
Warning Failedscheduling <unknown> default-scheduler 0/3 nodes are available: 3 node(s) didn't match node SELEctor.
# 4、接下来c;停止pod
[root@k8s-m-01 ~]# kubectl delete -f pod-nodeaffinity-required.yaml
pod "pod-nodeaffinity-required" deleted
# 5、修改文件c;将values: ["xxx","yyy"]------> ["pro","yyy"]
[root@k8s-m-01 ~]# vim pod-nodeaffinity-required.yaml
# 6、再次启动
[root@k8s-m-01 ~]# kubectl create -f pod-nodeaffinity-required.yaml
pod/pod-nodeaffinity-required created
# 7、此时查看c;发现调度成功c;已经将pod调度到了k8s-n-01上
[root@k8s-m-01 ~]# kubectl get pods pod-nodeaffinity-required -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE ......
pod-nodeaffinity-required 1/1 Running 0 11s 10.244.1.89 k8s-n-01 ......
requiredDuringschedulingIgnoredDuringExecution
创建pod-nodeaffinity-preferred.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-nodeaffinity-preferred
namespace: dev
spec:
containers:
- name: nginx
image: nginx:1.17.1
affinity: #亲和性设置
nodeAffinity: #设置node亲和性
preferredDuringschedulingIgnoredDuringExecution: # 软限制
- weight: 1
preference:
matchExpressions: # 匹配env的值在["xxx","yyy"]中的标签(当前环境没有)
- key: nodeenv
operator: In
values: ["xxx","yyy"]
# 1、创建pod
[root@k8s-m-01 ~]# kubectl create -f pod-nodeaffinity-preferred.yaml
pod/pod-nodeaffinity-preferred created
# 2、查看pod状态 (运行成功)
[root@k8s-m-01 ~]# kubectl get pod pod-nodeaffinity-preferred -n dev
NAME READY STATUS RESTARTS AGE
pod-nodeaffinity-preferred 1/1 Running 0 40s
NodeAffinity规则设置的注意事项:
# 1 、如果同时定义了nodeSELEctor和nodeAffinityc;那么必须两个条件都得到满足c;Pod才能运行在指定的Node上
# 2 、如果nodeAffinity指定了多个nodeSELEctorTermsc;那么只需要其中一个能够匹配成功即可
# 3 、如果一个nodeSELEctorTerms中有多个matchExpressions c;则一个节点必须满足所有的才能匹配成功
# 4 、如果一个pod所在的Node在Pod运行期间其标签发生了改变c;不再符合该Pod的节点亲和性需求c;则系统将忽略此变化
PodAffinity主要实现以运行的Pod为参照c;实现让新创建的Pod跟参照pod在一个区域的功能。
PodAffinity
的可配置项pod.spec.affinity.podAffinity
requiredDuringschedulingIgnoredDuringExecution 硬限制
namespaces 指定参照pod的namespace
topologyKey 指定调度作用域
labelSELEctor 标签选择器
matchExpressions 按节点标签列出的节点选择器要求列表(推荐)
key 键
values 值
operator 关系符 支持In, NoTin, Exists, DoesnotExist.
matchLabels 指多个matchExpressions映射的内容
preferredDuringschedulingIgnoredDuringExecution 软限制
podAffinityTerm 选项
namespaces
topologyKey
labelSELEctor
matchExpressions
key 键
values 值
operator
matchLabels
weight 倾向权重c;在范围1-100
topologyKey用于指定调度时作用域,例如:
如果指定为kubernetes.io/hostnamec;那就是以Node节点为区分范围
如果指定为beta.kubernetes.io/os,则以Node节点的操作系统类型来区分
requiredDuringschedulingIgnoredDuringExecution
,1、首先创建一个参照Podc;pod-podaffinity-target.yaml:
apiVersion: v1
kind: Pod
metadata:
name: pod-podaffinity-target
namespace: dev
labels:
podenv: pro #设置标签
spec:
containers:
- name: nginx
image: nginx:1.17.1
nodename: k8s-n-01 # 将目标pod名确指定到k8s-n-01上
# 启动目标pod
[root@k8s-m-01 ~]# kubectl create -f pod-podaffinity-target.yaml
pod/pod-podaffinity-target created
# 查看pod状况
[root@k8s-m-01 ~]# kubectl get pods pod-podaffinity-target -n dev
NAME READY STATUS RESTARTS AGE
pod-podaffinity-target 1/1 Running 0 4s
2、创建pod-podaffinity-required.yamlc;内容如下:
apiVersion: v1
kind: Pod
metadata:
name: pod-podaffinity-required
namespace: dev
spec:
containers:
- name: nginx
image: nginx:1.17.1
affinity: #亲和性设置
podAffinity: #设置pod亲和性
requiredDuringschedulingIgnoredDuringExecution: # 硬限制
- labelSELEctor:
matchExpressions: # 匹配env的值在["xxx","yyy"]中的标签
- key: podenv
operator: In
values: ["xxx","yyy"]
topologyKey: kubernetes.io/hostname
上面配置表达的意思是:新Pod必须要与拥有标签nodeenv=xxx或者nodeenv=yyy的pod在同一Node上c;显然现在没有这样podc;接下来c;运行测试一下。
# 1、启动pod
[root@k8s-m-01 ~]# kubectl create -f pod-podaffinity-required.yaml
pod/pod-podaffinity-required created
# 2、查看pod状态c;发现未运行
[root@k8s-m-01 ~]# kubectl get pods pod-podaffinity-required -n dev
NAME READY STATUS RESTARTS AGE
pod-podaffinity-required 0/1 Pending 0 9s
# 3、查看详细信息
[root@k8s-m-01 ~]# kubectl describe pods pod-podaffinity-required -n dev
......
Events:
Type Reason Age From message
---- ------ ---- ---- -------
Warning Failedscheduling <unknown> default-scheduler 0/3 nodes are available: 2 node(s) didn't match pod affinity rules, 1 node(s) had taints that the pod didn't tolerate.
# 4、接下来修改 values: ["xxx","yyy"]----->values:["pro","yyy"]
# 意思是:新Pod必须要与拥有标签nodeenv=xxx或者nodeenv=yyy的pod在同一Node上
[root@k8s-m-01 ~]# vim pod-podaffinity-required.yaml
# 5、然后重新创建podc;查看效果
[root@k8s-m-01 ~]# kubectl delete -f pod-podaffinity-required.yaml
pod "pod-podaffinity-required" deleted
[root@k8s-m-01 ~]# kubectl create -f pod-podaffinity-required.yaml
pod/pod-podaffinity-required created
# 6、发现此时Pod运行正常
[root@k8s-m-01 ~]# kubectl get pods pod-podaffinity-required -n dev
NAME READY STATUS RESTARTS AGE LABELS
pod-podaffinity-required 1/1 Running 0 6s <none>
关于PodAffinity
的 preferredDuringschedulingIgnoredDuringExecution
c;这里不再演示。
PodAntiAffinity主要实现以运行的Pod为参照c;让新创建的Pod跟参照pod不在一个区域中的功能。
它的配置方式和选项跟PodAffinty是一样的c;这里不再做详细解释c;直接做一个测试案例。
[root@k8s-m-01 ~]# kubectl get pods -n dev -o wide --show-labels
NAME READY STATUS RESTARTS AGE IP NODE LABELS
pod-podaffinity-required 1/1 Running 0 3m29s 10.244.1.38 k8s-n-01 <none>
pod-podaffinity-target 1/1 Running 0 9m25s 10.244.1.37 k8s-n-01 podenv=pro
apiVersion: v1
kind: Pod
metadata:
name: pod-podantiaffinity-required
namespace: dev
spec:
containers:
- name: nginx
image: nginx:1.17.1
affinity: #亲和性设置
podAntiAffinity: #设置pod亲和性
requiredDuringschedulingIgnoredDuringExecution: # 硬限制
- labelSELEctor:
matchExpressions: # 匹配podenv的值在["pro"]中的标签
- key: podenv
operator: In
values: ["pro"]
topologyKey: kubernetes.io/hostname
上面配置表达的意思是:新Pod必须要与拥有标签nodeenv=pro的pod不在同一Node上c;运行测试一下。
# 创建pod
[root@k8s-m-01 ~]# kubectl create -f pod-podantiaffinity-required.yaml
pod/pod-podantiaffinity-required created
# 查看pod
# 发现调度到了k8s-n-02上
[root@k8s-m-01 ~]# kubectl get pods pod-podantiaffinity-required -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE ..
pod-podantiaffinity-required 1/1 Running 0 30s 10.244.1.96 k8s-n-02 ..
前面的调度方式都是站在Pod的角度上c;通过在Pod上添加属性c;来确定Pod是否要调度到指定的Node上c;其实我们也可以站在Node的角度上c;通过在Node上添加**污点**属性c;来决定是否允许Pod调度过来。
Node被设置上污点之后就和Pod之间存在了一种相斥的关系c;进而拒绝Pod调度进来c;甚至可以将已经存在的Pod驱逐出去。
污点的格式为:key=value:effect
, key和value是污点的标签c;effect描述污点的作用c;支持如下三个选项:
使用kubectl设置和去除污点的命令示例如下:
# 1、设置污点
kubectl taint nodes k8s-n-01 key=value:effect
# 2、去除污点
kubectl taint nodes k8s-n-01 key:effect-
# 3、去除所有污点
kubectl taint nodes k8s-n-01 key-
接下来c;演示下污点的效果:
tag=heima:PreferNoschedule
;然后创建pod1( pod1 可以 )tag=heima:Noschedule
;然后创建pod2( pod1 正常 pod2 失败 )tag=heima:NoExecute
;然后创建pod3 ( 3个pod都失败 )# 1、为k8s-n-01设置污点(PreferNoschedulE)
[root@k8s-m-01 ~]# kubectl taint nodes k8s-n-01 tag=heima:PreferNoschedule
# 2、创建pod1
[root@k8s-m-01 ~]# kubectl run taint1 --image=nginx:1.17.1 -n dev
[root@k8s-m-01 ~]# kubectl get pods -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE
taint1-7665f7fd85-574h4 1/1 Running 0 2m24s 10.244.1.59 k8s-n-01
# 3、为k8s-n-01设置污点(取消PreferNoschedulec;设置NoschedulE)
[root@k8s-m-01 ~]# kubectl taint nodes k8s-n-01 tag:PreferNoschedule-
[root@k8s-m-01 ~]# kubectl taint nodes k8s-n-01 tag=heima:Noschedule
# 4、创建pod2
[root@k8s-m-01 ~]# kubectl run taint2 --image=nginx:1.17.1 -n dev
[root@k8s-m-01 ~]# kubectl get pods taint2 -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE
taint1-7665f7fd85-574h4 1/1 Running 0 2m24s 10.244.1.59 k8s-n-01
taint2-544694789-6zmlf 0/1 Pending 0 21s <none> <none>
# 5、为k8s-n-01设置污点(取消Noschedulec;设置NoExecutE)
[root@k8s-m-01 ~]# kubectl taint nodes k8s-n-01 tag:Noschedule-
[root@k8s-m-01 ~]# kubectl taint nodes k8s-n-01 tag=heima:NoExecute
# 6、创建pod3
[root@k8s-m-01 ~]# kubectl run taint3 --image=nginx:1.17.1 -n dev
[root@k8s-m-01 ~]# kubectl get pods -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED
taint1-7665f7fd85-htkmp 0/1 Pending 0 35s <none> <none> <none>
taint2-544694789-bn7wb 0/1 Pending 0 35s <none> <none> <none>
taint3-6d78dbd749-tktkq 0/1 Pending 0 6s <none> <none> <none>
总结:
使用kubeadm搭建的集群c;默认就会给master节点添加一个污点标记,所以pod就不会调度到master节点上.
上面介绍了污点的作用c;我们可以在Node上添加污点用于拒绝pod调度上来c;但是如果就是想将一个pod调度到一个有污点的node上去c;这时候应该怎么做呢?这就要使用到容忍。
下面先通过一个案例看下效果:
apiVersion: v1
kind: Pod
metadata:
name: pod-toleration
namespace: dev
spec:
containers:
- name: nginx
image: nginx:1.17.1
tolerations: # 添加容忍
- key: "tag" # 要容忍的污点的key
operator: "Equal" # 操作符
value: "heima" # 容忍的污点的value
effect: "NoExecute" # 添加容忍的规则c;这里必须和标记的污点规则相同
# 添加容忍之前的pod
[root@k8s-m-01 ~]# kubectl get pods -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED
pod-toleration 0/1 Pending 0 3s <none> <none> <none>
# 添加容忍之后的pod
[root@k8s-m-01 ~]# kubectl get pods -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED
pod-toleration 1/1 Running 0 3s 10.244.1.62 k8s-n-01 <none>
[root@k8s-m-01 ~]# kubectl explain pod.spec.tolerations
......
FIELDS:
key # 对应着要容忍的污点的键c;空意味着匹配所有的键
value # 对应着要容忍的污点的值
operator # key-value的运算符c;支持Equal和Exists(默认)
effect # 对应污点的effectc;空意味着匹配所有影响
tolerationSeconds # 容忍时间, 当effect为NoExecute时生效c;表示pod在Node上的停留时间
Pod是kubernetes的最小管理单元c;在kubernetes中c;按照pod的创建方式可以将其分为两类:
# 自主式pod:
kubernetes直接创建出来的Podc;这种pod删除后就没有了c;也不会重建
# 控制器创建的pod:
kubernetes通过控制器创建的podc;这种pod删除了之后还会自动重建
什么是Pod控制器
Pod控制器是管理pod的中间层c;使用Pod控制器之后c;只需要告诉Pod控制器c;想要多少个什么样的Pod就可以了c;它会创建出满足条件的Pod并确保每一个Pod资源处于用户期望的目标状态。如果Pod资源在运行中出现故障c;它会基于指定策略重新编排Pod。
在kubernetes中c;有很多类型的pod控制器c;每种都有自己的适合的场景c;常见的有下面这些:
# 1、ReplicationController:
比较原始的pod控制器c;已经被废弃c;由ReplicaSet替代
# 2、ReplicaSet:
保证副本数量一直维持在期望值c;并支持pod数量扩缩容c;镜像版本升级
# 3、Deployment:
通过控制ReplicaSet来控制Podc;并支持滚动升级、回退版本
# 4、Horizontal Pod Autoscaler:
可以根据集群负载自动水平调整Pod的数量c;实现削峰填谷
# 5、DaemonSet:
在集群中的指定Node上运行且仅运行一个副本c;一般用于守护进程类的任务
# 6、Job:
它创建出来的pod只要完成任务就立即退出c;不需要重启或重建c;用于执行一次性任务
# 7、Cronjob:
它创建的Pod负责周期性任务控制c;不需要持续后台运行
# 8、StatefulSet:
管理有状态应用
ReplicaSet的主要作用是保证一定数量的pod正常运行c;它会持续监听这些Pod的运行状态c;一旦Pod发生故障c;就会重启或重建。同时它还支持对pod数量的扩缩容和镜像版本的升降级。
ReplicaSet的资源清单文件:
apiVersion: apps/v1 # 版本号
kind: ReplicaSet # 类型
metadata: # 元数据
name: # rs名称
namespace: # 所属命名空间
labels: #标签
controller: rs
spec: # 详情描述
replicas: 3 # 副本数量
SELEctor: # 选择器c;通过它指定该控制器管理哪些pod
matchLabels: # Labels匹配规则
app: nginx-pod
matchExpressions: # Expressions匹配规则
- {key: app, operator: In, values: [nginx-pod]}
template: # 模板c;当副本数量不足时c;会根据下面的模板创建pod副本
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
在这里面c;需要新了解的配置项就是spec
下面几个选项:
创建pc-replicaset.yaml文件c;内容如下:
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: pc-replicaset
namespace: dev
spec:
replicas: 3
SELEctor:
matchLabels:
app: nginx-pod
template:
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx
# 1、创建rs
[root@k8s-m-01 ~]# kubectl create -f pc-replicaset.yaml
replicaset.apps/pc-replicaset created
# 2、查看rs
# DESIRED:期望副本数量
# CURRENT:当前副本数量
# READY:已经准备好提供服务的副本数量
[root@k8s-m-01 ~]# kubectl get rs pc-replicaset -n dev -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
pc-replicaset 3 3 3 22s nginx nginx app=nginx-pod
# 查看当前控制器创建出来的pod
# 这里发现控制器创建出来的pod的名称是在控制器名称后面拼接了-xxxxx随机码
[root@k8s-m-01 ~]# kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
pc-replicaset-6vmvt 1/1 Running 0 54s
pc-replicaset-fmb8f 1/1 Running 0 54s
pc-replicaset-snrk2 1/1 Running 0 54s
# 1、编辑rs的副本数量c;修改spec:replicas: 6即可
[root@k8s-m-01 ~]# kubectl edit rs pc-replicaset -n dev
replicaset.apps/pc-replicaset edited
# 2、查看pod
[root@k8s-m-01 ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pc-replicaset-6vmvt 1/1 Running 0 114m
pc-replicaset-cftnp 1/1 Running 0 10s
pc-replicaset-fjlm6 1/1 Running 0 10s
pc-replicaset-fmb8f 1/1 Running 0 114m
pc-replicaset-s2whj 1/1 Running 0 10s
pc-replicaset-snrk2 1/1 Running 0 114m
# 当然也可以直接使用命令实现
# 3、使用scale命令实现扩缩容c; 后面--replicas=n直接指定目标数量即可
[root@k8s-m-01 ~]# kubectl scale rs pc-replicaset --replicas=2 -n dev
replicaset.apps/pc-replicaset scaled
# 命令运行完毕c;立即查看c;发现已经有4个开始准备退出了
[root@k8s-m-01 ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pc-replicaset-6vmvt 0/1 TerminaTing 0 118m
pc-replicaset-cftnp 0/1 TerminaTing 0 4m17s
pc-replicaset-fjlm6 0/1 TerminaTing 0 4m17s
pc-replicaset-fmb8f 1/1 Running 0 118m
pc-replicaset-s2whj 0/1 TerminaTing 0 4m17s
pc-replicaset-snrk2 1/1 Running 0 118m
# 4、稍等片刻c;就只剩下2个了
[root@k8s-m-01 ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pc-replicaset-fmb8f 1/1 Running 0 119m
pc-replicaset-snrk2 1/1 Running 0 119m
# 1、编辑rs的容器镜像 - image: nginx:1.17.2
[root@k8s-m-01 ~]# kubectl edit rs pc-replicaset -n dev
replicaset.apps/pc-replicaset edited
# 2、再次查看c;发现镜像版本已经变更了
[root@k8s-m-01 ~]# kubectl get rs -n dev -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES ...
pc-replicaset 2 2 2 140m nginx nginx:1.17.2 ...
# 同样的道理c;也可以使用命令完成这个工作
# kubectl set image rs rs名称 容器=镜像版本 -n namespace
[root@k8s-m-01 ~]# kubectl set image rs pc-replicaset nginx=nginx -n dev
replicaset.apps/pc-replicaset image updated
# 3、再次查看c;发现镜像版本已经变更了
[root@k8s-m-01 ~]# kubectl get rs -n dev -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES ...
pc-replicaset 2 2 2 145m nginx nginx ...
# 1、使用kubectl delete命令会删除此RS以及它管理的Pod
# 在kubernetes删除RS前c;会将RS的replicasclear调整为0c;等待所有的Pod被删除后c;在执行RS对象的删除
[root@k8s-m-01 ~]# kubectl delete rs pc-replicaset -n dev
replicaset.apps "pc-replicaset" deleted
[root@k8s-m-01 ~]# kubectl get pod -n dev -o wide
No resources found in dev namespace.
# 2、如果希望仅仅删除RS对象(保留Pod)c;可以使用kubectl delete命令时添加--cascade=false选项(不推荐)。
[root@k8s-m-01 ~]# kubectl delete rs pc-replicaset -n dev --cascade=false
replicaset.apps "pc-replicaset" deleted
[root@k8s-m-01 ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pc-replicaset-cl82j 1/1 Running 0 75s
pc-replicaset-dslhb 1/1 Running 0 75s
# 3、也可以使用yaml直接删除(推荐)
[root@k8s-m-01 ~]# kubectl delete -f pc-replicaset.yaml
replicaset.apps "pc-replicaset" deleted
# 1、Deployment:一般用来部署长期运行的、无状态的应用
特点:集群之中c;随机部署(每一次请求都不依赖历史数据c;也无数据持久化需求)
精确匹配: # matchLabels
模糊匹配: # matchExpressions
为了更好的解决服务编排的问题c;kubernetes在V1.2版本开始c;引入了Deployment控制器。值得一提的是c;这种控制器并不直接管理podc;而是通过管理ReplicaSet来简介管理Podc;即:Deployment管理ReplicaSetc;ReplicaSet管理Pod。所以Deployment比ReplicaSet功能更加强大。
@H_772_1446@
Deployment主要功能有下面几个:
Deployment的资源清单文件:
apiVersion: apps/v1 # 版本号
kind: Deployment # 类型
metadata: # 元数据
name: # rs名称
namespace: # 所属命名空间
labels: #标签
controller: deploy
spec: # 详情描述
replicas: 3 # 副本数量
revisionHistoryLimit: 3 # 保留历史版本
paused: false # 暂停部署c;默认是false
progressDeadlineseconds: 600 # 部署超时时间(s)c;默认是600
strategy: # 策略
type: Rollingupdate # 滚动更新策略
rollingupdate: # 滚动更新
maxSurge: 30% # 最大额外可以存在的副本数c;可以为百分比c;也可以为整数
maxUnavailable: 30% # 最大不可用状态的 Pod 的最大值c;可以为百分比c;也可以为整数
SELEctor: # 选择器c;通过它指定该控制器管理哪些pod
matchLabels: # Labels匹配规则
app: nginx-pod
matchExpressions: # Expressions匹配规则
- {key: app, operator: In, values: [nginx-pod]}
template: # 模板c;当副本数量不足时c;会根据下面的模板创建pod副本
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
apiVersion: apps/v1
kind: Deployment
metadata:
name: pc-deployment
namespace: dev
spec:
replicas: 3
SELEctor:
matchLabels:
app: nginx-pod
template:
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx
# 1、创建deployment
[root@k8s-m-01 ~]# kubectl create -f pc-deployment.yaml --record=true
deployment.apps/pc-deployment created
# 2、查看deployment
# UP-TO-DATE 最新版本的pod的数量
# AVAILABLE 当前可用的pod的数量
[root@k8s-m-01 ~]# kubectl get deploy pc-deployment -n dev
NAME READY UP-TO-DATE AVAILABLE AGE
pc-deployment 3/3 3 3 15s
# 3、查看rs
# 发现rs的名称是在原来deployment的名字后面添加了一个10位数的随机串
[root@k8s-m-01 ~]# kubectl get rs -n dev
NAME DESIRED CURRENT READY AGE
pc-deployment-6696798b78 3 3 3 23s
# 4、查看pod
[root@k8s-m-01 ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pc-deployment-6696798b78-d2c8n 1/1 Running 0 107s
pc-deployment-6696798b78-smpvp 1/1 Running 0 107s
pc-deployment-6696798b78-wvjd8 1/1 Running 0 107s
# 1、变更副本数量为5个
[root@k8s-m-01 ~]# kubectl scale deploy pc-deployment --replicas=5 -n dev
deployment.apps/pc-deployment scaled
# 2、查看deployment
[root@k8s-m-01 ~]# kubectl get deploy pc-deployment -n dev
NAME READY UP-TO-DATE AVAILABLE AGE
pc-deployment 5/5 5 5 2m
# 3、查看pod
[root@k8s-m-01 ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pc-deployment-6696798b78-d2c8n 1/1 Running 0 4m19s
pc-deployment-6696798b78-jxmdq 1/1 Running 0 94s
pc-deployment-6696798b78-mktqv 1/1 Running 0 93s
pc-deployment-6696798b78-smpvp 1/1 Running 0 4m19s
pc-deployment-6696798b78-wvjd8 1/1 Running 0 4m19s
# 4、编辑deployment的副本数量c;修改spec:replicas: 4即可
[root@k8s-m-01 ~]# kubectl edit deploy pc-deployment -n dev
deployment.apps/pc-deployment edited
# 5、查看pod
[root@k8s-m-01 ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pc-deployment-6696798b78-d2c8n 1/1 Running 0 5m23s
pc-deployment-6696798b78-jxmdq 1/1 Running 0 2m38s
pc-deployment-6696798b78-smpvp 1/1 Running 0 5m23s
pc-deployment-6696798b78-wvjd8 1/1 Running 0 5m23s
deployment支持两种更新策略:重建更新
和滚动更新
,可以通过strategy
指定策略类型,支持两个属性:
strategy:指定新的Pod替换旧的Pod的策略c; 支持两个属性:
type:指定策略类型c;支持两种策略
Recreate:在创建出新的Pod之前会先杀掉所有已存在的Pod
Rollingupdate:滚动更新c;就是杀死一部分c;就启动一部分c;在更新过程中c;存在两个版本Pod
rollingupdate:当type为Rollingupdate时生效c;用于为Rollingupdate设置参数c;支持两个属性:
maxUnavailable:用来指定在升级过程中不可用Pod的最大数量c;默认为25%。
maxSurge: 用来指定在升级过程中可以超过期望的Pod的最大数量c;默认为25%。
spec:
strategy: # 策略
type: Recreate # 重建更新
# 1、变更镜像
[root@k8s-m-01 ~]# kubectl set image deployment pc-deployment nginx=nginx:1.17.2 -n dev
deployment.apps/pc-deployment image updated
# 2、观察升级过程
[root@k8s-m-01 ~]# kubectl get pods -n dev -w
NAME READY STATUS RESTARTS AGE
pc-deployment-5d89bdfbf9-65qcw 1/1 Running 0 31s
pc-deployment-5d89bdfbf9-w5nzv 1/1 Running 0 31s
pc-deployment-5d89bdfbf9-xpt7w 1/1 Running 0 31s
pc-deployment-5d89bdfbf9-xpt7w 1/1 TerminaTing 0 41s
pc-deployment-5d89bdfbf9-65qcw 1/1 TerminaTing 0 41s
pc-deployment-5d89bdfbf9-w5nzv 1/1 TerminaTing 0 41s
pc-deployment-675d469f8b-grn8z 0/1 Pending 0 0s
pc-deployment-675d469f8b-hbl4v 0/1 Pending 0 0s
pc-deployment-675d469f8b-67nz2 0/1 Pending 0 0s
spec:
strategy: # 策略
type: Rollingupdate # 滚动更新策略
rollingupdate:
maxSurge: 25%
maxUnavailable: 25%
# 1、变更镜像
[root@k8s-m-01 ~]# kubectl set image deployment pc-deployment nginx=nginx:1.17.3 -n dev
deployment.apps/pc-deployment image updated
# 2、观察升级过程
[root@k8s-m-01 ~]# kubectl get pods -n dev -w
NAME READY STATUS RESTARTS AGE
pc-deployment-c848d767-8rbzt 1/1 Running 0 31m
pc-deployment-c848d767-h4P68 1/1 Running 0 31m
pc-deployment-c848d767-hlmz4 1/1 Running 0 31m
pc-deployment-c848d767-rrqcn 1/1 Running 0 31m
# 至此c;新版本的pod创建完毕c;就版本的pod销毁完毕
# 中间过程是滚动进行的c;也就是边销毁边创建
镜像更新中rs的变化:
# 查看rs,发现原来的rs的依旧存在c;只是pod数量变为了0c;而后又新产生了一个rsc;pod数量为4
# 其实这就是deployment能够进行版本回退的奥妙所在c;后面会详细解释
[root@k8s-m-01 ~]# kubectl get rs -n dev
NAME DESIRED CURRENT READY AGE
pc-deployment-6696798b78 0 0 0 7m37s
pc-deployment-6696798b11 0 0 0 5m37s
pc-deployment-c848d76789 4 4 4 72s
deployment支持版本升级过程中的暂停、继续功能以及版本回退等诸多功能c;下面具体来看.
kubectl rollout: 版本升级相关功能c;支持下面的选项:
status 显示当前升级状态
history 显示 升级历史记录
pause 暂停版本升级过程
resume 继续已经暂停的版本升级过程
restart 重启版本升级过程
undo 回滚到上一级版本(可以使用–to-revision回滚到指定版本)
# 1、查看当前升级版本的状态
[root@k8s-m-01 ~]# kubectl rollout status deploy pc-deployment -n dev
deployment "pc-deployment" successfully rolled out
# 2、查看升级历史记录
[root@k8s-m-01 ~]# kubectl rollout history deploy pc-deployment -n dev
deployment.apps/pc-deployment
REVISION CHANGE-CAUSE
1 kubectl create --filename=pc-deployment.yaml --record=true
2 kubectl create --filename=pc-deployment.yaml --record=true
3 kubectl create --filename=pc-deployment.yaml --record=true
# 可以发现有三次版本记录c;说明完成过两次升级
# 3、版本回滚
# 这里直接使用--to-revision=1回滚到了1版本c; 如果省略这个选项c;就是回退到上个版本c;就是2版本
[root@k8s-m-01 ~]# kubectl rollout undo deployment pc-deployment --to-revision=1 -n dev
deployment.apps/pc-deployment rolled BACk
# 4、查看发现c;通过nginx镜像版本可以发现到了第一版
[root@k8s-m-01 ~]# kubectl get deploy -n dev -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES
pc-deployment 4/4 4 4 74m nginx nginx
# 查看rsc;发现第一个rs中有4个pod运行c;后面两个版本的rs中pod为运行
# 其实deployment之所以可是实现版本的回滚c;就是通过记录下历史rs来实现的c;
# 一旦想回滚到哪个版本c;只需要将当前版本pod数量降为0c;然后将回滚版本的pod提升为目标数量就可以了
[root@k8s-m-01 ~]# kubectl get rs -n dev
NAME DESIRED CURRENT READY AGE
pc-deployment-6696798b78 4 4 4 78m
pc-deployment-966bf7f44 0 0 0 37m
pc-deployment-c848d767 0 0 0 71m
Deployment控制器支持控制更新过程中的控制c;如“暂停(pausE)”或“继续(resumE)”更新操作。
比如有一批新的Pod资源创建完成后立即暂停更新过程c;此时c;仅存在一部分新版本的应用c;主体部分还是旧的版本。然后c;再筛选一小部分的用户请求路由到新版本的Pod应用c;继续观察能否稳定地按期望的方式运行。确定没问题之后再继续完成余下的Pod资源滚动更新c;否则立即回滚更新操作。这就是所谓的金丝雀发布。
# 1、更新deployment的版本c;并配置暂停deployment
[root@k8s-m-01 ~]# kubectl set image deploy pc-deployment nginx=nginx:1.17.4 -n dev && kubectl rollout pause deployment pc-deployment -n dev
deployment.apps/pc-deployment image updated
deployment.apps/pc-deployment paused
# 2、观察更新状态
[root@k8s-m-01 ~]# kubectl rollout status deploy pc-deployment -n dev
WaiTing for deployment "pc-deployment" rollout to finish: 2 out of 4 new replicas have been updated...
# 监控更新的过程c;可以看到已经新增了一个资源c;但是并未按照预期的状态去删除一个旧的资源c;就是因为使用了pause暂停命令
[root@k8s-m-01 ~]# kubectl get rs -n dev -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES
pc-deployment-5d89bdfbf9 3 3 3 19m nginx nginx
pc-deployment-675d469f8b 0 0 0 14m nginx nginx:1.17.2
pc-deployment-6c9f56fcfb 2 2 2 3m16s nginx nginx:1.17.4
[root@k8s-m-01 ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pc-deployment-5d89bdfbf9-rj8sq 1/1 Running 0 7m33s
pc-deployment-5d89bdfbf9-ttwgg 1/1 Running 0 7m35s
pc-deployment-5d89bdfbf9-v4wvc 1/1 Running 0 7m34s
pc-deployment-6c9f56fcfb-996rt 1/1 Running 0 3m31s
pc-deployment-6c9f56fcfb-j2gtj 1/1 Running 0 3m31s
# 3、确保更新的pod没问题了c;继续更新
[root@k8s-m-01 ~]# kubectl rollout resume deploy pc-deployment -n dev
deployment.apps/pc-deployment resumed
# 4、查看最后的更新情况
[root@k8s-m-01 ~]# kubectl get rs -n dev -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES
pc-deployment-5d89bdfbf9 0 0 0 21m nginx nginx
pc-deployment-675d469f8b 0 0 0 16m nginx nginx:1.17.2
pc-deployment-6c9f56fcfb 4 4 4 5m11s nginx nginx:1.17.4
[root@k8s-m-01 ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pc-deployment-6c9f56fcfb-7bfwh 1/1 Running 0 37s
pc-deployment-6c9f56fcfb-996rt 1/1 Running 0 5m27s
pc-deployment-6c9f56fcfb-j2gtj 1/1 Running 0 5m27s
pc-deployment-6c9f56fcfb-rf84v 1/1 Running 0 37s
删除Deployment
# 删除deploymentc;其下的rs和pod也将被删除
[root@k8s-m-01 ~]# kubectl delete -f pc-deployment.yaml
deployment.apps "pc-deployment" deleted
在前面的课程中c;我们已经可以实现通过手工执行`kubectl scale`命令实现Pod扩容或缩容c;但是这显然不符合Kubernetes的定位目标--自动化、智能化。 Kubernetes期望可以实现通过监测Pod的使用情况c;实现pod数量的自动调整c;于是就产生了Horizontal Pod Autoscaler(HPA)这种控制器。
HPA可以获取每个Pod利用率c;然后和HPA中定义的指标进行对比c;同时计算出需要伸缩的具体值c;最后实现Pod的数量的调整。其实HPA与之前的Deployment一样c;也属于一种Kubernetes资源对象c;它通过追踪分析RC控制的所有目标Pod的负载变化情况c;来确定是否需要针对性地调整目标Pod的副本数c;这是HPA的实现原理。
# 1、安装git
[root@k8s-m-01 ~]# yum install git -y
# 2、获取metrics-server, 注意使用的版本
[root@k8s-m-01 ~]# git clone -b v0.3.6 https://github wangt.cc /kubernetes-incubator/metrics-server
# 修改deployment, 注意修改的是镜像和初始化参数
[root@k8s-m-01 ~]# cd /root/metrics-server/deploy/1.8+/
[root@master 1.8+]# vim metrics-server-deployment.yaml
按图中添加下面选项
hostNetwork: true
image: registry wangt.cc -hangzhou.aliyuncs wangt.cc /google_containers/metrics-server-amd64:v0.3.6
args:
- --kubelet-insecure-tls
- --kubelet-preferred-address-types=InternalIP,Hostname,InternalDNS,ExternalDNS,ExternalIP
# 1、安装metrics-server
[root@master 1.8+]# kubectl apply -f ./
# 2、查看pod运行情况
[root@master 1.8+]# kubectl get pod -n kube-system
metrics-server-6b976979db-2xwbj 1/1 Running 0 90s
# 3、使用kubectl top node 查看资源使用情况
[root@master 1.8+]# kubectl top node
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
master 98m 4% 1067Mi 62%
k8s-n-01 27m 1% 727Mi 42%
k8s-n-02 34m 1% 800Mi 46%
[root@master 1.8+]# kubectl top pod -n kube-system
NAME CPU(cores) MEMORY(bytes)
coredns-6955765f44-7ptsb 3m 9Mi
coredns-6955765f44-vcwr5 3m 8Mi
etcd-master 14m 145Mi
...
# 至此,metrics-server安装完成
为了操作简单,直接使用命令
# 1、创建deployment
[root@master 1.8+]# kubectl run nginx --image=nginx:latest --requests=cpu=100m -n dev
# 2、创建service
[root@master 1.8+]# kubectl expose deployment nginx --type=NodePort --port=80 -n dev
# 3、查看
[root@master 1.8+]# kubectl get deployment,pod,svc -n dev
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx 1/1 1 1 47s
NAME READY STATUS RESTARTS AGE
pod/nginx-7df9756ccc-bh8dr 1/1 Running 0 47s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/nginx NodePort 10.109.57.248 <none> 80:31136/TCP 35s
创建pc-hpa.yaml
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: pc-hpa
namespace: dev
spec:
minReplicas: 1 #最小pod数量
maxReplicas: 10 #最大pod数量
targetCPUUtilizationPercentage: 3 # CPU使用率指标
scaleTargetRef: # 指定要控制的nginx信息
apiVersion: apps/v1
kind: Deployment
name: nginx
# 1、创建hpa
[root@master 1.8+]# kubectl create -f pc-hpa.yaml
horizontalpodautoscaler.autoscaling/pc-hpa created
# 2、查看hpa
[root@master 1.8+]# kubectl get hpa -n dev
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
pc-hpa Deployment/nginx 0%/3% 1 10 1 62s
使用压测工具对service地址192.168.109.100:31136
进行压测c;然后通过控制台查看hpa和pod的变化
hpa变化
[root@k8s-m-01 ~]# kubectl get hpa -n dev -w
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
pc-hpa Deployment/nginx 0%/3% 1 10 1 4m11s
pc-hpa Deployment/nginx 0%/3% 1 10 1 5m19s
pc-hpa Deployment/nginx 22%/3% 1 10 1 6m50s
pc-hpa Deployment/nginx 22%/3% 1 10 4 7m5s
pc-hpa Deployment/nginx 22%/3% 1 10 8 7m21s
pc-hpa Deployment/nginx 6%/3% 1 10 8 7m51s
pc-hpa Deployment/nginx 0%/3% 1 10 8 9m6s
pc-hpa Deployment/nginx 0%/3% 1 10 8 13m
pc-hpa Deployment/nginx 0%/3% 1 10 1 14m
deployment变化
[root@k8s-m-01 ~]# kubectl get deployment -n dev -w
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 1/1 1 1 11m
nginx 1/4 1 1 13m
nginx 1/4 1 1 13m
nginx 1/4 1 1 13m
nginx 1/4 4 1 13m
nginx 1/8 4 1 14m
nginx 1/8 4 1 14m
nginx 1/8 4 1 14m
nginx 1/8 8 1 14m
nginx 2/8 8 2 14m
nginx 3/8 8 3 14m
nginx 4/8 8 4 14m
nginx 5/8 8 5 14m
nginx 6/8 8 6 14m
nginx 7/8 8 7 14m
nginx 8/8 8 8 15m
nginx 8/1 8 8 20m
nginx 8/1 8 8 20m
nginx 1/1 1 1 20m
pod变化
[root@k8s-m-01 ~]# kubectl get pods -n dev -w
NAME READY STATUS RESTARTS AGE
nginx-7df9756ccc-bh8dr 1/1 Running 0 11m
nginx-7df9756ccc-cpgrv 0/1 Pending 0 0s
nginx-7df9756ccc-8zhwk 0/1 Pending 0 0s
nginx-7df9756ccc-rr9bn 0/1 Pending 0 0s
nginx-7df9756ccc-cpgrv 0/1 ContainerCreaTing 0 0s
nginx-7df9756ccc-8zhwk 0/1 ContainerCreaTing 0 0s
nginx-7df9756ccc-rr9bn 0/1 ContainerCreaTing 0 0s
nginx-7df9756ccc-m9gsj 0/1 Pending 0 0s
nginx-7df9756ccc-g56qb 0/1 Pending 0 0s
nginx-7df9756ccc-sl9c6 0/1 Pending 0 0s
nginx-7df9756ccc-fgst7 0/1 Pending 0 0s
nginx-7df9756ccc-g56qb 0/1 ContainerCreaTing 0 0s
nginx-7df9756ccc-m9gsj 0/1 ContainerCreaTing 0 0s
nginx-7df9756ccc-sl9c6 0/1 ContainerCreaTing 0 0s
nginx-7df9756ccc-fgst7 0/1 ContainerCreaTing 0 0s
nginx-7df9756ccc-8zhwk 1/1 Running 0 19s
nginx-7df9756ccc-rr9bn 1/1 Running 0 30s
nginx-7df9756ccc-m9gsj 1/1 Running 0 21s
nginx-7df9756ccc-cpgrv 1/1 Running 0 47s
nginx-7df9756ccc-sl9c6 1/1 Running 0 33s
nginx-7df9756ccc-g56qb 1/1 Running 0 48s
nginx-7df9756ccc-fgst7 1/1 Running 0 66s
nginx-7df9756ccc-fgst7 1/1 TerminaTing 0 6m50s
nginx-7df9756ccc-8zhwk 1/1 TerminaTing 0 7m5s
nginx-7df9756ccc-cpgrv 1/1 TerminaTing 0 7m5s
nginx-7df9756ccc-g56qb 1/1 TerminaTing 0 6m50s
nginx-7df9756ccc-rr9bn 1/1 TerminaTing 0 7m5s
nginx-7df9756ccc-m9gsj 1/1 TerminaTing 0 6m50s
nginx-7df9756ccc-sl9c6 1/1 TerminaTing 0 6m50s
# DaemonSet:每一个节点上部署一个Podc;删除节点自动删除对应的POD(zabbix-agent)
特点:每一台上有且只有一台
DaemonSet类型的控制器可以保证在集群中的每一台(或指定)节点上都运行一个副本。一般适用于日志收集、节点监控等场景。也就是说c;如果一个Pod提供的功能是节点级别的(每个节点都需要且只需要一个)c;那么这类Pod就适合使用DaemonSet类型的控制器创建。
DaemonSet控制器的特点:
下面先来看下DaemonSet的资源清单文件
apiVersion: apps/v1 # 版本号
kind: DaemonSet # 类型
metadata: # 元数据
name: # rs名称
namespace: # 所属命名空间
labels: #标签
controller: daemonset
spec: # 详情描述
revisionHistoryLimit: 3 # 保留历史版本
updateStrategy: # 更新策略
type: Rollingupdate # 滚动更新策略
rollingupdate: # 滚动更新
maxUnavailable: 1 # 最大不可用状态的 Pod 的最大值c;可以为百分比c;也可以为整数
SELEctor: # 选择器c;通过它指定该控制器管理哪些pod
matchLabels: # Labels匹配规则
app: nginx-pod
matchExpressions: # Expressions匹配规则
- {key: app, operator: In, values: [nginx-pod]}
template: # 模板c;当副本数量不足时c;会根据下面的模板创建pod副本
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
创建pc-daemonset.yamlc;内容如下:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: pc-daemonset
namespace: dev
spec:
SELEctor:
matchLabels:
app: nginx-pod
template:
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx
# 1、创建daemonset
[root@k8s-m-01 ~]# kubectl create -f pc-daemonset.yaml
daemonset.apps/pc-daemonset created
# 2、查看daemonset
[root@k8s-m-01 ~]# kubectl get ds -n dev -o wide
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES
pc-daemonset 2 2 2 2 2 24s nginx nginx
# 3、查看pod,发现在每个Node上都运行一个pod
[root@k8s-m-01 ~]# kubectl get pods -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE
pc-daemonset-9bck8 1/1 Running 0 37s 10.244.1.43 k8s-n-01
pc-daemonset-k224w 1/1 Running 0 37s 10.244.2.74 k8s-n-02
# 4、删除daemonset
[root@k8s-m-01 ~]# kubectl delete -f pc-daemonset.yaml
daemonset.apps "pc-daemonset" deleted
# 5、更新
[root@k8s-m-01 k8s]# kubectl edit daemonsets zabbix-agent
- image: zabbix/zabbix-agent:5.2.4-centos
zabbix版本是5.2.4
# 6、回滚
[root@k8s-m-01 k8s]# kubectl rollout undo daemonset zabbix-agent
daemonset.apps/zabbix-agent rolled BACk
# 回滚到指定版本
[root@k8s-m-01 k8s]# kubectl rollout history daemonset zabbix-agent
daemonset.apps/zabbix-agent
REVISION CHANGE-CAUSE
1 <none>
2 <none>
[root@k8s-m-01 k8s]# kubectl rollout undo daemonset zabbix-agent --to-revision=1
# 7、扩展 (删除集群c;重新添加)
[root@k8s-m-01 k8s]# kubectl delete nodes k8s-n-01 # 主节点删除n2从节点
[root@k8s-n-01 ~]# kubeadm reset
[root@k8s-n-01 ~]# rm -rf /etc/kubernetes/*
[root@k8s-m-01 ~]# kubeadm token create --print-join-command # 主节点
从节点拿着token直接执行一下c;就加入集群了
# 不支持弹性扩容c;但是支持资源更新
Jobc;主要用于负责**批量处理(一次要处理指定数量任务)短暂的一次性(每个任务仅运行一次就结束)**任务。Job特点如下:
Job的资源清单文件:apiVersion: batch/v1 # 版本号
kind: Job # 类型
metadata: # 元数据
name: # rs名称
namespace: # 所属命名空间
labels: #标签
controller: job
spec: # 详情描述
completions: 1 # 指定job需要成功运行Pods的次数。默认值: 1
parallelism: 1 # 指定job在任一时刻应该并发运行Pods的数量。默认值: 1
activeDeadlineseconds: 30 # 指定job可运行的时间期限c;超过时间还未结束c;系统将会尝试进行终止。
BACkoffLimit: 6 # 指定job失败后进行重试的次数。默认是6
manualSELEctor: true # 是否可以使用SELEctor选择器选择podc;默认是false
SELEctor: # 选择器c;通过它指定该控制器管理哪些pod
matchLabels: # Labels匹配规则
app: counter-pod
matchExpressions: # Expressions匹配规则
- {key: app, operator: In, values: [counter-pod]}
template: # 模板c;当副本数量不足时c;会根据下面的模板创建pod副本
metadata:
labels:
app: counter-pod
spec:
restartPolicy: Never # 重启策略只能设置为Never或者OnFailure
containers:
- name: counter
image: busybox:1.30
command: ["bin/sh","-c","for i in 9 8 7 6 5 4 3 2 1; do echo $i;sleep 2;done"]
关于重启策略设置的说明:
如果指定为OnFailurec;则job会在pod出现故障时重启容器c;而不是创建podc;failed次数不变
如果指定为Neverc;则job会在pod出现故障时创建新的podc;并且故障pod不会消失c;也不会重启c;failed次数加1
如果指定为Always的话c;就意味着一直重启c;意味着job任务会重复去执行了c;当然不对c;所以不能设置为Always
创建pc-job.yamlc;内容如下:
apiVersion: batch/v1
kind: Job
metadata:
name: pc-job
namespace: dev
spec:
manualSELEctor: true
SELEctor:
matchLabels:
app: counter-pod
template:
metadata:
labels:
app: counter-pod
spec:
restartPolicy: Never
containers:
- name: counter
image: busybox:1.30
command: ["bin/sh","-c","for i in 9 8 7 6 5 4 3 2 1; do echo $i;sleep 3;done"]
# 1、创建job
[root@k8s-m-01 ~]# kubectl create -f pc-job.yaml
job.batch/pc-job created
# 2、查看job
[root@k8s-m-01 ~]# kubectl get job -n dev -o wide -w
NAME COMPLETIONS DURATION AGE CONTAINERS IMAGES SELECTOR
pc-job 0/1 21s 21s counter busybox:1.30 app=counter-pod
pc-job 1/1 31s 79s counter busybox:1.30 app=counter-pod
# 3、通过观察pod状态可以看到c;pod在运行完毕任务后c;就会变成Completed状态
[root@k8s-m-01 ~]# kubectl get pods -n dev -w
NAME READY STATUS RESTARTS AGE
pc-job-rxg96 1/1 Running 0 29s
pc-job-rxg96 0/1 Completed 0 33s
# 接下来c;调整下pod运行的总数量和并行数量 即:在spec下设置下面两个选项
# completions: 6 # 指定job需要成功运行Pods的次数为6
# parallelism: 3 # 指定job并发运行Pods的数量为3
# 然后重新运行jobc;观察效果c;此时会发现c;job会每次运行3个podc;总共执行了6个pod
[root@k8s-m-01 ~]# kubectl get pods -n dev -w
NAME READY STATUS RESTARTS AGE
pc-job-684ft 1/1 Running 0 5s
pc-job-jhj49 1/1 Running 0 5s
pc-job-pfcvh 1/1 Running 0 5s
pc-job-684ft 0/1 Completed 0 11s
pc-job-v7rhr 0/1 Pending 0 0s
pc-job-v7rhr 0/1 Pending 0 0s
pc-job-v7rhr 0/1 ContainerCreaTing 0 0s
pc-job-jhj49 0/1 Completed 0 11s
pc-job-5vg2j 0/1 Completed 0 12s
# 删除job
[root@k8s-m-01 ~]# kubectl delete -f pc-job.yaml
job.batch "pc-job" deleted
CronJob控制器以Job控制器资源为其管控对象c;并借助它管理pod资源对象c;Job控制器定义的作业任务在其控制器资源创建之后便会立即执行c;但CronJob可以以类似于Linux操作系统的周期性任务作业计划的方式控制其运行时间点及重复运行的方式。也就是说c;CronJob可以在特定的时间点(反复的)去运行job任务。
apiVersion: batch/v1beta1 # 版本号
kind: CronJob # 类型
metadata: # 元数据
name: # rs名称
namespace: # 所属命名空间
labels: #标签
controller: cronjob
spec: # 详情描述
schedule: # cron格式的作业调度运行时间点,用于控制任务在什么时间执行
concurrencyPolicy: # 并发执行策略c;用于定义前一次作业运行尚未完成时是否以及如何运行后一次的作业
failedJobHistoryLimit: # 为失败的任务执行保留的历史记录数c;默认为1
successfulJobHistoryLimit: # 为成功的任务执行保留的历史记录数c;默认为3
starTingDeadlineseconds: # 启动作业错误的超时时长
jobTemplate: # job控制器模板c;用于为cronjob控制器生成job对象;下面其实就是job的定义
metadata:
spec:
completions: 1
parallelism: 1
activeDeadlineseconds: 30
BACkoffLimit: 6
manualSELEctor: true
SELEctor:
matchLabels:
app: counter-pod
matchExpressions: 规则
- {key: app, operator: In, values: [counter-pod]}
template:
metadata:
labels:
app: counter-pod
spec:
restartPolicy: Never
containers:
- name: counter
image: busybox:1.30
command: ["bin/sh","-c","for i in 9 8 7 6 5 4 3 2 1; do echo $i;sleep 20;done"]
# schedule: cron表达式c;用于指定任务的执行时间
*/1 * * * *
<分钟> <小时> <日> <月份> <星期>
分钟 值从 0 到 59.
小时 值从 0 到 23.
日 值从 1 到 31.
月 值从 1 到 12.
星期 值从 0 到 6, 0 代表星期日
多个时间可以用逗号隔开; 范围可以用连字符给出;*可以作为通配符; /表示每...
# concurrencyPolicy:
Allow: 允许Jobs并发运行(默认)
Forbid: 禁止并发运行c;如果上一次运行尚未完成c;则跳过下一次运行
replace: 替换c;取消当前正在运行的作业并用新作业替换它
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: pc-cronjob
namespace: dev
labels:
controller: cronjob
spec:
schedule: "*/1 * * * *"
jobTemplate:
metadata:
spec:
template:
spec:
restartPolicy: Never
containers:
- name: counter
image: busybox:1.30
command: ["bin/sh","-c","for i in 9 8 7 6 5 4 3 2 1; do echo $i;sleep 3;done"]
# 1、创建cronjob
[root@k8s-m-01 ~]# kubectl create -f pc-cronjob.yaml
cronjob.batch/pc-cronjob created
# 2、查看cronjob
[root@k8s-m-01 ~]# kubectl get cronjobs -n dev
NAME scheDULE SUSPEND ACTIVE LAST scheDULE AGE
pc-cronjob */1 * * * * false 0 <none> 6s
# 3、查看job
[root@k8s-m-01 ~]# kubectl get jobs -n dev
NAME COMPLETIONS DURATION AGE
pc-cronjob-1592587800 1/1 28s 3m26s
pc-cronjob-1592587860 1/1 28s 2m26s
pc-cronjob-1592587920 1/1 28s 86s
# 4、查看pod
[root@k8s-m-01 ~]# kubectl get pods -n dev
pc-cronjob-1592587800-x4tsm 0/1 Completed 0 2m24s
pc-cronjob-1592587860-r5gv4 0/1 Completed 0 84s
pc-cronjob-1592587920-9dxxq 1/1 Running 0 24s
# 5、删除cronjob
[root@k8s-m-01 ~]# kubectl delete -f pc-cronjob.yaml
cronjob.batch "pc-cronjob" deleted
以上是大佬教程为你收集整理的linux12k8s --> 06Pod详解全部内容,希望文章能够帮你解决linux12k8s --> 06Pod详解所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。