linux云计算 |【第五阶段】cloud-爱代码爱编程
主要内容:
在kubernetes平台上理解掌握各种控制器的用法:掌握kubectl管理命令、掌握POD原理、掌握集群调度的规则、熟悉控制器资源文件;
一、kubectl 常用命令
Kubectl是用于控制Kubernetes集群的命令行工具;
- - 格式:kubectl [command] [TYPE] [NAME] [flags]
Command:子命令,如create、get、describe、delete;
TYPE:资源类型,可以表示为单数,复数或缩写形式;
Name:资源的名称,如果省略,则显示所有资源信息;
Flags:指定可选标志,或附加的参数;
1、Kubectl基础命令
命令格式 | 命令说明 |
kubectl run 资源名称 -参数 --image=镜像名称:标签 | 创建资源对象,常用参数-i交互,-t终端 |
kubectl exec -it 容器id 执行的命令 | 同 docker exec 指令,进入容器内 |
kubectl attach 容器id | 同 docker attach 指令,连接容器 |
kubectl get 查询资源 [可选参数-o wide 显示主机信息] [可选参数-o yaml 显示YAML信息] | 常用查询资源 node | deployment | pod | namespace |
kubectl describe 资源类型 资源名称 | 查询资源的详细信息 |
kubectl logs 容器id | 查看容器控制台的标准输出(正常显示为空) |
kubectl delete 资源类型 资源名称 | 删除指定的资源 |
kubectl create | apply | delete -f 资源文件 | 执行指定的资源文件 |
示例1:Kubectl get 查询资源
常用资源类型:node | deployment | pod | namespace
1)查询node资源
- 格式:kubectl get node [节点主机名] //查询节点状态
- 格式:kubectl get node -o wide [节点主机名] //查询节点状态和显示主机信息
- 格式:kubectl get node -o yaml [节点主机名] //查询节点状态和显示YAML信息
例如:查看集群的节点状态
[root@master ~]# kubectl get node
NAME STATUS ROLES AGE VERSION
master Ready master 21h v1.17.6
node-0001 Ready <none> 17h v1.17.6
node-0002 Ready <none> 17h v1.17.6
node-0003 Ready <none> 17h v1.17.6
例如:查看集群的节点状态和显示主机信息
[root@master ~]# kubectl get node -o wide master
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
master Ready master 45h v1.17.6 192.168.1.21 <none> CentOS Linux 7 (Core) 3.10.0-1160.15.2.el7.x86_64 docker://18.6.3
例如:查询节点状态和显示YAML信息
[root@master ~]# kubectl get node -o yaml
2)查询pod资源
- 格式:kubectl get pod //查询pod容器资源
- 格式:kubectl get namespace //查询系统命名空间
补充:系统的命名空间
① default,默认的命名空间,不声明命名空间的POD默认保存在default;
② kube-node-lease,为高可用提供心跳监视的命名空间;
③ kube-public,公共数据,所有用户都可以读取;
④ kube-system,系统服务对象所使用的命名空间;
例如:查询Pod容器资源
[root@master ~]# kubectl get pod
No resources found in default namespace. //一般查看的是默认命名空间内容
[root@master ~]# kubectl get namespaces //查看所有的命名空间
NAME STATUS AGE
default Active 21h
kube-node-lease Active 21h
kube-public Active 21h
kube-system Active 21h
由于默认的命名空间没有Pod容器资源,所以在kube-system系统命名空间查询;
[root@master ~]# kubectl -n kube-system get pod //[-n]指定命名空间查询Pod容器资源
NAME READY STATUS RESTARTS AGE
coredns-f6bfd8d46-b5lkt 1/1 Running 0 21h
coredns-f6bfd8d46-h4c2v 1/1 Running 0 21h
etcd-master 1/1 Running 0 21h
kube-apiserver-master 1/1 Running 0 21h
kube-controller-manager-master 1/1 Running 0 21h
kube-flannel-ds-amd64-kcm7p 1/1 Running 0 16h
kube-flannel-ds-amd64-qmbcq 1/1 Running 0 16h
kube-flannel-ds-amd64-qst8m 1/1 Running 1 16h
kube-flannel-ds-amd64-rq8qb 1/1 Running 0 16h
kube-proxy-56dh5 1/1 Running 1 17h
kube-proxy-jwc9b 1/1 Running 1 21h
kube-proxy-nzchw 1/1 Running 1 17h
kube-proxy-sb588 1/1 Running 1 17h
kube-scheduler-master 1/1 Running 0 21h
解释:
- NAME表示POD资源的容器名;
- READY表示当前就绪状态(m/n,n表示需要几个,m表示当前运行几个);
- STATUS表示当前容器的状态;
- RESTARTS表示重启次数,重启次数阈值过高,需要排查是否有问题;(当容器有控制器,控制器会在容器死亡时依据策略对容器进行重启)
- AGE表示启动服务容器运行的时间;
3)查询deployment资源控制器
- 格式:kubectl get deployment.apps //查询资源控制器
[root@master ~]# kubectl -n kube-system get deployments.apps //查询资源控制器名称
NAME READY UP-TO-DATE AVAILABLE AGE
coredns 2/2 2 2 46h
示例2:常用排错的三个命令(get、describe、logs)
排错流程:Kubernetes排错比较困难,需要了解整个集群的相关配置信息,一般排错是综合利用get、describe、logs来完成;
① kubectl get(查询POD容器资源,容器的STATUS状态信息)
② kubectl describe(查询资源的详细信息,根据events事件信息排错)
③ kubectl logs(查询容器终端信息-日志)
- 格式:kubectl describe 资源类型 资源名称 //查看资源的详细信息(资源名称即容器名)
- 格式:kubectl logs 资源名称 //查看console 终端的输出信息
例如:kube-flannel容器服务启动异常,报错:ImagePullBackOff
① 通过get查询POD资源容器,STATUS状态为ImagePullBackOff,镜像下载失败
[root@master~]# kubectl -n kube-system get pod
② 通过describe查询POD资源容器的详细信息(找到events事件信息)
[root@master ~]# kubectl -n kube-system describe pod kube-flannel-ds-amd64-5xqms
根据events事件,发现192.168.1.100:5000/flannel:v0.12.0-adm64 not found,未找到镜像;
③ 通过kubectl logs查看console终端的输出信息(为空是正常现象,表示没有日志输出)
[root@master ~]# kubectl logs kube-flannel-ds-amd64-5xqms
Error from server (NotFound): pods "kube-flannel-ds-amd64-5xqms" not found
④ 根据输出信息,找到错误原因并修改;
[root@master ~]# vim flannel/kube-flannel.yml
image: 192.168.1.100:5000/flannel:v0.12.0-amd64 //修改后
⑤ 重新执行指定的资源文件
[root@master ~]# kubectl delete -f flannel/kube-flannel.yml //删除资源文件
[root@master ~]# kubectl apply -f flannel/kube-flannel.yml //重新执行资源文件
验证效果
[root@master ~]# kubectl delete -f flannel/kube-flannel.yml //删除资源文件
[root@master ~]# kubectl apply -f flannel/kube-flannel.yml //重新执行资源文件
二、Kubect容器管理
1、POD与控制器
K8S定位不是管理单个容器的管理系统,而是容器集群管理系统
- Deployment资源控制器,为RS提供滚动更新;
- ReplicaSet二级资源控制器(RS),负责创建、管理POD,可以扩容与缩容;
- POD最小的管理单元,负责启动和运行容器;
整个架构的目的是由ReplicaSet二级资源控制器创建若干个容器并组成一个集群,再由Deployment资源控制器负责管理RS;实现最终的自动维护和自动管理;
2、POD概述及用途
POD是Kubernetes中最小的管理元素或最基本的部署调度单元;可以包含1个或多个container容器,逻辑上表示某种应用的一个实例。可以理解成多个Linux命名空间的联合
同一个Pod共享进程(PID)
同一个Pod共享网络IP及权限(NETWORK)
同一个Pod共享IPC通信信号(IPC)
同一个Pod共享主机名称(UTS)
POD 具体的创建过程:
① 客户端提交创建请求,可以通过API Server的Restful API,也可以使用kubectl命令行工具。支持的数据类型包括JSON和YAML。
② API Server处理用户请求,存储Pod数据到etcd键值数据库。
③ Scheduler调度器通过API Server查看未绑定的Pod。尝试为Pod分配主机。
- 过滤主机 (调度预选):调度器用一组规则过滤掉不符合要求的主机。比如Pod指定了所需要的资源量,那么可用资源比Pod需要的资源量少的主机会被过滤掉。
- 主机打分 (调度优选):对第一步筛选出的符合要求的主机进行打分,在主机打分阶段,调度器会考虑一些整体优化策略,比如把容一个Replication Controller的副本分布到不同的主机上,使用最低负载的主机等。
- 选择主机:选择打分最高的主机,进行Pinding操作,结果存储到etcd中。
④ kubelet根据调度结果执行Pod创建操作: 绑定成功后,scheduler会调用APIServer的API在etcd中创建一个boundpod对象,描述在一个工作节点上绑定运行的所有pod信息。运行在每个工作节点上的kubelet也会定期与etcd同步boundpod信息,一旦发现应该在该工作节点上运行的boundpod对象没有更新,则调用Docker API创建并启动pod内的容器。
例如:kubernetes Pod资源对象创建的工作流
第一步:用户使用kubectl工具向Api Server发起一个create pod请求;
第二步:Api Server接收到pod创建请求后,不会去直接创建pod,而是生成一个包含创建信息的yaml。
第三步:Api Server将刚才的yaml信息写入etcd数据库。到此为止仅仅是在etcd中添加了一条记录, 还没有任何的实质性进展。
第四步:Scheduler查看k8s api,类似于通知机制。首先判断:pod.spec.Node == null?若为null,表示这个Pod请求是新来的,需要创建;因此先进行调度计算,找到最“闲”的node节点。然后将信息在etcd数据库中更新分配结果:pod.spec.Node = nodeA (设置一个具体的节点),同样上述操作的各种信息也要写到etcd数据库中。
第五步:kubelet 通过监测etcd数据库(即不停地看etcd中的记录),发现api server 中有了个新的Node;如果这条记录中的Node与自己的编号相同(即这个Pod由scheduler分配给自己了);则调用node中的docker api,创建container。
POD 生命周期:
Pod对象自从其创建开始至其终止退出的时间范围称为其生命周期。在这段时间中,Pod会处于多种不同的状态,并执行一些操作,这些操作是否执行则取决于Pod的定义;其中操作包括:
① 创建主容器(main container),为必须的操作;
② 容器启动后钩子(post start hook)
③ 容器的存活性探针(liveness probe),负责监测容器存活状态;
④ 容器的就绪性探针(readiness probe),负责检查服务是否就绪,就绪后才会对服务开放
⑤ 容器的终止前钩子(pre stop hook)
POD phase相位:
Pod的STATUS字段是一个PodStatus的对象,Pod对象总是应该处于其生命进程中以下几个相位(phase)之一:
① Pending: 容器创建过程中,还尚未开始调度到某台机器上。如果没有符合条件的主机,就会一直处于 Pending 状态;
② Running: 所有容器都已经被kubelet创建完成;
③ Succeeded:所有容器都已经成功终止了并不会被重启,比如cronjob一段时间就结束了,需要反馈任务执行的结果,而不会被重启;
④ Failed:pod中的container异常退出,退出是非0状态(echo $?)
⑤ Unknown:未知、无法正常获取Pod对象的状态信息,比如pod所在的机器无法连接
POD 特点:
- Pod的生命周期是短暂的,用后即焚的实体,注意:重启Pod中的容器跟重启Pod不是一回事,Pod只提供容器的运行环境并保持容器的运行状态,重启容器不会造成Pod重启;
- Pod不会自愈,如果Pod运行的Node故障,或者是调度器本身故障,这个Pod就会被删除;
- 控制器(Deployment/RC/RS)可以创建和管理多个Pod,提供副本管理、滚动升级和集群级别的自愈能力。
3、使用kubectl run创建容器
- 格式:kubectl run 资源名称 -i -t --image=私有仓库镜像名称:标签
例如:创建一个资源名称叫testos的容器
[root@master ~]# kubectl run testos -it --image=192.168.1.100:5000/myos:v1804
[root@testos-6d7c98965-89cz4 /]# ifconfig
[root@master ~]# kubectl get deployments.apps //查询deployment资源管理
NAME READY UP-TO-DATE AVAILABLE AGE
testos 1/1 1 1 128m
[root@master ~]# kubectl get replicasets.apps //查询RS资源管理器
NAME DESIRED CURRENT READY AGE
testos-6d7c98965 1 1 1 128m
[root@master ~]# kubectl get pod //查询Pod资源的容器信息
NAME READY STATUS RESTARTS AGE
testos-6d7c98965-kzqhb 1/1 Running 0 25s
[root@master ~]# kubectl get pod -o wide //查询Pod资源信息和显示主机名信息
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
testos-6d7c98965-kzqhb 1/1 Running 0 36s 10.244.3.10 node-0003 <none> <none>
4、使用Kubectl exec进入正在运行的容器
- 格式:kubectl exec -it 容器id [--] 执行的命令
[root@master ~]# kubectl exec -it testos-6d7c98965-kzqhb /bin/bash
[root@testos-6d7c98965-kzqhb /]#
补充:-- 选项终止符,结束某一个参数的选项,避免混淆
5、使用Kubectl attach进入正在运行的容器
- 格式:kubectl attach -it 容器id
[root@master ~]# kubectl attach -it testos-6d7c98965-kzqhb
[root@testos-6d7c98965-kzqhb /]#
6、使用Kubectl delete删除资源
- 格式:kubectl delete 资源类型 资源名称
[root@master ~]# kubectl delete pod testos-6d7c98965-kzqhb //删除POD资源的容器
pod "testos-6d7c98965-kzqhb" deleted
[root@master ~]# kubectl get pod //直接删除POD会自动重建
NAME READY STATUS RESTARTS AGE
testos-6d7c98965-rk2pd 1/1 Running 0 45s
补充1:因K8S的设计是基于生产环境下的,当删除一个应用时,不会立即删除,而是检测是否还有其它用户或应用正在连接,当连接超时或没有连接,再进行删除,提升用户体验;所以在删除资源时,需要等待检测及删除时间;
补充2:在创建完容器后会形成一个有控制器的架构(deploy - rs - pod),当删除pod时,并没有通知deploy控制器,控制器的生存探针会检测到pod已死亡,并重新创建Pod,体现了架构的高可用属性。若要删除某一个Pod,只能将其架构上层的deploy控制器删除;
[root@master ~]# kubectl delete deployments.apps testos //删除deploy资源控制器
deployment.apps "testos" deleted
[root@master ~]# kubectl get deployments.apps
No resources found in default namespace.
[root@master ~]# kubectl get pod
No resources found in default namespace.
注意:不能直接对ReplicaSets二级资源控制器进行删除,否则导致架构上下连接紊乱;
在K8S中,对于资源的管理只有apply应用和delete删除,没有start、stop、restart功能;
三、K8S资源对象管理
1、资源文件
Kubernetes通过RC/RS管理POD,在RC控制器中定义了如何启动POD、如何运行、启动几个副本等功能,如果创建的文件使用YAML的语法格式描述以上信息,可以简单的将这个文件作为资源对象文件;
用途:可以创建、删除、管理资源对象;很多高级的复杂功能靠简单的命令方式无法实现,这些都需要使用资源文件描述;
- 格式:kubectl create | apply | delete -f 资源文件
解释:
Create //创建资源对象
Apply //声明更新资源对象
Delete //删除资源对象
POD资源文件模板:
通过执行命令:kubectl explain deployment 查看资源控制器版本或官网查看手册;
示例:编写Pod资源文件(镜像myos:v1804)
[root@master ~]# vim mypod.yaml
--- //资源定义的起始标志
kind: Pod //当前创建的资源类型(Pod,注意大小写字母)
apiVersion: v1 //当前资源类型的版本(注意apiVersion的大写字母)
metadata: //当前资源的元数据(即基本信息,如名字、标签等)
name: mypod //当前资源的名称(mypod)
spec: //当前资源的详细定义
containers: //容器定义(Pod负责管理创建容器)
- name: mylinux //容器名称(多容器在一个Pod中,名称不能重复)
image: 192.168.1.100:5000/myos:v1804 //启动容器的镜像地址
stdin: true //相当于-i参数,分配标准输出
tty: true //相当于-t参数,分配终端
[root@master ~]# kubectl apply -f mypod.yaml //执行资源文件
pod/mypod created
[root@master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
mypod 1/1 Running 0 5s
# 验证效果
[root@master ~]# kubectl exec -it mypod /bin/bash //进入容器,容器名为mypod
[root@mypod /]#
[root@master ~]# kubectl delete pod mypod
pod "mypod" deleted
[root@master ~]# kubectl get pod
No resources found in default namespace.
补充:通过编写的Pod资源文件创建的容器,是没有deploy控制器。所以在进行删除容器操作后,是直接删除不会重建;
补充:而控制器要在众多容器中找到对应管理的容器,需通过定义标签的策略方式实现;
为了建立控制器和Pod间的关联,Kubernetes先给每个Pod打上一个标签(Label),然后再给相应的位置定义标签选择器(Label Selector)
DEPLOYMENT资源文件模板:
补充:资源文件的容器定义中,添加restartPolicy: Always,容器死亡策略;
容器死亡策略有3种:
① Always,当容器死亡,控制器就会重启(默认策略)
② Onfailure,判断容器启动状态是否正常,非0则重启;
③ Nerver,当容器死亡,也不重启;
示例:编写Deployment资源文件(部署Apache容器,镜像myos:httpd)
[root@master ~]# vim myapache.yaml
--- //资源定义起始标志
kind: Deployment //创建资源的类型(Deployment控制器,注意大小写)
apiVersion: apps/v1 //控制器资源类型的版本
metadata: //控制器资源的元数据
name: myapache //控制器资源的名称(myapache)
spec: //控制器资源的详细定义
selector: //声明资源匹配选择器(主要确定资源的方式)
matchLabels: //资源方式:匹配标签
myapp: httpd //为服务的后端选择标签(具体匹配的标签,与labels要一致)
replicas: 1 //定义POD副本数量
template: //POD资源模板定义
metadata: //POD资源的元数据
labels: //声明定义标签
myapp: httpd //标签名(与matchLabels要一致)(键值对的方式)
spec: //容器的详细定义
containers: //容器定义
- name: webcluster //容器名称
image: 192.168.1.100:5000/myos:httpd //启动容器的镜像地址
stdin: false //标准输入,默认false(服务容器中可省略stdin)
tty: false //终端,默认false(服务容器中可省略tty)
ports: //服务端口定义
- protocol: TCP //服务使用的协议
containerPort: 80 //容器监听的端口号
restartPolicy: Always //容器的死亡策略
[root@master ~]# kubectl apply -f myapache.yaml
deployment.apps/myapache created
[root@master ~]# kubectl get pod //查看Pod资源信息(已有控制器myapache)
NAME READY STATUS RESTARTS AGE
myapache-7d689bf8f-7txbf 1/1 Running 0 41s
[root@master ~]# kubectl get replicasets.apps //查看RS资源控制器信息
NAME DESIRED CURRENT READY AGE
myapache-7d689bf8f 1 1 1 72s
[root@master ~]# kubectl get deployments.apps //查看Deploy资源控制器信息
NAME READY UP-TO-DATE AVAILABLE AGE
myapache 1/1 1 1 95s
# 验证效果
[root@master ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
myapache-7d689bf8f-7txbf 1/1 Running 0 2m31s 10.244.2.8 node-0002 <none> <none>
[root@master ~]# curl http://10.244.2.8
this is apache
补充:查询资源对象
资源对象文件一般由用户根据修改编写,一般资源对象文件格式包含json、yaml;
- 格式:kubectl get 资源类型 资源名称 -o 格式
例如:查看deployments
[root@master ~]# kubectl get deployments.apps -o yaml
四、K8S集群管理
1、集群扩容
replicas决定了集群POD的数量;(资源文件中控制器的spec详细定义)
例如:创建一个单节点的web容器,使用 kubectl apply -f myapache.yml
使用scale命令,在集群运行的过程中,动态调整集群的POD数量(扩容与缩容)
- 格式:kubectl scale deployment 资源控制器名称 --replicas=数量
集群中的POD里的容器是由RS资源控制器创建,而RS资源控制器由Deployment控制器创建及管理;当需要更多的POD时,只需要下发指令给Deployment控制器即可自动完成创建和管理;
示例:扩容与缩容
① 使用kubectl scale进行扩容
[root@master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
myapache-7d689bf8f-7txbf 1/1 Running 0 84m
[root@master ~]# kubectl scale deployment myapache --replicas=3
deployment.apps/myapache scaled
[root@master ~]# kubectl get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
myapache 3/3 3 3 85m
[root@master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
myapache-7d689bf8f-65v97 1/1 Running 0 43s
myapache-7d689bf8f-7txbf 1/1 Running 0 85m
myapache-7d689bf8f-knm5g 1/1 Running 0 43s
[root@master ~]# kubectl get pod -o wide
补充:为POD分配的Node主机是由Scheduler进行调度分配;
# 测试效果
[root@master ~]# curl http://10.244.1.6
this is apache
[root@master ~]# curl http://10.244.2.8
this is apache
[root@master ~]# curl http://10.244.3.14
this is apache
② 使用kubectl scale进行缩容
[root@master ~]# kubectl scale deployment myapache --replicas=1
deployment.apps/myapache scaled
[root@master ~]# kubectl get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
myapache 1/1 1 1 94m
[root@master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
myapache-7d689bf8f-7txbf 1/1 Running 0 94m
2、集群更新与回滚
查询控制器更新规则
解释说明:
- deploy.spec.revisionHistoryLimit 保留历史保本数量(在更新版本时需要)
- deployment.spec.strategy更新策略,支持两种更新方式:
① Recrete 重建式更新(删一个建一个,效率较低)
② RollingUpdate 滚动式更新,根据maxSurge阈值,提前创建另个RS并更新POD资源,更新期间POD最多不能超过25%;
使用edit命令修改服务配置,即修改YAML资源对象文件(即使生效)
- 格式:kubectl edit deployment 资源控制器名称
使用rollout histroy查看历史版本
- 格式:kubectl rollout history deployment资源控制器名称
使用rollout undo 完成版本回滚操作
- 格式:kubectl rollout history deployment资源控制器名称 --to-revison=版本序号
示例:集群更新与回滚
① POD资源的更新
[root@master ~]# kubectl scale deployment myapache --replicas=2
deployment.apps/myapache scaled
[root@master ~]# kubectl get pod -o wide
[root@master ~]# curl 10.244.1.7
this is apache
[root@master ~]# curl 10.244.2.8
this is apache
[root@master ~]# kubectl rollout history deployment myapache //查看历史版本
deployment.apps/myapache
REVISION CHANGE-CAUSE
1 <none>
[root@master ~]# kubectl edit deployments.apps myapache //修改服务配置
deployment.apps/myapache edited
补充:修改容器定义部分中的镜像,将apache替换成nginx(更新WEB版本)
containers:
- image: 192.168.1.100:5000/myos:nginx
[root@master ~]# kubectl get pod -o wide
补充:通过RollingUpdate 滚动式更新,IP地址及Node地址已重新调度分配;
[root@master ~]# curl 10.244.2.9
this is nginx
[root@master ~]# curl 10.244.3.15
this is nginx
[root@master ~]# kubectl rollout history deployment myapache
deployment.apps/myapache
REVISION CHANGE-CAUSE
1 <none>
2 <none>
② POD资源的回滚
[root@master ~]# kubectl rollout history deployment myapache
deployment.apps/myapache
REVISION CHANGE-CAUSE
1 <none>
2 <none>
[root@master ~]# kubectl rollout undo deployment myapache --to-revision=1
deployment.apps/myapache rolled back
[root@master ~]# kubectl rollout history deployment myapache
deployment.apps/myapache
REVISION CHANGE-CAUSE
2 <none>
3 <none>
[root@master ~]# kubectl get pod -o wide
[root@master ~]# curl http://10.244.1.8
this is apache
[root@master ~]# curl http://10.244.3.16
this is apache
扩展:在资源控制器的元数据中添加:kubernetes.io/change-cause: 软件版本;实现以下效果:
① 在执行资源文件前修改
[root@master ~]# vim myapache.yaml
metadata:
name: myapache
annotations: //添加annotations:
kubernetes.io/change-cause: httpd.v1
…
[root@master ~]# kubectl apply -f myapache.yaml
② 在资源文件已执行后,edit修改(保存立即生效)
[root@master ~]# kubectl edit deployments myapache //annotations执行后默认产生
五、K8S集群调度
1、nodeName标签(单节点选择)
容器创建是随机的,如果希望在调度时,选择固定的宿主机,使用nodeName选择标签可以根据定义的节点名称选择宿主机;(即nodeName 能让容器运行在指定节点上,属于手动选择节点,而不是随机调度分配节点)
弊端:如果添加了nodeName选择标签,但在选择指定节点时,发现节点不符合POD指定所需的资源量要求或无法使用该主机,POD将一直处于Pending未调度完成状态;其次,控制器也无法完成高可用
注意:选择节点标签只在容器运行前有效;’
示例:使用nodeName节点标签选择节点
① 修改资源文件,添加在POD.SPEC添加nodeName标签
[root@master ~]# vim myapache.yaml
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: myapache
spec:
selector:
matchLabels:
myapp: httpd
replicas: 1
template:
metadata:
labels:
myapp: httpd
spec:
nodeName: node-0001 //新增一行,nodeName节点标签
containers:
- name: webcluster
image: 192.168.1.100:5000/myos:httpd
stdin: false
tty: false
ports:
- protocol: TCP
containerPort: 80
restartPolicy: Always
[root@master ~]# kubectl delete -f myapache.yaml
[root@master ~]# kubectl apply -f myapache.yaml
[root@master ~]# kubectl get pods -o wide
补充:nodeName选择标签存在的弊端,会导致即使有控制器也无法完成高可用,为解决该问题,需使用nodeSelector标签
2、nodeSelector标签(多节点选择)
选择一类宿主机,需要提前为目标主机打上特定的标签(可以是多台),在资源文件中根据标签选择宿主机,更加灵活;(比如生产环境中需要将MySQL资源运行在目标节点上)
nodeSelector是节点选择约束的最简单推荐形式,可以提前为节点设置标签,并在资源文件中添加节点选择器,根据标签来选择需要的节点;
① 查看节点标签
- 格式:kubectl get node --show-labels
② 设置节点标签
- 格式:kubectl label node =
③ 删除节点标签
- 格式:kubectl label node -
示例:使用nodeSelector标签选择节点
[root@master ~]# kubectl delete -f myapache.yaml
deployment.apps "myapache" deleted
[root@master ~]# kubectl get nodes --show-labels //查看节点的所有标签
补充:标签以键值对的形式出现,以逗号进行分隔;
① 为节点设置标签,标签类型为disktype=ssd(磁盘类型为ssd)
[root@master ~]# kubectl label nodes node-0002 node-0003 disktype=ssd
node/node-0002 labeled
node/node-0003 labeled
[root@master ~]# kubectl get nodes --show-labels
② 修改资源文件,添加节点选择器
[root@master ~]# vim myapache.yaml
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: myapache
spec:
selector:
matchLabels:
myapp: httpd
replicas: 1
template:
metadata:
labels:
myapp: httpd
spec:
nodeSelector: //新增节点选择器
disktype: ssd //选择类型为disktype:ssd
containers:
- name: webcluster
image: 192.168.1.100:5000/myos:httpd
stdin: false
tty: false
ports:
- protocol: TCP
containerPort: 80
restartPolicy: Always
[root@master ~]# kubectl apply -f myapache.yaml
deployment.apps/myapache created
[root@master ~]# kubectl scale deployment myapache --replicas=5
deployment.apps/myapache scaled
[root@master ~]# kubectl get pod -o wide
补充:提前为节点设置标签,并在资源文件中添加节点选择器,根据标签来选择需要的节点
③ 删除标签及资源文件配置
[root@master ~]# kubectl delete -f myapache.yaml
deployment.apps "myapache" deleted
[root@master ~]# kubectl label nodes node-0002 node-0003 disktype-
node/node-0002 labeled
node/node-0003 labeled
[root@master ~]# kubectl get nodes --show-labels
NAME STATUS ROLES AGE VERSION LABELS
[root@master ~]# vim myapache.yaml //删除nodeSelector配置
nodeSelector: //删除
disktype: ssd //删除
[root@master ~]# kubectl apply -f myapache.yaml
[root@master ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
myapache-7d689bf8f-wmv85 1/1 Running 0 14s 10.244.1.10 node-0001 <none> <none>
六、高级调度策略(扩展知识)
1、亲和与反亲和
亲和可理解成编号或喜好,同样反亲和可理解成不喜欢;在kubernetes中亲和特性在pod.spec.affinity中设置。
- 从亲和的对象又可以分为:(节点亲和)和(容器亲和);
- 从亲和的策略又可以分为:(硬亲和)和(软亲和);
参考案例:kubernetes/v1.17.6/config/
例如1:php-example.yaml
[root@ecs-proxy config]# vim php-example.yaml
补充:根据定义的亲和性(节点亲和),进行CPU(硬亲和)和内存(软亲和)的筛选(high、mid),来分配容器;
例如2:web-example.yaml
[root@ecs-proxy config]# vim web-example.yaml
补充:根据定义的亲和性(容器亲和),哪个主机运行PHP(硬亲和),哪个主机运行apache(软亲和)进行筛选
小结:
本篇章节为【第五阶段】CLOUD-DAY7 的学习笔记,这篇笔记可以初步了解到 在kubernetes平台上理解掌握各种控制器的用法:掌握kubectl管理命令、掌握POD原理、掌握集群调度的规则、熟悉控制器资源文件,除此之外您还可以参考以下内容:
Tip:毕竟两个人的智慧大于一个人的智慧,如果你不理解本章节的内容或需要相关笔记、视频,可私信小安,请不要害羞和回避,可以向他人请教,花点时间直到你真正的理解。