目录
2)deployment.spec.strategy支持两种策略
一.常用命令及kubect介绍
1.kubect介绍
--Kubectl是用于控制Kubernetes集群的命令行工具
1)语法格式:
~]# kubectl [command] [TYPE] [NAME] [flagsJ command: # 子命令,如create, get, describe, delete type: # 资源类型,可以表示为单数,复数或缩写形式 name: # 资源的名称,如果省略,则显示所有资源信息 flags: # 指定可选标志,或附加的参数 # 查看所有类型 ~]# kubectl api-resources ## 示例 # 查询节点状态 ~]# kubectl get node # 查询主机信息 ~]# kubectl get node node1 -o wide # -o参数帮助 ~]# kubectl get node node1 -o wide --help .... [(-o|--output=)json|yaml|name|go-template|go-template-file|template|templatefile|jsonpath|jsonpath-as-json|jsonpath-file|custom-columns|custom-columns-file|wide] ..... # -o 指定以yaml格式显示出来 ~]# kubectl get node node1 -o yaml # 查询deployment资源名称 ~]# kubectl get deployment # 查询pod容器资源(默认命名空间default) ~]# kubectl get pods # 指定查看pods的名称空间 ~]# kubectl get pods -n kube-system
2)命名空间的概述
k8s命名空间为对象名称提供了一个作用域,我们可以把资源放到不同的命名空间中,这样我们可以使用同名的资源名称,只要保证同一命名空间中的资源名称唯一即可
系统命名空间
--default默认的命名空间,不声明命名空间的POD都在这里
--kube-node-lease为高可用提供心跳监视的命名空间
--kube-public公共数据,所有用户都可以读取它
--kube-system 系统服务对象所使用的命名空间
3)查看命名空间
~]# kubectl get namespace
4)查看命名空间中的资源对象
~]# kubectl -n kube-system get pod
2.查用排错命令
1)查询资源文件
# 格式 ~]# kubectl get [资源类型] [资源名称] ## 示例 # 查看所有pod容器 ~]# kubectl get pods -A # 查看指定容器名称空间内的所有容器 ~]# kubectl get pods -n kube-system NAME READY STATUS RESTARTS AGE coredns-557689b88f-g9pwl 1/1 Running 1 (5h1m ago) 2d22h coredns-557689b88f-rj84r 1/1 Running 1 (5h1m ago) 2d22h ....... # 查看指定容器名称空间内的指定容器 ~]# kubectl get pods -n kube-system coredns-557689b88f-g9pwl # 查看指定容器名称空间内的指定容器信息 ~]# kubectl get pods -n kube-system coredns-557689b88f-g9pwl -o wide # 查看指定容器名称空间内的指定容器详细信息以yaml格式显示 ~]# kubectl get pods -n kube-system coredns-557689b88f-g9pwl -o yaml # 查看节点信息并显示详细信息以yaml格式显示 ~]# kubectl get nodes -o yaml
2)查看资源详细信息(经常用于排错)
# 格式 ~]# kubectl describe [资源类型] [资源名称] # 示例 ~]# kubectl describe pods -n kube-system kube-flannel-ds-jxwf5
3)查看容器的日志信息
-查看console终端的输出信息
-为空是正常现象,表示没有日志输出
# 格式 ~]# kubectl logs [名称空间] [容器名称] # 示例 ~]# kubectl logs -n kube-system kube-flannel-ds-jxwf5
排错流程,一般先get查看,然后再describe,最后再logs查看
3.kubectl 命令与示例
命令格式 | 命令说明 |
---|---|
kubectl run 资源名称 -参数 --image=镜像名称:标签 | 创建资源对象,常用参数-i交互,-t终端 |
kubectl get 查询资源 可选参数 -o wide 显示主机信息 | 常用查询的资源 node|deployment|pod |
kubectl exec -it 容器id 执行的命令 | 同 docker exec 指令,进入容器内 |
kubectl describe 资源类型 资源名称 | 查询资源的详细信息 |
kubectl attach | 同 docker attach 指令,连接容器 |
kubectl logs 容器id | 查看容器控制台的标准输出 |
kubectl delete 资源类型 资源名称 | 删除指定的资源 |
kubectl create|apply -f 资源文件 | 执行指定的资源文件 |
命令示例
# 执行指定的资源文件 ~]# kubectl apply -f kube-flannel.yml # 删除指定资源文件(当flannel注册失败容器报pending时,可以用这种方法重启) ~]# kubectl delete -f kube-flannel.yml # 查看 ~]# kubectl get pods -A NAMESPACE NAME READY STATUS RESTARTS AGE default testos 1/1 Running 2 (31m ago) 125m kube-system coredns-557689b88f-g9pwl 1/1 Running 1 (8h ago) 3d1h kube-system coredns-557689b88f-rj84r 1/1 Running 1 (8h ago) 3d1h kube-system etcd-master 1/1 Running 3 (8h ago) 3d1h kube-system kube-apiserver-master 1/1 Running 3 (8h ago) 3d1h kube-system kube-controller-manager-master 1/1 Running 3 (8h ago) 3d1h kube-system kube-proxy-flzrz 1/1 Running 2 (8h ago) 3d1h kube-system kube-proxy-sv5n8 1/1 Running 0 7h42m kube-system kube-proxy-tkctb 1/1 Running 0 30h kube-system kube-scheduler-master 1/1 Running 4 (8h ago) 3d1h ## get 查询信息 # 查看节点 ~]# kubectl get nodes NAME STATUS ROLES AGE VERSION master Ready master 19h v1.17.6 node-0001 Ready <none> 16h v1.17.6 # 查看pod容器 ~]# kubectl get pod No resources found in default namespace. # 注:这里是因为get pod不写指定名称空间,默认找default # 查看所有名称空间 ~]# kubectl get namespaces NAME STATUS AGE default Active 9h kube-node-lease Active 9h kube-public Active 9h kube-system Active 9h # 指定名称空间查看pod容器 ~]# kubectl -n kube-system get pod NAME READY STATUS RESTARTS AGE kube-flannel-ds-amd64-hf2jp 1/1 Running 0 41m kube-flannel-ds-amd64-rtl4l 1/1 Running 0 41m ... ... # describe 查询详细信息 ~]# kubectl -n kube-system describe pod kube-flannel-ds-amd64-rtl4l Name: kube-proxy-4tbp6 Namespace: kube-system ... ... Events: ...... # 注:错误信息主要找Events # 使用run启动容器 ~]# kubectl run testos -it --image=192.168.1.100:5000/myos:v1804 # 注释: 命令 子命令 自己起的名字 交互式终端 指定镜像=镜像仓库地址/镜像名 If you don't see a command prompt, try pressing enter /]# exit ~]# kubectl get pods NAME READY STATUS RESTARTS AGE testos 1/1 Running 1 (5s ago) 3m28s # 启动服务 ~]# kubectl run web-test --image=192.168.1.100:5000/myos:httpd kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead. deployment.apps/web-test created # 访问节点 ~]# kubectl get pod -o wide #详细信息 NAME READY STATUS RESTARTS AGE IP testos-79778b4895-s8mxl 1/1 Running 1 6m33s 10.244.3.2 ... ... testweb--7bf98b9576-v566c 1/1 Running 0 4m24s 10.244.4.2 ... ... ~]# curl http://10.244.4.2/info.php <pre> Array ( [REMOTE_ADDR] => 10.244.0.0 [REQUEST_METHOD] => GET [HTTP_USER_AGENT] => curl/7.29.0 [REQUEST_URI] => /info.php ) php_host: web-test-7bf98b9576-v566c 1229 # 进入容器 ~]# kubectl exec -it testos-79778b4895-s8mxl -- /bin/bash /]# ~]# kubectl attach -it testos-79778b4895-s8mxl /]# # 查看终端日志 ~]# kubectl logs web-test-7bf98b9576-v566c AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 10.244.4.2. Set the 'ServerName' directive globally to suppress this message # 删除资源控制器,直接删除POD会自动重建 ~]# kubectl delete pod testos-79778b4895-s8mxl pod "testos-79778b4895-s8mxl" deleted ~]# kubectl delete deployments testos deployment.apps "testos" deleted
二.kubectl容器管理
1.Pod与控制器
1)Deployment 资源控制器
Deployment 为 RS 提供滚动更新
-ReplicaSet资源控制器(RS)
-ReplicaSet 创建管理POD
-ReplicaSet可以扩容和缩容
-POD最小的管理单元
-POD负责启动和运行容器
控制器架构示例图
# 查看一级控制器 ~]# kubectl get deployments.apps NAME READY STATUS RESTARTS AGE testos 1/1 Running 1 (6m57s ago) 10m # 查看二级控制器 ~]# kubectl get replicasets.apps NAME READY STATUS RESTARTS AGE testos-79778b4895 1/1 Running 1 (6m57s ago) 10m # 查看三级控制器 ~]# kubectl get pods NAME READY STATUS RESTARTS AGE testos-79778b4895-s8mxl 1/1 Running 1 (6m57s ago) 10m
# 注:二级,三级等一下控制器都是自动生成的,而一级控制器是自己创建的(必须手定义)
2)POD是什么?
-
POD是Kubernetes中最小的管理元素
-
一个pod 可以理解为多个linux命名空间的联合
同一个Pod共享进程(PID)
同一个Pod共享网络IP及权限(NETWORK)
同一个Pod共享IPC通信信号(IPC)
同一个Pod共享主机名(UTS)
-
包涵1个或多个容器 例如:共享网络、共享存储等
理解POD对掌握kubernetes非常重要
Pod支持横向扩展和复制
2.POD的概述
1)POD的启动过程
用户创建pod--->>(kubectl )联系API server--->>(kubectl 的命令)记录在etcd数据库中--->>然后(api server)再去找Scheduler调度器,Scheduler再调用内部的算法去找适合运行容器的节点--->>(Scheduler)把结果返回aip server-->>api server再把结果记录到etcd数据库中,由于master默认不运行服务,所以api serve 回直接找node节点也就是(kubelete计算节点)--->> (kubelete)找docker创建容器--(docker)把容器状态返回kubelete--->>(kubelet)再把容器状态返回给api server--->>( api server)再把结果记录再etcd数据库中
注:此时数据库中记录了类似与(c1 node running),所以此时使用kubectl就能调用这些信息
Scheduler分配容器
第一步筛选
比如此时要运行一个容器需要(500m的内存,端口80),此时 Scheduler就会去找节点凡是内存没有500m的排除,端口80被占用的排除,
第二步优选
如果此时有多个节点符合筛选条件,则根据内部算法(打分机制)选择
2)POD生命周期
Pod对象自从其创建开始至其终止退出的时间范围称为其生命周期。在这段时间中,Pod会处于 多种不同的状态,并执行一些操作;其中,创建主容器(main container)为必需的操作,其他可选的操作还包括运行于初始化容器(init container)、容器启动后钩子 (postart hook)、容器的存活性探测(liveness probe) 就绪性探测 (readiness probe)以及容器终止前钩子 (pre stop hook) 等,这些操作是否执行则取决于Pod 的定义
pod的启动--->>初始化容器(init container)(默认没有条件,可以填加初始话条件)--->>随着容器启动的小程序,也叫启动前脚本(post start hook)(小程序可以执行一些特别的操作,比如指定容器为谁的从服务器,默认也是空的)--->> 容器关闭前脚本(pre stop hook)(默认也是空的)(比如删除容器时发现容器在启动之后产生了5个G的硬盘空间,此时想要删除,这时候就可以设置结束前执行脚本了)
此时pod还有两个探测器
- 生存探测(liveness probe)
如果容器失败了,就会重启
- 就绪性探测 (readiness probe)
如果失败不会重启容器,只会改为NoReady,没有就绪状态,这个时候就以排错了(默认为空)
## 生存探测器示例 ~]# kubectl get pods NAME READY STATUS RESTARTS AGE testos 1/1 Running 1 (13m ago) 17m ~]# kubectl attach pods -n default -it testos If you don't see a command prompt, try pressing enter. # 在容器内查看进程 /]# echo $$ 1 # 因为attach进入容器用的父进程,而容器的父进程是上帝进程,且容器退出的方式是杀掉父进程,也就是会干掉容器 /]# exit # 就绪探测器发现容器没有启动就会直接显示该状态 ~]# kubectl get pods NAME READY STATUS RESTARTS AGE testos 0/1 Completed 1 (90m ago) 93m # 此时生存探测器发现容器被干掉了,就会重新生成容器 ~]# kubectl get pods NAME READY STATUS RESTARTS AGE testos 1/1 Running 2 (4s ago) 93m
3.POD的启动状态
Pod phase(相位状态)
--Pod的status字段是一个PodStatus的对象,Pod对象总是应 该处于其生命进程中以下几个相位(phase)之-。
--Pending 容器创建过程中,但它尚未被调度完成(api server找Scheduler之前的状态就是Pending,如果是这种状态,则说明节点不服和调度)
--Running 所有容器都已经被kubelet创建完成(Scheduler到docker之间的状态)
--Succeeded 所有容器都已经成功终止了并不会被重启
--Failed Pod中的所有容器中至少有一个容器退出是非O状态
--Unknown 无法正常获取到Pod对象的状态信息
4.POD特点
--Pod的生命周期是短暂的,用后即焚的实体。 注意:重启Pod中的容器跟重启Pod不是一回事。Pod只提供容器的运行环境并保持容器的运行状态,重启容器不会造成Pod重启。(在k8s中没有停止的概念,只有创建与删除。create,delete)
--Pod不会自愈。如果Pod运行的Node故障,或者是调度器本身故障,这个Pod就会被删除。(但是如果有控制器就不不一样)
--控制器(Deployment/RC/RS)可以自动创建和管理多个Pod, 提供副本管理、滚动升级和集群级别的自愈能力。
5.容器管理命令
1)进入一个正在运行的容器
语法格式:
~]# kubectl exec -it 容器id --执行的命令 # 这样运行的退出后不会重启
2)删除资源
语法格式:
~]# kubectl delete 资源类型 资源名称 # 删除容器 ~]# kubectl delete pods -n default testos-79778b4895-s8mxl pod "testos-79778b4895-s8mxl" deleted # 查看pod容器,发现还是会创建出来 ~]# kubectl get pods NAME READY STATUS RESTARTS AGE testos-79778b4895-43er4 1/1 Running 2 (88m ago) 92m # 此时就要删除该pod容器的控制器 ~]# kubectl get deployments.apps NAME READY STATUS RESTARTS AGE testos 1/1 Running 2 (88m ago) 92m ~]# kubectl delete deployments testos deployment.apps "testos" deleted # 删除容器时有一个宽限期,为了保证数据的完整性,删除资源控制器时也有一个(terminating回收状态)宽限期
6.其他资源控制器
peployment
Deployment /RC/RS 都是资源控制器
Deployment为Pod和ReplicaSet提供了一个声明式定 义方法,用来替代以前的Replicationcontroller 来方便的管理应用。
典型的应用场景包括:
--定义Deployment来创建Pod和ReplicaSet
--滚动升级和回滚应用
--扩容和缩容
--暂停和继续Deployment
RC/RS/Deployment
--kubernetes通过Replication Control1(简称RC) 管理POD,在RC中定义了如何启动POD,如何 运行,启动几副本等功能,如果我们创建文件, 在其中使用Yaml的语法格式描述了上面的信息, 这个文件就是我们的资源对象文件
--ReplicaSet (简称RS)是RC的升级版
--Deployment为Pods和RS提供描述性的更新方式
三.资源文件的概述
1.资源对象文件的概述
-kuberbetes通过RC/RS 管理POD,在RC中定义了如何启动POD,如何运行,启动几个副本等功能,如果我们创建的文件,在其中使用Yaml的语法描述了上面的信息,这个文件就是我们的资源对象文件
-资源文件可以创建,删除,管理资源对象
-资源文件有很多高级的复杂的功能靠简单的命令方式无法实现,这些都需要使用资源文件描述
2.YAMl语法概述
YAML 是什么?
YAML 是一种可读性高,以数据为中心的数据序列化格式。可以表达 对象(键值对)数组,标量; 这几种数据形式 能够被多种编程语言和脚本语言解析
YAML 语法与格式
基本语法
以 k: v 的形式来表示键值对的关系,冒号后面必须有一个空格
表示注释
对大小写敏感
通过缩进来表示层级关系,缩排中空格的数目不重要,只要相同阶层的元素左侧对齐就可以了
缩进只能使用空格,不能使用 tab缩进键
字符串可以不用双引号
格式
对象和键值对
通过 k: v 的方式表示对象或者键值对,冒号后必须要加一个空格:
Name: Astron Sex: female School: TJU
通过缩进来表示对象的多个属性:
People: Name: Astron Sex: female School: TJU
也可以写成
people: {name: Astron, sex: female}
数组
数组(或者列表)中的元素采用
-
表示,以-
开头的行表示构成一个数组# eg1: - A - B - C
#eg2: people: - yyy - zzz - www
行内表示:
people: [yyy, zzz, www]
eg3: 对象数组
people: - name: yyy age: 18 - name: zzz age: 19
使用流式表示:
people: [{name: yyy, age: 18},{name: zzz, age: 19}]
标量
标量是最基本的不可再分的值,包括:
整数
浮点数
字符串
布尔值
Null
时间
日期
eg: boolean: - true # 大小写都可以 - false float: - 3.14 - 3.25e+5 # 科学计数法 int: 12 null: nodeName: name string: 123 date: 2020-01-01 # 格式为 yyyy-MM-dd datetime: 2020-01-10T15:02:08+08:00 # 日期和时间使用T连接,+表示时区
引用
&
用于建立锚点,*
用于引用锚点,<<
表示合并到当前数据eg1: defaults: &defaults adapter: ppp host: qqq development: database: mq <<: *defaults
相当于:
defaults: adapter: ppp host: qqq development: database: mq adapter: ppp host: qqq eg2: - &showell steve - clark - eve - *showell
相当于:
- steve - clark - eve - steve
3.资源文件的管理命令
--create 创建资源对象(没有密等性,一般不用)
--apply 生名更新资源对象
--delete 删除资源文件
# 更新资源对象,也可以用来创建 ~]# kubectl apply -f mypod.yaml # 创建资源对象,但是用create创建的资源不能用apply更新 ~]# kubectl create -f mypod.yaml # 删除资源文件 ~]# kubectl delete -f mypod.yaml
4.POD的资源文件书写格式概述
--- # 资源的开始,当一个文件中有多个时,则说明一个文件有多个资源文件 kind: Pod # 资源对象的类型,这里定义pod,默认键值对采用key(小驼峰) : value(大坨峰),资源所有对象查看(kubectl api-resources) apiVersion: v1 # pod的版本,查看当前k8s支持的所有版本(kubectl api-versions),查看当前pod的版本,及基本概述(kubectl explain pods),详细的当输入前面这条命令的时候地下会有网址,不过建议访问国内的(https://kubernetes.io/) metadata: # 元数据,(属性数据,定义该pod的详细信息,pod.metadata) name: mypod # 定义pod的名字,且是唯一性 spec: # 标志位,标志详细信息,前面定义了资源对象,所以这里就是pod的详细信息(pod.spec) containers: # pod里的容器 - name: mylinux #相当于pod里面的容器(mypod.mylinux) image: 172.17.0.98:5000/myos:v1804 # 这个容器用的什么镜像 stdin: true # 标准输出(相当与-i) tty: true # 终端(相当与-t) # 注:stdin,tty不写默认是false ## 示例 # 创建容器 ~]# kubectl apply -f mypod.yaml pod/mypod created # 查看创建 ~]# kubectl get pods NAME READY STATUS RESTARTS AGE mypod 1/1 Running 0 5s # 注意此时是没有控制器的,所以可以直接删除 ~]# kubectl get deployments.apps No resources found in default namespace. ~]# kubectl get replicasets.apps No resources found in default namespace # 直接删除 ]# kubectl delete pods mypod pod "mypod" deleted ~]# kubectl get replicasets.apps No resources found in default namespace. ~]# kubectl get pods NAME READY STATUS RESTARTS AGE
5.deploy资源控制器文件的书写
# 由于创建不带控制器的pod非常的不安全,所以这里创建带控制器的pod ~]# vim myapache.yaml --- # 资源的开始 kind: Deployment # 资源对象的类型,为Deployment控制器 apiVersion: apps/v1 # 控制器的版本,查看deployment的版本(kubectl explain deployment) metadata: # 元数据,(属性数据,定义该deployment控制器的详细信息,deploy.metadata) name: myapache # 定义deploy控制器的名字,且是唯一性 annotations: # 附加信息,该字段保留,后续介绍 kubernetes.io/change-cause: httpd.v1 spec: # 详细定义,定义了资源对象控制器的详细信息,(deploy.spec) selector: # 定义了控制器的标签 matchLabels: myapp: httpd # 定义了标签为httpd replicas: 1 # 定义pod副本数 template: # 定义pod的资源模板 metadata: # pod的元数据,(属性数据,定义该pod的详细信息,pod.metadata) labels: # 定义pod的标签 myapp: httpd # 标签名 (由于创建了控制器所以不能给pod起名字,只能由控制器创建pod的名字,所以这里只定义了标签) spec: # 定义pod的spec这里就是pod的详细信息(pod.spec) containers: # pod里的容器 - name: webcluster # 定义于pod里面的容器名字(mypod.webcluster) image: 172.17.0.98:5000/myos:httpd # 这个容器用的什么镜像 stdin: false # 标准输出(相当与-i),由于这边启动的是apache,不需要交互试的终端输出,所以这里同意设置flase,或者不写也是可以的 tty: false # 终端(相当与-t) ports: # 由于启动的是服务所以要设置监听端口号 - protocol: TCP # 监听的协议TCP containerPort: 80 # 监听的端口是80 restartPolicy: Always # 定义策略,pod维护容器的策略(策略:Always;OnFailure;Never)默认Always,Always表示容器一但死亡,则会重新创建;OnFailure表示只有当容器退出时$?!=0时才重启,也就是启动失败才重启;Never表示不管哪种都不重启; # 创建 ~]# kubectl apply -f myapache.yaml deployment.apps/myapache created # 查看pod ~]# kubectl get pods NAME READY STATUS RESTARTS AGE myapache-9d7557448-nq8rw 1/1 Running 0 17s # 查看一级控制器 ~]# kubectl get deployments.apps myapache 1/1 1 1 3m49s # 查看二级控制器 ~]# kubectl get replicasets.apps NAME DESIRED CURRENT READY AGE myapache-9d7557448 1 1 1 4m # 测试 ~]# curl -ik http://10.244.2.4
6.标签和选择器的书写格式
k8s 的 标签 和 标签选择器 标签 可以附加在 kubernetes 任何资源对象之上的键值型 数据 ,常用于 标签选择器 的匹配度检查,从而完成资源筛选 资源 标签 当 Kubernetes 对系统的任何API对象如Pod和节点进行“分组”时,会对其添加Label(key=value形式的“键-值对”)用以精准地 选择 对应的API对象
lables是设置标签,matchLabels匹配标签
为了建立控制器和pod间的关联,因为pod的名字是唯一的,如果起多个容器的话,不可以这么操作,所以kubernetes 先给每个pod打上一个标签(Label),然后再给相应的位置定义标签选择器(Label Selector),引用这些标签管理,而且资源控制器会给pod自动分配名字;
三.集群的管理
一个资源控制器可以控制多个pod
1.集群扩容
-
replicas 决定了集群pod数量
创建一个单节点的web容器
-
在集群运行的过程中我们可以动态调整集群pod的数量
在创建文件之初设置容器副本数
~]# cat myapache.yaml --- ...... replicas: 1 # 根据数字设置 ......
在线修改设置,及时生效
# 先查看要扩容的容器的资源控制器,只有修改资源控制器才有效,而pod是被创建出来的 ~]# kubectl get deployment NAME READY UP-TO-DATE AVAILABLE AGE myapache 1/1 1 1 26m # 进入配置里修改 ~]# kubectl edit deployment myapache ....... replicas: 3 # 根据数字设置,这里设置3测试 ...... # 查看 ~]# kubectl get deployment myapache NAME READY UP-TO-DATE AVAILABLE AGE myapache 3/3 3 3 31m ~]# kubectl get pods ~]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapache-9d7557448-59fxm 1/1 Running 0 3m4s 10.244.1.4 vm-0-114-centos <none> <none> myapache-9d7557448-64fhh 1/1 Running 0 109s 10.244.1.5 vm-0-114-centos <none> <none> myapache-9d7557448-brsbc 1/1 Running 0 109s 10.244.2.4 vm-0-142-centos <none> <none> testos 1/1 Running 2 (23h ago) 24h 10.244.1.2 vm-0-114-centos <none> <none>
scale 命令
# 先查看要扩容的容器的资源控制器,只有修改资源控制器才有效,而pod是被创建出来的 ~]# kubectl get deployment myapache NAME READY UP-TO-DATE AVAILABLE AGE myapache 3/3 3 3 31m ## 用scale设置 # 缩减 ~]# kubectl scale deployments.apps myapache --replicas=1 # 查看pod ~]# kubectl get deployment myapache NAME READY UP-TO-DATE AVAILABLE AGE myapache 1/1 1 1 35m # 扩展 ~]# kubectl scale deployments.apps myapache --replicas=3 # 查看pod ~]# kubectl get deployment myapache NAME READY UP-TO-DATE AVAILABLE AGE myapache 3/3 3 3 31m ~]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapache-9d7557448-59fxm 1/1 Running 0 3m4s 10.244.1.4 vm-0-114-centos <none> <none> myapache-9d7557448-64fhh 1/1 Running 0 109s 10.244.1.5 vm-0-114-centos <none> <none> myapache-9d7557448-brsbc 1/1 Running 0 109s 10.244.2.4 vm-0-142-centos <none> <none>
2.集群更新与回滚
1)查看控制器规则
kubectl get 资源对象 资源名称 -o 格式
~]# kubectl get deployment myapache -o yaml ...... spec: progressDeadlineSeconds: 600 replicas: 1 revisionHistoryLimit: 10 # 保留最多10个历史版本 selector: matchLabels: myapp: httpd strategy: # 更新策略 rollingUpdate: # 滚动更新 maxSurge: 25% # 最多超过25%的副本数 maxUnavailable: 25% # 最多有25%的副本不可用 type: RollingUpdate # 更行方式(Recrete ,rollingUpdate)
2)deployment.spec.strategy支持两种策略
-
Recrete
重建式更新,就是删一个建一个(如果有一百个容器则会比较慢)
-
rollingUpdate
滚动更新,更新期间pod最多有几个(相当与多线程操作,这边删,那边创),滚动更新在创建的时候最多不能超过25%,最大有25%的副本数量在不可用(删除)
示例
## 更新;把apache升级成nginx # 先查看原有配置及测试 ~]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapache-9d7557448-brsbc 1/1 Running 0 31m 10.244.2.4 vm-0-142-centos <none> <none> ~]# curl -ik http://10.244.2.4 this is apache # 在线修改 ...... kubernetes.io/change-cause: nginx.v1 # 版本名 ..... - image: 172.17.0.98:5000/myos:nginx # 更新的镜像 ..... # 查看 ]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapache-5886d7b69b-bl7l4 0/1 Running 6 (3m42s ago) 9m34s 10.244.1.6 vm-0-114-centos <none> <none> ~]# curl -ik http://10.244.2.4 this is nginx ## 回滚 # 查看历史记录 ~]# kubectl rollout history deployment myapache deployment.apps/myapache REVISION CHANGE-CAUSE 1 httpd.v1 2 nginx.v1 # 回滚 ~]# kubectl rollout undo deployment myapache --to-revision=1 deployment.apps/myapache rolled back ~]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapache-9d7557448-8gv62 1/1 Running 0 9m59s 10.244.2.6 vm-0-142-centos <none> <none> ~]# curl -ik http://10.244.2.4 this is apache
3.集群调度
容器的创建是随机的,如何选择固定的宿主机
1)nodeName标签
容器创建是随机的,选择nodeName固宿主机
# 先查看原有的pod ~]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapache-9d7557448-8gv62 1/1 Running 0 15h 10.244.2.6 node2 <none> <none> # 可以看出容器在node2上,那么此时修改yaml文件更新 ~]#vim myapache.yaml --- kind: Deployment apiVersion: apps/v1 metadata: name: myapache annotations: kubernetes.io/change-cause: httpd.v1 spec: selector: matchLabels: myapp: httpd replicas: 1 template: metadata: labels: myapp: httpd spec: nodeName: node1 # 在该配置文件中添加一行使其调度到node1 containers: - name: webcluster image: 172.17.0.98:5000/myos:httpd stdin: false tty: false ports: - protocol: TCP containerPort: 80 restartPolicy: Always ~]# kubectl apply -f myapache.yaml deployment.apps/myapache configured ~]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapache-58fdbddd8d-m78jv 1/1 Running 0 11s 10.244.1.8 node1 <none> <none>
注:如果添加了选则标签,但无法使用该主机,POD将一直处于Pending状态
使用 nodeName 参数让容器运行在指定节点上
2)nodeSelector标签
如何选择一类宿主机?
需要提前为目标主机打上特定的标签(可以是多台)
在资源文件中根据标签选择宿主机(更加灵活)
node标签的管理
nodeSelector是节点选择约束的最简单推荐形式
-
可以给节点打上标签,根据标签来选择需要的节点(标签名任意)
-
查看标签
# 格式 ~]# kubectl get node --show-labels # 示例 ~]# kubectl get node --show-labels aster Ready control-plane,master 4d16h v1.23.2 beta.kubernetes.io/arch=amd64,....... node1 Ready <none> 2d22h v1.23.2 beta.kubernetes.io/arch=amd64,...... node2 Ready <none> 47h v1.23.2 beta.kubernetes.io/arch=amd64,......
-
设置标签
# 格式 ~]# kubectl label nodes <node-name> <label-key>=<label-value> # 示例,设置磁盘类型为ssd ~]# kubectl label nodes node2 disktype=ssd node/node2 labeled ~]# kubectl get node --show-labels NAME STATUS ROLES AGE VERSION LABELS ...... node2 Ready <none> 47h v1.23.2 .....disktype=ssd........
- 删除标签
# 格式 ~]# kubectl label nodes <node-name> <label-key>- # 示例 ~]# kubectl label nodes node2 disktype- node/node2 unlabeled ~]# kubectl get node --show-labels NAME STATUS ROLES AGE VERSION LABELS master Ready control-plane,master 4d16h v1.23.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=master,kubernetes.io/os=linux,node-role.kubernetes.io/control-plane=,node-role.kubernetes.io/master=,node.kubernetes.io/exclude-from-external-load-balancers= node1 Ready <none> 2d22h v1.23.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=vm-0-114-centos,kubernetes.io/os=linux node2 Ready <none> 47h v1.23.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=vm-0-142-centos,kubernetes.io/os=linux
- 使用 标签 让容器运行在一些节点上
运用资源文件把容器跑在有标签的节点组上
# 先运行标签 ~]# kubectl label nodes node2 disktype=ssd node/node2 labeled # 修改配置文件 ]# cat myapache.yaml --- kind: Deployment apiVersion: apps/v1 metadata: name: myapache annotations: kubernetes.io/change-cause: httpd.v1 spec: selector: matchLabels: myapp: httpd replicas: 1 template: metadata: labels: myapp: httpd spec: nodeSelector: # 添加标签组 disktype: ssd # 绑定刚刚创建的标签 containers: - name: webcluster image: 172.17.0.98:5000/myos:httpd stdin: false tty: false ports: - protocol: TCP containerPort: 80 restartPolicy: Alwa ~]# kubectl get node --show-labels NAME STATUS ROLES AGE VERSION LABELS ........ node2 Ready <none> 47h v1.23.2 disktype=ssd,..... ~]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapache-7d685d5d66-shd86 1/1 Running 0 42s 10.244.2.7 node2 <none>
3)高级调度策略
亲和与反亲和
亲和可以理解成偏爱或喜好,同样反亲和可以理解成不喜欢
在kubernetes 中亲和特性在pod. spec. affinity中设置
从亲和的对象又可以分为(节点亲和)和(容器亲和)
从亲和的策略又可以分为(硬亲和)和(软亲和)
手册地址:
pod节点亲和示例
亲和示例
## 非强制性亲和示例 # 先创建节点标签 ~]# kubectl label nodes node2 app=myapp-apache # 创建yaml文件 ~]# vim web-example.yaml --- apiVersion: apps/v1 kind: Deployment metadata: name: web-example spec: selector: matchLabels: app: myapp-web replicas: 3 revisionHistoryLimit: 10 strategy: rollingUpdate: maxSurge: 25% maxUnavailable: 25% type: RollingUpdate template: metadata: labels: app: myapp-web spec: affinity: podAffinity: # pod的亲和设置 preferredDuringSchedulingIgnoredDuringExecution: # 亲和性,表示更倾向于部署在指定节点上,但不是必须的 - weight: 1 # weight范围1-100。这个涉及调度器的优选打分过程,每个node的评分都会加上这个weight,最后bind最高的node podAffinityTerm: #指定pod要调度在含有标签app=myapp-apache的节点上 labelSelector: # 连接的标签组 matchExpressions: - key: app operator: In values: - myapp-apache topologyKey: kubernetes.io/hostname # 用topologyKey表示,具体值用node label表示,调度器需要考虑这些pods是否满足规则Y containers: - name: nginx image: 172.17.0.98:5000/myos:httpd ports: - protocol: TCP containerPort: 80 restartPolicy: Always # 创建 ~]# kubectl apply -fweb-example.yaml deployment.apps/web-example configured # 查看调度 ~]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES web-example-558fd5cd9b-gs7v4 1/1 Running 0 9s 10.244.1.9 node1 <none> <none> web-example-558fd5cd9b-jlx97 1/1 Running 0 6s 10.244.1.10 node2 <none> <none> web-example-558fd5cd9b-tl67p 1/1 Running 0 7s 10.244.2.17 node2 <none> <none> # affinity.podAffinity第二个表示创建的3个pod部署时要满足倾向性亲和性,创建的3个pod更倾向于部署在Pod的标签为app=myapp-apache所在的节点上,并且所在的节点要含有kubernetes.io/hostname标签。如下所示,上设置,app=myapp-apache的pod在kus-node2节点上,新创建的3个pod调度时要满足倾向性亲和性,最终2个pod调度在了k8s-node2上,1个pod调度在了k8s-node1上,更倾向于调度在k8s-node2上
# 强制亲和性 ~]# vim web-example.yaml --- apiVersion: apps/v1 kind: Deployment metadata: name: web-example spec: selector: matchLabels: app: myapp-web replicas: 3 revisionHistoryLimit: 10 strategy: # 设置滚动升级 rollingUpdate: maxSurge: 25% maxUnavailable: 25% type: RollingUpdate template: metadata: labels: app: myapp-web spec: # pod设置 nodeName: vm-0-142-centos nodeSelector: # 指定标签 disktype: ssd affinity: # 亲和设置 podAffinity: # pod的亲和设置 requiredDuringSchedulingIgnoredDuringExecution: #强制亲和性 - labelSelector: # 连接的标签组 matchExpressions: #指定pod要调度在含有标签app=myapp-apache的节点上 - key: app operator: In values: - myapp-apache topologyKey: kubernetes.io/hostname # 必须也要满足此标签要求 containers: - name: nginx image: 172.17.0.98:5000/myos:httpd ports: - protocol: TCP containerPort: 80 restartPolicy: Always # affinity.podAffinity第一个表示部署apache时会创建3个pod,并且这3个pod要满足强制亲和性,要调度在节点含有标签为app=myapp-apache的pod,并且,调度的节点要含有标签kubernetes.io/hostname。如上设置,app=myapp-apache的pod在kus-node2节点上,所以创建的3个pod全部调度在了k8s-node2节点上
反亲和示例
就是把podAffinity替换成podAntiAffinity
# 强制 ~]# vim web-example.yaml --- apiVersion: apps/v1 kind: Deployment metadata: name: web-example spec: selector: matchLabels: app: myapp-web replicas: 3 revisionHistoryLimit: 10 strategy: rollingUpdate: maxSurge: 25% maxUnavailable: 25% type: RollingUpdate template: metadata: labels: app: myapp-web spec: nodeName: vm-0-142-centos nodeSelector: disktype: ssd affinity: podAntiAffinity: # pod的反亲和设置 requiredDuringSchedulingIgnoredDuringExecution: # - labelSelector: matchExpressions: - key: app operator: In values: - myapp-apache topologyKey: kubernetes.io/hostname containers: - name: nginx image: 172.17.0.98:5000/myos:httpd ports: - protocol: TCP containerPort: 80 restartPolicy: Always
# 非强制 ~]# vim web-example.yaml --- apiVersion: apps/v1 kind: Deployment metadata: name: web-example spec: selector: matchLabels: app: myapp-web replicas: 3 revisionHistoryLimit: 10 strategy: rollingUpdate: maxSurge: 25% maxUnavailable: 25% type: RollingUpdate template: metadata: labels: app: myapp-web spec: affinity: podAntiAffinity: # pod的反亲和设置 preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 podAffinityTerm: labelSelector: matchExpressions: - key: app operator: In values: - myapp-apache topologyKey: kubernetes.io/hostname containers: - name: nginx image: 172.17.0.98:5000/myos:httpd ports: - protocol: TCP containerPort: 80 restartPolicy: Always
node节点亲和示例
## 反亲和性 ~]# vim web-example.yaml --- apiVersion: apps/v1 kind: Deployment metadata: name: web-example spec: selector: matchLabels: app: myapp-web replicas: 3 revisionHistoryLimit: 10 strategy: rollingUpdate: maxSurge: 25% maxUnavailable: 25% type: RollingUpdate template: metadata: labels: app: myapp-web spec: affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: # 反亲和性,表示更倾向于部署在指定节点上,但不是必须的 - weight: 1 preference: matchExpressions: - key: cpu operator: In values: - high containers: - name: nginx image: 172.17.0.98:5000/myos:httpd ports: - protocol: TCP containerPort: 80 restartPolicy: Always # 创建容器 ~]# kubectl apply -f web-example.yaml deployment.apps/web-example configured # 查看 ]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES web-example-64d897b884-f8gz5 1/1 Running 0 4s 10.244.2.31 node2 <none> <none> web-example-64d897b884-fqkj8 1/1 Running 0 5s 10.244.1.20 node1 <none> <none> web-example-64d897b884-pdsln 1/1 Running 0 7s 10.244.2.30 node2 <none> <none> #因为非强制所以都可以分配 ## 强制反亲和性 ~]# vim web-example.yaml --- apiVersion: apps/v1 kind: Deployment metadata: name: php-example spec: selector: matchLabels: app: myapp-php replicas: 1 template: metadata: labels: app: myapp-php spec: affinity: requiredDuringSchedulingIgnoredDuringExecution: #强制反亲和性 nodeSelectorTerms: - matchExpressions: - key: mem operator: In values: - high - mid containers: - name: php-fpm image: 192.168.1.100:5000/myos:php-fpm ports: - protocol: TCP containerPort: 9000 restartPolicy: Always # 查看pod的启动此时就可以看到处于pengding状态了 ]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES 10.244.2.30 node2 <none> <none> web-example-77647fb5fd-85g4m 0/1 Pending 0 3s <none> <none> <none> <none> # 是因为几台节点上都没有标签所以不知道跳哪天导致的报错,这里给node1设置一个标签,就可以跳到node2上 ~]# kubectl label node vm-0-114-centos mem=high ]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES web-example-77647fb5fd-85g4m 1/1 Running 0 14m 10.244.1.21 node1 <none> <none> web-example-77647fb5fd-9bc9f 1/1 Running 0 41s 10.244.1.22 node1 <none> <none> web-example-77647fb5fd-9vf4k 1/1 Running 0 39s 10.244.1.23 node1 <none> <none>