Linux云计算 |【第五阶段】CLOUD-DAY7

主要内容:

在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信息

例如:查看集群的节点状态

bash 复制代码
[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

例如:查看集群的节点状态和显示主机信息

bash 复制代码
[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信息

bash 复制代码
[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容器资源

bash 复制代码
[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系统命名空间查询;

bash 复制代码
[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 //查询资源控制器
bash 复制代码
[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,镜像下载失败

bash 复制代码
[root@master~]# kubectl -n kube-system get pod

② 通过describe查询POD资源容器的详细信息(找到events事件信息)

bash 复制代码
[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终端的输出信息(为空是正常现象,表示没有日志输出)

bash 复制代码
[root@master ~]# kubectl logs kube-flannel-ds-amd64-5xqms
Error from server (NotFound): pods "kube-flannel-ds-amd64-5xqms" not found

④ 根据输出信息,找到错误原因并修改;

bash 复制代码
[root@master ~]# vim flannel/kube-flannel.yml
        image: 192.168.1.100:5000/flannel:v0.12.0-amd64    //修改后

⑤ 重新执行指定的资源文件

bash 复制代码
[root@master ~]# kubectl delete -f flannel/kube-flannel.yml   //删除资源文件
[root@master ~]# kubectl apply -f flannel/kube-flannel.yml   //重新执行资源文件

验证效果

bash 复制代码
[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的容器

bash 复制代码
[root@master ~]# kubectl run testos -it --image=192.168.1.100:5000/myos:v1804
[root@testos-6d7c98965-89cz4 /]# ifconfig
bash 复制代码
[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 [--] 执行的命令
bash 复制代码
[root@master ~]# kubectl exec -it testos-6d7c98965-kzqhb /bin/bash
[root@testos-6d7c98965-kzqhb /]#

补充:-- 选项终止符,结束某一个参数的选项,避免混淆

5、使用Kubectl attach进入正在运行的容器

  • 格式:kubectl attach -it 容器id
bash 复制代码
[root@master ~]# kubectl attach -it testos-6d7c98965-kzqhb
[root@testos-6d7c98965-kzqhb /]#

6、使用Kubectl delete删除资源

  • 格式:kubectl delete 资源类型 资源名称
bash 复制代码
[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控制器删除;

bash 复制代码
[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)

bash 复制代码
[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

验证效果

bash 复制代码
[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)

bash 复制代码
[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

验证效果

bash 复制代码
[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

bash 复制代码
[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进行扩容

bash 复制代码
[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进行调度分配;

测试效果

bash 复制代码
[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进行缩容

bash 复制代码
[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资源的更新

bash 复制代码
[root@master ~]# kubectl scale deployment myapache --replicas=2
deployment.apps/myapache scaled
[root@master ~]# kubectl get pod -o wide
bash 复制代码
[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版本)

bash 复制代码
      containers:
      - image: 192.168.1.100:5000/myos:nginx
bash 复制代码
[root@master ~]# kubectl get pod -o wide

补充:通过RollingUpdate 滚动式更新,IP地址及Node地址已重新调度分配;

bash 复制代码
[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资源的回滚

bash 复制代码
[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
bash 复制代码
[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: 软件版本;实现以下效果:

① 在执行资源文件前修改

bash 复制代码
[root@master ~]# vim myapache.yaml
metadata:
  name: myapache
  annotations:     //添加annotations:
kubernetes.io/change-cause: httpd.v1
...
[root@master ~]# kubectl apply -f myapache.yaml

② 在资源文件已执行后,edit修改(保存立即生效)

bash 复制代码
[root@master ~]# kubectl edit deployments myapache   //annotations执行后默认产生

五、K8S集群调度

1、nodeName标签(单节点选择)

容器创建是随机的,如果希望在调度时,选择固定的宿主机,使用nodeName选择标签可以根据定义的节点名称选择宿主机;(即nodeName 能让容器运行在指定节点上,属于手动选择节点,而不是随机调度分配节点)

弊端:如果添加了nodeName选择标签,但在选择指定节点时,发现节点不符合POD指定所需的资源量要求或无法使用该主机,POD将一直处于Pending未调度完成状态;其次,控制器也无法完成高可用

注意:选择节点标签只在容器运行前有效;'


示例:使用nodeName节点标签选择节点

① 修改资源文件,添加在POD.SPEC添加nodeName标签

bash 复制代码
[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标签选择节点

bash 复制代码
[root@master ~]# kubectl delete -f myapache.yaml
deployment.apps "myapache" deleted
[root@master ~]# kubectl get nodes --show-labels    //查看节点的所有标签

补充:标签以键值对的形式出现,以逗号进行分隔;

① 为节点设置标签,标签类型为disktype=ssd(磁盘类型为ssd)

bash 复制代码
[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

② 修改资源文件,添加节点选择器

bash 复制代码
[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

补充:提前为节点设置标签,并在资源文件中添加节点选择器,根据标签来选择需要的节点

③ 删除标签及资源文件配置

bash 复制代码
[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
bash 复制代码
[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中设置。

  • 从亲和的对象又可以分为:(节点亲和)和(容器亲和);
  • 从亲和的策略又可以分为:(硬亲和)和(软亲和);

参考:将 Pod 指派给节点 | Kubernetes

参考案例:kubernetes/v1.17.6/config/

例如1:php-example.yaml

bash 复制代码
[root@ecs-proxy config]# vim php-example.yaml

补充:根据定义的亲和性(节点亲和),进行CPU(硬亲和)和内存(软亲和)的筛选(high、mid),来分配容器;

例如2:web-example.yaml

bash 复制代码
[root@ecs-proxy config]# vim web-example.yaml

补充:根据定义的亲和性(容器亲和),哪个主机运行PHP(硬亲和),哪个主机运行apache(软亲和)进行筛选

小结:

本篇章节为**【第五阶段】CLOUD-DAY7** 的学习笔记,这篇笔记可以初步了解到 在kubernetes平台上理解掌握各种控制器的用法:掌握kubectl管理命令、掌握POD原理、掌握集群调度的规则、熟悉控制器资源文件,除此之外您还可以参考以下内容:


Tip:毕竟两个人的智慧大于一个人的智慧,如果你不理解本章节的内容或需要相关笔记、视频,可私信小安,请不要害羞和回避,可以向他人请教,花点时间直到你真正的理解。

相关推荐
搬砖的小码农_Sky28 分钟前
如何在Linux中比较两个文件的差异?
linux
wanhengwangluo29 分钟前
弹性裸金属服务器和传统裸金属服务器有什么区别?
运维·服务器
来一杯龙舌兰1 小时前
【MongoDB】Windows/Docker 下载安装,MongoDB Compass的基本使用、NoSQL、MongoDB的基础概念及基础用法(超详细)
windows·mongodb·docker·mongodb compass
Syclus1 小时前
成功解决WSL2上的Ubuntu22.04执行sudo apt-get update指令报错问题
linux·运维·服务器
kaoa0001 小时前
Linux入门攻坚——36、Linux防火墙-iptables-2
linux·运维
EasyCVR2 小时前
国标GB28181视频平台EasyCVR私有化视频平台工地防盗视频监控系统方案
运维·科技·ffmpeg·音视频·1024程序员节·监控视频接入
小林熬夜学编程2 小时前
【Linux系统编程】第四十二弹---多线程编程全攻略:涵盖线程创建、异常处理、用途、进程对比及线程控制
linux·服务器·c语言·开发语言·c++
恒创科技HK2 小时前
ssh和ssl的区别在哪些方面?
运维·ssh·ssl
上烟雨心上尘2 小时前
通过 ssh config 快速免密连接服务器
运维·服务器·ssh