一、集群管理命令
kubectl 是用于控制 kubernetes集群的命令工具
语法格式:
kubectl [command] [TYPE] [NAME] [flags]
command: 子命令,如create、get、describe、delete
type: 资源类型,可以表示单数,复数或缩写形式
name: 资源的名称,如果省略,泽显示所有资源信息
flags: 指定可选标志,或附加的参数
子命令说明help用于查看命令及子命令的帮助信息cluster-info显示集群的相关配置信息version查看服务器及客户端的版本信息api-resources查看当前服务器上所有的资源对象api-versions查看当前服务器上所有资源对象的版本config管理当前节点上kubeconfig 的认证信息
二、命名空间
Namespace是kubernetes系统中的一种非常重要资源,它的主要作用是用来实现多套环境的资源隔离或者多租户的资源隔离。
1. 获取命名空间列表
[root@master ~]# kubectl get ns # 简写
[root@master ~]# kubectl get namespaces # 全写
[root@master ~]# kubectl -n 命名空间 get pods # 查看命名空间中的资源对象
2. 创建命名空间
[root@master ~]# kubectl create ns your_namespace # 简写, 其中:your_namespace 为你自己的命名空间名称
[root@master ~]# kubectl create namespace your_namespace # 全写, 其中:your_namespace 为你自己的命名空间名称
3. 删除命名空间
[root@master ~]# kubectl delete namespace your_namespace # 简写, 其中:your_namespace 为你自己的命名空间名称
[root@master ~]# kubectl delete namespace your_namespace # 全写, 其中:your_namespace 为你自己的命名空间名称
4. 查看命名空间详情
[root@master ~]# kubectl describe ns your_namespace # your_namespace 为你自己的命名空间名称
三、Pod
1. Pod概述
- 由一个容器或多个容器组成(最少一个容器)
- 是k8s中最小的管理元素
- 同一个Pod 共享IP及权限,主机名称,共享存储设备,命名空间
- 每个Pod都会存在一个Pause根容器,这是每一个Pod都会去运行的。它就像一个基石,为Pod中的其他容器提供基础运行环境。Pause容器会加载所有必要的运行时、内核模块和设备驱动,以确保Pod中的所有容器都能在相同的网络和命名空间中运行。
- 其他的资源对象都是用来支撑或者扩展Pod对象功能的。
2. Pod相位状态
-- Pending: Pod创建过程中,但它尚未被调度完成
-- Running: Pod中所有容器都被创建成功
-- Completed或者**successd: **Pod所有容器都已经成功终止,并不会被重启
-- **Failed: **Pod中的所有容器至少有一个容器退出是非0状态
-- **Unkown: **无法正常获取Pod对象的状态信息
3. 管理命令
3.1 获取命名空间下容器(pod)列表
[root@master ~]# kubectl get pods -n your_namespace -o wide -w # your_namespace为你自己的命名空间名称
-n 指定命名空间
-o wide 显示更加详细信息
-o name 只显示名字
-o yaml/json 以yaml/json语法格式显示资源对象
-w 持续监听
3.2 查看pod的详细信息
[root@master ~]# kubectl describe pod your_pod -n your_namespace # your_pod为自己的pod名称,your_namespace为你自己的命名空间名称
3.3 创建 && 运行
[root@master ~]# kubectl run [pod名称] --image=[镜像]:[镜像版本] --port=[对外端口] --namespace [namespace]
3.4 删除pod
[root@master ~]# kubectl delete pod [pod名称] -n [命名空间名称]
删除会再次出现?
因为pod是隶属于Pod控制器下,控制器会监控pod的健康值,出现问题会重启几次失败后删除重新创建,所以会出现删除在出现的问题。
3.5 进入容器
[root@master ~]# kubectl exec your_pod -c 容器名称 -n your_namespace -it /bin/bash
# 在容器内执行命令
[root@master ~]# kubectl exec myweb -- ls
50x.html
index.html
若有很多容器
# 获取pod列表
[root@node2 ~]# kubectl get pods -n your_namespace
NAME READY STATUS RESTARTS AGE
nginx-64777cd554-c2k5n 2/2 Running 2 23h
# 获取pod详情
# - your_pod 你的pd名称, 对应上面 nginx-64777cd554-c2k5n
[root@node2 ~]# kubectl describe pod your_pod -n your_namespace
...其他配置
Controlled By: ReplicaSet/nginx-replicaset
Containers:
nginx: # ***容器名称***
Container ID: docker://42534954660b49806772a7df127267f399652fcaef18b26c619363e1283d6c8c
Image: nginx:1.17.1
Image ID: docker-pullable://nginx@sha256:b4b9b3eee194703fc2fa8afa5b7510c77ae70cfba567af1376a573a967c03dbb
...其他配置
# 进入容器内部
# - your_container 你的容器名称,对应上面获取pod详情结果的 nginx
[root@master ~]# kubectl exec your_pod -n your_namespace -it -c your_container /bin/bash
3.6 根据资源对象文件运行命令
[root@master ~]# kubectl create/apply/delete -f 资源文件名称.yaml
- create 创建文件中定义的资源 kubectl create .... --dry-run=client -o yaml(create主要用来生成资源对象的模板,我们一般都是用apply)
- apply 创建(更新)文件中定义的资源 (主要用的就是这个)
- delete 删除文件中定义的资源
3.7 排错三兄弟
- kubectl get 查看资源对象的状态信息)
- kubectl describe 查询资源对象的属性信息 Events下是事物日志,用来排错
- Kubectl logs 查看容器报错信息
# 查看 work 名称空间下的 pod 信息
[root@master ~]# kubectl -n work describe pod myhttp
Name: myhttp
Namespace: work
Priority: 0
Service Account: default
Node: node-0004/192.168.1.54
... ...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 12m default-scheduler Successfully assigned work/myhttp
to node-0004
Normal Pulling 12m kubelet Pulling image "myos:httpd"
Normal Pulled 12m kubelet Successfully pulled image
"myos:httpd" in 3.678925795s (3.678930716s including waiting)
Normal Created 12m kubelet Created container myhttp
Normal Started 12m kubelet Started container myhttp
# 查看 myweb 日志
[root@master ~]# kubectl logs myweb
2023/09/14 09:42:38 [error] 7#0: *2 open() "/usr/local/nginx/html/info.php"
failed (2: No such file or directory), client: 10.244.219.64, server: localhost,
request: "GET /info.php HTTP/1.1", host: "10.244.243.193"
2023/09/14 09:44:46 [error] 6#0: *4 open() "/usr/local/nginx/html/info.php"
failed (2: No such file or directory), client: 10.244.219.64, server: localhost,
request: "GET /info.php HTTP/1.1", host: "10.244.243.193"
2023/09/14 09:51:08 [error] 6#0: *5 open() "/usr/local/nginx/html/info.php"
failed (2: No such file or directory), client: 10.244.219.64, server: localhost,
request: "GET /info.php HTTP/1.1", host: "10.244.243.193"
4. 污点策略
4.1 概述
- 污点(Taint)是使节点与Pod产生排斥的一类规则
- 污点策略通过嵌合在键值对上的污点标签进行声明
- 污点的格式为:**
key=value:effect
**, key和value是污点的标签,effect描述污点的作用- 污点标签 - PreferNoSchedule:kubernetes将尽量避免把Pod调度到具有该污点的Node上,除非没有其他节点可调度- NoSchedule:kubernetes将不会把Pod调度到具有该污点的Node上,但不会影响当前Node上已存在的Pod- NoExecute:kubernetes将不会把Pod调度到具有该污点的Node上,同时也会将Node上已存在的Pod驱离
- 管理污点标签- 查看污点标签 kubectl describe nodes [节点名字]- 设置污点标签 kubectl taint node [节点名字] key=value:污点标签- 删除污点标签 kubectl taint node [节点名字] key=value:污点标签-
4.2 设置并查看污点标签
# node01 设置污点策略 PreferNoSchedule
[root@master ~]# kubectl taint node node01 k=v1:PreferNoSchedule
node/node01 tainted
# 查看污点
[root@master ~]# kubectl describe node node01
Name: node01
Roles: <none>
Labels: beta.kubernetes.io/arch=amd64
beta.kubernetes.io/os=linux
kubernetes.io/arch=amd64
kubernetes.io/hostname=node01
kubernetes.io/os=linux
Annotations: flannel.alpha.coreos.com/backend-data: {"VNI":1,"VtepMAC":"ce:d8:30:f2:9b:b0"}
flannel.alpha.coreos.com/backend-type: vxlan
flannel.alpha.coreos.com/kube-subnet-manager: true
flannel.alpha.coreos.com/public-ip: 192.168.1.101
kubeadm.alpha.kubernetes.io/cri-socket: /var/run/dockershim.sock
node.alpha.kubernetes.io/ttl: 0
volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp: Mon, 25 Dec 2023 12:15:15 +0800
Taints: taint=v1:PreferNoSchedule # 污点标签
Unschedulable: false
...其他设置内容
4.3 删除污点标签
[root@master ~]# kubectl taint node node01 k-
node/node01 untainted
四、资源对象文件
1. 资源对象文件相关帮助
1.1 Pod的资源清单
apiVersion: v1 #必选,版本号,例如v1
kind: Pod #必选,资源类型,例如 Pod
metadata: #必选,元数据
name: string #必选,Pod名称
annotations: #选做,描述信息
nginx: nginx
namespace: string #Pod所属的命名空间,默认为"default"
labels: #自定义标签列表
- name: string
spec: #必选,Pod中容器的详细定义
containers: #必选,Pod中容器列表
- name: string #必选,容器名称
image: string #必选,容器的镜像名称
imagePullPolicy: [ Always|Never|IfNotPresent ] #获取镜像的策略
command: [string] #容器的启动命令列表,如不指定,使用打包时使用的启动命令
args: [string] #容器的启动命令参数列表
workingDir: string #容器的工作目录
volumeMounts: #挂载到容器内部的存储卷配置
- name: string #引用pod定义的共享存储卷的名称,需用volumes[]部分定义的的卷名
mountPath: string #存储卷在容器内mount的绝对路径,应少于512字符
readOnly: boolean #是否为只读模式
ports: #需要暴露的端口库号列表
- name: string #端口的名称
containerPort: 80 #容器需要监听的端口号
hostPort: int #容器所在主机需要监听的端口号,默认与Container相同
protocol: string #端口协议,支持TCP和UDP,默认TCP
env: #容器运行前需设置的环境变量列表
- name: string #环境变量名称
value: string #环境变量的值
resources: #资源限制和请求的设置
limits: #资源限制的设置(上限)
cpu: string #Cpu的限制,单位为core数,将用于docker run --cpu-shares参数
memory: string #内存限制,单位可以为Mib/Gib,将用于docker run --memory参数
requests: #资源请求的设置(下限)
cpu: string #Cpu请求,容器启动的初始可用数量
memory: string #内存请求,容器启动的初始可用数量
lifecycle: #生命周期钩子
postStart: #容器启动后立即执行此钩子,如果执行失败,会根据重启策略进行重启
preStop: #容器终止前执行此钩子,无论结果如何,容器都会终止
livenessProbe: #对Pod内各容器健康检查的设置,当探测无响应几次后将自动重启该容器
exec: #对Pod容器内检查方式设置为exec方式
command: [string] #exec方式需要制定的命令或脚本
httpGet: #对Pod内个容器健康检查方法设置为HttpGet,需要制定Path、port
path: string
port: number
host: string
scheme: string
HttpHeaders:
- name: string
value: string
tcpSocket: #对Pod内个容器健康检查方式设置为tcpSocket方式
port: number
initialDelaySeconds: 0 #容器启动完成后首次探测的时间,单位为秒
timeoutSeconds: 0 #对容器健康检查探测等待响应的超时时间,单位秒,默认1秒
periodSeconds: 0 #对容器监控检查的定期探测时间设置,单位秒,默认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名称,以key:secretkey格式指定
- name: string
hostNetwork: false #是否使用主机网络模式,默认为false,如果设置为true,表示使用宿主机网络
volumes: #在该pod上定义共享存储卷列表
- name: string #共享存储卷名称 (volumes类型有很多种)
emptyDir: {} #类型为emtyDir的存储卷,与Pod同生命周期的一个临时目录。为空值
hostPath: string #类型为hostPath的存储卷,表示挂载Pod所在宿主机的目录
path: string #Pod所在宿主机的目录,将被用于同期中mount的目录
secret: #类型为secret的存储卷,挂载集群与定义的secret对象到容器内部
scretname: string
items:
- key: string
path: string
configMap: #类型为configMap的存储卷,挂载预定义的configMap对象到容器内部
name: string
items:
- key: string
path: string
1.1 最基础Pod资源对象文件
[root@master ~]# vim myweb.yml
--- # Yaml文件起始标志
kind: Pod # 当前创建资源的类型
apiVersion: v1 # 当前资源对应的版本
metadata: # 属性信息,元数据,包括名字和其他标识符等。这些信息对于识别和管理Pod很有用
name: myweb # 属性信息,资源的名称
spec: # 资源的特性描述(规约),定义Pod具体行为的部分
containers: # 容器资源特征描述
- name: webserver # 容器名称
image: myos:nginx # 启动容器使用的镜像
status: {} # 资源状态,运行后自动生成(一般不写这行)
1.3 自动生成模板命令
生成模板命令: [ --dry-run=client -o yaml]
[root@master ~]# kubectl run myweb --image=myos:nginx --dry-run=client -o yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: myweb
name: myweb
spec:
containers:
- image: myos:nginx
name: myweb
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
1.4 查询帮助信息
[root@master ~]# kubectl explain Pod.spec.restartPolicy
KIND: Pod
VERSION: v1
FIELD: restartPolicy <string>
DESCRIPTION:
Restart policy for all containers within the pod. One of Always, OnFailure,
Never. Default to Always. More info:
https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy
Possible enum values:
- `"Always"`
- `"Never"`
- `"OnFailure"`
资源文件参数使用"."分割层级结构关系
---
kind: xxx # 一级,可以表示为 .kind
apiVersion: xx # 一级,可以表示为 .apiVersion
metadata: # 一级,可以表示为 .metadata
name: xx # 二级,可以表示为 .metadata.name
spec: # 一级,可以表示为 .spec
restartPolicy: xx # 二级,可以表示为 .spec.restartPolicy
containers: # 二级,可以表示为 .spec.containers
- name: xx # 三级,可以表示为 .spec.containers.name
image: xx # 三级,可以表示为 .spec.containers.image
status: {} # 一级,可以表示为 .status
2. Pod
2.1 Pod自定义命令
- 创建Pod时,启动时要执行的自定义命令,如果配置了自定义命令,那镜像中自带的默认命令将不再执行
- 蓝色的,是固定的,下面红色的是变化,可以理解上面蓝色的就是一个模板
[root@master ~]# vim myweb.yml
---
kind: Pod
apiVersion: v1
metadata: # 属性信息,元数据,包括名字和其他标识符等。这些信息对于识别和管理Pod很有用
name: myweb
spec: # 资源的特性描述(规约),定义Pod具体行为的部分
containers:
- name: webserver
image: myos:nginx
command: ["/bin/bash"]
args:
- -c
- |
while sleep 5;do
echo "hello world"
done
2.2 restartPolicy 保护策略
- 指在系统发生故障或意外停机时,系统或应用程序如何处理和恢复的策略
- 重启[Always] -- 不重启[Never] -- 失败就重启[OnFailure]
- Pod会根据策略决定容器结束后是否重启
[root@master ~]# vim mycmd.yaml
---
kind: Pod
apiVersion: v1
metadata:
name: mycmd
spec:
restartPolicy: Never # 配置保护策略
containers:
- name: linux
image: myos:8.5
command: ["sleep"]
args: ["30"]
2.3 terminationGracePeriodSeconds 宽限期策略
- 是K8s中的Pod生命周期策略之一,当容器运行完自己的任务后,会等待一段时间,然后优雅的退出
- 宽限期为避免服务突然中断,造成事物不一致的问题
- 宽限期默认 30s 不等待为 0s
[root@master ~]# vim mycmd.yaml
---
kind: Pod
apiVersion: v1
metadata:
name: mycmd
spec:
terminationGracePeriodSeconds:0 # 设置宽限期
restartPolicy: Never
containers:
- name: linux
image: myos:8.5
command: ["sleep"]
args: ["30"]
2.4 activeDeadlineSeconds 策略
- 是K8s中的Pod生命周期策略之一
- 允许Pod运行的最大时长
- 如果一个Pod的内部程序在运行时出现循环死锁,那么就会永远不停的重复执行,为避免出现循环死索,允许Pod运行的最大时长,等到时间后,强制关闭,并设置Error状态
[root@master ~]# vim mycmd.yaml
---
kind: Pod
apiVersion: v1
metadata:
name: mycmd
spec:
terminationGracePeriodSeconds: 0
activeDeadlineSeconds: 60 # 可以执行的最大时长
restartPolicy: Never
containers:
- name: linux
image: myos:8.5
command: ["sleep"]
args: ["300"]
2.5 多容器Pod
- 受影响的命令: [log , exec , cp ]
- 需要以上命令后加 -c 容器名
[root@master ~]# vim mynginx.yaml
---
kind: Pod
apiVersion: v1
metadata:
name: mynginx
spec:
terminationGracePeriodSeconds: 0
restartPolicy: Always
containers: # 容器资源是个数组,可以定义多个Pod
- name: nginx # 容器名称
image: myos:nginx # 启动容器使用的镜像
- name: php # 容器名称
image: myos:php-fpm # 启动容器使用的镜像
注意:如果启动多容器,也根据提供的配置文件,没有明确指定每个容器的端口信息,那就需要在一个Pod中,每个容器需要使用不同的端口来避免冲突
[root@master ~]# vim web2.yaml
---
kind: Pod
apiVersion: v1
metadata:
name: web2
spec:
containers:
- name: httpd
image: myos:httpd
ports:
- containerPort: 80 # 指定该容器端口80
- name: nginx
image: myos:nginx
ports:
- containerPort: 8080 # 指定该容器端口8080
3. Pod容忍策略
- 容忍刚好和污点相反,某些时候我们需要在有污点的节点上运行Pod,这种无视污点标签的调度方式成为容忍
- 精确匹配: 下面3个条件必须写全 模糊匹配: 不需要写全
3.1 精确匹配策略
把effect: "" 改成这个样子代表容忍所有污点
# 容忍 k=v1:NoSchedule 污点
[root@master ~]# vim myphp.yaml
---
kind: Pod
apiVersion: v1
metadata:
name: myphp
spec:
tolerations: # 定义容忍策略
- operator: Equal # 匹配方式,必选(Equal精确匹配,Exists模糊匹配)
key: k # 设置键值对的key,为空代表任意键值对
value: v1 # 设置values的值
effect: NoSchedule # 设置容忍的标签,为空代表所有污点标签
containers:
- name: php
image: myos:php-fpm
3.2 模糊匹配策略
# 容忍 k=*:NoSchedule 污点
[root@master ~]# vim myphp.yaml
---
kind: Pod
apiVersion: v1
metadata:
name: myphp
spec:
tolerations:
- operator: Exists # 部分匹配,存在即可
key: k # 键
effect: NoSchedule # 污点标签
containers:
- name: php
image: myos:php-fpm
4. 优先级与抢占
- 优先级就是为了保证重要的Pod被调度运行
- 通过配置优先级PriorityClass或创建Pod时为其设置对应的优先级来确认优先级
- PriorityClass是一个全局资源对象,它定义了从优先级类名称到优先级整数值的映射。优先级在value字段中指定,可以设置小于10亿的整数值,值越大,优先级越高,默认优先级0
- PriorityClass还有两个可选字段: - globalDefault用于设置默认优先级状态,如果没有任何优先级设置Pod的优先级为零- description用来配置描述性信息,告诉用户优先级的用途
- 优先级策略: - 非抢占优先:指的是在调度阶段优先进行调度分配,一旦容器调度完成就不可以抢占,资源不足时,只能等待- 抢占优先:强制调度一个Pod,如果资源不足无法被调度,调度程序会抢占(删除)较低优先级的Pod的资源,来保证高优先级Pod的运行
4.1 非抢占优先级
创建新的优先级策略
# 定义优先级(队列优先)
[root@master ~]# vim mypriority.yaml
---
kind: PriorityClass
apiVersion: scheduling.k8s.io/v1
metadata:
name: high-non # 优先级名称
preemptionPolicy: Never # 策略:非抢占
value: 1000 # 优先级
---
kind: PriorityClass
apiVersion: scheduling.k8s.io/v1
metadata:
name: low-non # 优先级名称
preemptionPolicy: Never # 策略:非抢占
value: 500 # 优先级
# 运行并查看优先级
[root@master ~]# kubectl apply -f mypriority.yaml
priorityclass.scheduling.k8s.io/high-non created
priorityclass.scheduling.k8s.io/low-non created
[root@master ~]# kubectl get priorityclasses.scheduling.k8s.io
NAME VALUE GLOBAL-DEFAULT AGE
high-non 1000 false 12s
low-non 500 false 12s
system-cluster-critical 2000000000 false 45h
system-node-critical 2000001000 false 45h
创建pod
[root@master ~]# vim php2.yaml
---
kind: Pod
apiVersion: v1
metadata:
name: php2
spec:
nodeSelector:
kubernetes.io/hostname: node01
priorityClassName: low-non # 优先级名称
containers:
- name: php
image: myos:php-fpm
4.2 抢占优先级
创建新的优先级策略
[root@master ~]# vim mypriority.yaml
---
kind: PriorityClass
apiVersion: scheduling.k8s.io/v1
metadata:
name: high
preemptionPolicy: PreemptLowerPriority #抢占策略
value: 1000
---
kind: PriorityClass
apiVersion: scheduling.k8s.io/v1
metadata:
name: low
preemptionPolicy: PreemptLowerPriority #抢占策略
value: 500
# 运行并查看优先级策略
[root@master ~]# kubectl apply -f mypriority.yaml
priorityclass.scheduling.k8s.io/high-non created
priorityclass.scheduling.k8s.io/low-non created
priorityclass.scheduling.k8s.io/high created
priorityclass.scheduling.k8s.io/low created
[root@master ~]# kubectl get priorityclasses.scheduling.k8s.io
NAME VALUE GLOBAL-DEFAULT AGE
high 1000 false 2m56s
low 500 false 2m56s
system-cluster-critical 2000000000 false 7d22h
system-node-critical 2000001000 false 7d22h
5. Pod调度策略
- 将Pod分配到合适的计算节点上,并运行 -- kube-scheduler 默认调度器
- 什么是调度分配? - 在k8s中,调度是将Pod分配到合适的计算节点上,然后对应节点上的Kubelet运行这些pod- kube-scheduler是默认调度器,是集群的核心组件
- 调度器是如何工作的? - 调度器通过k8s的监测(Watch)机制来发现集群中尚未被调度到节点上的Pod。调度器依据调度原则将Pod分配到一个合适的节点上运行。
- 调度流程 - 调度器给一个pod做调度选择包含两个步骤: 过滤和打分
- 第一步过滤(筛选) - 首先要筛选出满足Pod所有的资源请求的节点,这里包含计算资源、内存、存储、网络、端口号等等,如果没有节点能满足Pod的需求,Pod将一直停留在Pending状态,直到调度器能够找到合适的节点运行它
- 第二步打分(优选): - 在打分阶段,调度器会根据打分规则,为每一个课调度节点进行打分。选出其中得分最高的节点来运行Pod。如果存在多个得分最高的节点,调度器会从中随机选取一个。
- 绑定 - 在确认了某个节点运行Pod之后,调度器将这个调度决定通知给kube-apiserver,这个过程叫做绑定
5.1 定向调度
- 基于节点名称的调度
- 在 spec下面,添加nodeName标签,让Pod运行在指定节点上面,若指标节点无法运行,它会一直等下去,现实pending
[root@master ~]# vim myhttp.yaml
---
kind: Pod
apiVersion: v1
metadata:
name: myhttp
spec:
nodeName: node-0001 # 基于节点名进行调度
containers:
- name: apache
image: myos:httpd
5.2 标签调度
- Pod标签调度是指通过在Pod上设置标签(Label),将Pod调度到具有匹配标签的节点上,可以匹配到多个节点,也可以一个节点都匹配不到。
- Pod标签调度是通过在Pod配置文件中设置nodeSelector字段来实现的
- 查看筛选标签 - 使用--show-labels查询标签
- 管理标签语法格式 - 设置标签 kubectl label 资源类型 [资源名称] =- 删除标签 kubectl label 资源类型 [资源名称] -- 查看标签 kubectl label 资源类型 [资源名称] --show-labels- 使用标签选择 kubectl get 资源类型 [资源名称] -l =
[root@master ~]# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
myhttp 1/1 Running 1 (3m18s ago) 15h <none>
[root@master ~]# kubectl get namespaces --show-labels
NAME STATUS AGE LABELS
default Active 6d17h kubernetes.io/metadata.name=default
kube-node-lease Active 6d17h kubernetes.io/metadata.name=kube-node-lease
kube-public Active 6d17h kubernetes.io/metadata.name=kube-public
kube-system Active 6d17h kubernetes.io/metadata.name=kube-system
# 使用标签过滤资源对象
[root@master ~]# kubectl get nodes -l kubernetes.io/hostname=master
NAME STATUS ROLES AGE VERSION
master Ready control-plane 6d18h v1.26.0
# 添加标签
[root@master ~]# kubectl label pod myhttp app=apache
pod/myhttp labeled
[root@master ~]# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
myhttp 1/1 Running 1 (39m ago) 15h app=apache
# 删除标签
[root@master ~]# kubectl label pod myhttp app-
pod/myhttp unlabeled
[root@master ~]# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
myhttp 1/1 Running 1 (40m ago) 15h <none>
使用系统标签调度
[root@master ~]# kubectl get nodes node-0002 --show-labels
NAME STATUS ROLES AGE VERSION LABELS
node-0002 Ready <none> 5d22h v1.26.0
beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd6
4,kubernetes.io/hostname=node-0002,kubernetes.io/os=linux
[root@master ~]# vim myhttp.yaml
---
kind: Pod
apiVersion: v1
metadata:
name: myhttp
labels:
app: apache
spec:
nodeSelector: # 基于节点标签进行调度
kubernetes.io/hostname: node-0002 # 标签
containers:
- name: apache
image: myos:httpd
[root@master ~]# kubectl apply -f myhttp.yaml
pod/myhttp created
[root@master ~]# kubectl get pods -l app=apache -o wide
NAME READY STATUS RESTARTS AGE IP NODE
myhttp 1/1 Running 0 23s 10.244.147.7 node-0002
6. Pod资源管理
- 是K8s中用于限制和约束集群中各个命名空间或项目使用资源的方式,避免资源争用和浪费
- Pod资源配额可以限制命名空间或项目中Pod使用的CPU、内存、存储等资源的数量
- 设置resources字段,来实现资源管理
CPU资源类型
- CPU资源的约束和请求以豪核(m)为单位。在k8s中1m是最小的调度单元,CPU的一个核心可以看作1000m
- 如果你有2颗cpu,且每CPU为4核心,那么你的CPU资源总量就是8000
1. 内存资源配额
[root@master ~]# vim minpod.yaml
---
kind: Pod
apiVersion: v1
metadata:
name: minpod
spec:
nodeSelector: # 配置Pod调度节点
kubernetes.io/hostname: node-0003 # 在node-0003节点创建
terminationGracePeriodSeconds: 0
containers:
- name: linux
image: myos:8.5
command: ["awk","BEGIN{while(1){}}"]
resources: # 资源策略
requests: # 配额策略
memory: 1100Mi # 内存配额
2. 计算资源配额
[root@master ~]# vim minpod.yaml
---
kind: Pod
apiVersion: v1
metadata:
name: minpod
spec:
terminationGracePeriodSeconds: 0
nodeSelector:
kubernetes.io/hostname: node-0003
containers:
- name: linux
image: myos:8.5
command: ["awk","BEGIN{while(1){}}"]
resources: # 资源策略
requests: # 配额策略
cpu: 800m # cpu配额,计算资源配额
3. 综合资源配额
同时设置CPU和内存配额时,资源必须满足全部需求
[root@master ~]# vim minpod.yaml
---
kind: Pod
apiVersion: v1
metadata:
name: minpod
spec:
terminationGracePeriodSeconds: 0
nodeSelector:
kubernetes.io/hostname: node-0003
containers:
- name: linux
image: myos:8.5
command: ["awk","BEGIN{while(1){}}"]
resources:
requests:
cpu: 800m # 计算资源配额
memory: 1100Mi # 内存资源配额
4. 内存 CPU限额
# 创建限额资源对象文件
[root@master ~]# vim maxpod.yaml
---
kind: Pod
apiVersion: v1
metadata:
name: maxpod
spec:
terminationGracePeriodSeconds: 0
containers:
- name: linux
image: myos:8.5
command: ["awk","BEGIN{while(1){}}"]
resources:
limits:
cpu: 800m # 计算资源配额
memory: 2000Mi # 内存资源配额
[root@master ~]# kubectl apply -f maxpod.yaml
pod/maxpod created
7. 全局资源管理
- 如果有大量的容器需要设置资源配额,为每个Pod设置资源配额策略不方便且不好管理。管理员可以以名称空间为单位(namespace),限制其资源的使用与创建。在该名称空间中创建的容器都会受到规则的限制。
- k8s 支持的全局资源配额方式有: - 对单个Pod内存、CPU进行配额:LimitRange- 对资源总量进行配额:ResourceQuota
7.1 LimitRange
# 创建名称空间
[root@master ~]# kubectl create namespace work
namespace/work created
# 设置默认配额
[root@master ~]# vim limit.yaml
---
apiVersion: v1
kind: LimitRange
metadata:
name: mylimit # 策略名称
namespace: work # 规则生效的名称空间
spec:
limits: # 全局规则
- type: Container # 资源类型
default: # 对没有限制策略的容器添加规则
cpu: 300m # 计算资源限额
memory: 500Mi # 内存资源限额
defaultRequest:
cpu: 8m # 计算资源配额
memory: 8Mi # 内存资源配额
[root@master ~]# kubectl -n work apply -f limit.yaml
limitrange/mylimit created
7.2 ResourceQuota
[root@master ~]# vim quota.yaml
---
apiVersion: v1
kind: ResourceQuota # 全局资源限额对象
metadata:
name: myquota # 规则名称
namespace: work # 规则作用的名称空间
spec: # ResourceQuota.spec定义
hard: # 创建强制规则
requests.cpu: 1000m # 计算资源配额总数
requests.memory: 2000Mi # 内存资源配额总数
limits.cpu: 5000m # 计算资源限额总数
limits.memory: 8Gi # 内存资源限额总数
pods: 3 # 限制创建资源对象总量
[root@master ~]# kubectl -n work apply -f quota.yaml
resourcequota/myquota created
五、控制器
- 控制器是什么? - 控制器是k8s内置的管理工具。可以帮助用户实现Pod的自动部署、自维护、扩容、翻滚更新等功能的自动化程序
- 为什么要使用控制器? - 有大量的Pod需要维护管理- 需要维护Pod的健康状态- 控制器可以像机器人一样可以替用户完成维护管理的工作
- Deployment控制器 - 最常用的无状态服务控制器,由Deployment、ReplicaSet、Pod组成、支持集群扩容缩容、滚动、更新、自动维护Pod可用性及副本数量等功能- ReplicaSet和Pod由Deployment自动管理,用户无需干预
1. Deployment
- 功能 - 需要service资源对象来对其资源进行访问- 当集群中有Pod被删除,Deploy会自动创建新的Pod来维护集群的完整性- 当Pod标签去掉时,会被踢出集群(谁有标签谁才可以在集群中)- 集群扩缩容- 滚动更新策略- 历史版本及回滚
** 在这里面,需要新了解的配置项就是spec下面几个选项:**
- replicas:指定副本数量,其实就是当前rs创建出来的pod的数量,默认为1
- selector:选择器,它的作用是建立pod控制器和pod之间的关联关系,采用的Label Selector机制,在pod模板上定义label,在控制器上定义选择器,就可以表明当前控制器能管理哪些pod了
- template:模板,就是当前控制器创建pod所使用的模板板,里面其实就是前一章学过的pod的定义
imagePullPolicy: 是确保容器总是使用最新版本的镜像
- IfNotPresent: 仅当镜像在本地不存在时,才被拉取
- Never:: 设镜像已经存在于本地,不会尝试拉取镜像
- always: 确保每次容器启动时都会拉取最新的镜像
最常用的控制器,资源清单文件:
[root@master ~]# vim mydeploy.yaml
---
kind: Deployment # 资源对象类型
apiVersion: apps/v1 # 版本
metadata: # 元数据
name: myweb # 名称
spec: # 详细定义
replicas: 2 # 副本数量
strategy: # 策略
type: RollingUpdate # 滚动更新策略
rollingUpdate: # 滚动更新
maxSurge: 30% # 最大额外可以存在的副本数,可以为百分比,也可以为整数
maxUnavailable: 30% # 最大不可用状态的 Pod 的最大值,可以为百分比,也可以为整数
selector: # 定义标签选择器
matchLabels: # 支持 matchExpressions 表达式语法
app: httpd # 通过标签来确定那个 Pod 由它来管理
template: # 定义用来创建 Pod 的模板,以下为 Pod 定义
metadata: # Pod元数据
labels: # 名称由控制器生成
app: httpd # 这里只能定义标签
spec: # Pod的详细定义
restartPolicy: Always # 重启策略
containers: # 容器定义
- name: webserver # 容器名称
image: myos:httpd # 创建容器使用的容器
imagePullPolicy: Always # 镜像下载策略
1.1 扩缩容
[root@master ~]# kubectl scale deployment myweb(Deployment名字) --replicas=3(指定Pod数量)
# 1、创建deployment
[root@master ~]# kubectl create -f nginx-deployment.yaml --record=true
deployment.apps/nginx-deployment created
# 2、查看deployment
# UP-TO-DATE 最新版本的pod的数量
# AVAILABLE 当前可用的pod的数量
# - your_namespace 你的命名空间名称
[root@master ~]# kubectl get deploy myweb -n your_spacename
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 15s
[root@master ~]# kubectl get pods -n your_namespace
NAME READY STATUS RESTARTS AGE
nginx-deployment-6696798b78-d2c8n 1/1 Running 0 4m19s
nginx-deployment-6696798b78-jxmdq 1/1 Running 0 94s
nginx-deployment-6696798b78-mktqv 1/1 Running 0 93s
1.2 镜像更新
deployment支持两种更新策略:
重建更新
和
滚动更新
,可以通过
strategy
指定策略类型,支持两个属性:
strategy:指定新的Pod替换旧的Pod的策略, 支持两个属性:
type:指定策略类型,支持两种策略
Recreate:在创建出新的Pod之前会先杀掉所有已存在的Pod
RollingUpdate:滚动更新,就是杀死一部分,就启动一部分,在更新过程中,存在两个版本Pod
rollingUpdate:当type为RollingUpdate时生效,用于为RollingUpdate设置参数,支持两个属性:
maxUnavailable:用来指定在升级过程中不可用Pod的最大数量,默认为25%。
maxSurge: 用来指定在升级过程中可以超过期望的Pod的最大数量,默认为25%。
1.3 滚动更新策略
- deployment支持版本升级过程中的暂停、继续功能以及版本回退等诸多功能,下面具体来看.
- kubectl rollout: 版本升级相关功能,支持下面的选项- status 显示当前升级状态- history 显示 升级历史记录- pause 暂停版本升级过程- resume 继续已经暂停的版本升级过程- restart 重启版本升级过程- undo 回滚到上一级版本(可以使用–to-revision回滚到指定版本)
[root@master ~]# kubectl get deployments.apps myweb -o yaml
......
spec:
revisionHistoryLimit: 10 # 保留10个历史版本
strategy: # 更新策略
rollingUpdate: # 滚动更新策略
maxSurge: 25% # 允许最大副本25%超量
maxUnavailable: 25% # 允许最小副本25%不足
type: RollingUpdate # 更新方式[Recreate,RollingUpdate]
template:
spec:
containers:
- name: webserver
image: myos:httpd
imagePullPolicy: Always # 镜像下载策略[Always,Never,ifNotPresent]
......
# 修改镜像,滚动更新集群
[root@master ~]# kubectl set image deployment myweb webserver=myos:nginx
deployment.apps/myweb image updated
# 给新版本添加注释信息
[root@master ~]# kubectl annotate deployments myweb kubernetes.io/change-
cause="nginx.v1"
deployment.apps/myweb annotated
# 查看历史版本信息
[root@master ~]# kubectl rollout history deployment myweb
deployment.apps/myweb
REVISION CHANGE-CAUSE
1 httpd:v1
2 nginx.v1
# 访问验证服务
[root@master ~]# curl -m 3 http://10.245.1.80
Nginx is running !
1.4 版本回滚
# 历史版本与回滚
[root@master ~]# kubectl rollout undo deployment myweb --to-revision 1
deployment.apps/myweb rolled back
[root@master ~]# curl -m 3 http://10.245.1.80
Welcome to The Apache.
[root@master ~]# kubectl rollout history deployment myweb
deployment.apps/myweb
REVISION CHANGE-CAUSE
2 nginx.v1
3 httpd:v1
1.5 金丝雀发布
Deployment控制器支持控制更新过程中的控制,如“暂停(pause)”或“继续(resume)”更新操作。
比如有一批新的Pod资源创建完成后立即暂停更新过程,此时,仅存在一部分新版本的应用,主体部分还是旧的版本。然后,再筛选一小部分的用户请求路由到新版本的Pod应用,继续观察能否稳定地按期望的方式运行。确定没问题之后再继续完成余下的Pod资源滚动更新,否则立即回滚更新操作。这就是所谓的金丝雀发布。
# 1、更新deployment的版本,并配置暂停deployment
[root@master ~]# kubectl set image deploy your_deploy_name nginx=nginx:1.17.4 -n your_namespace && kubectl rollout pause deployment your_deploy_name -n your_namespace
deployment.apps/nginx-deployment image updated
deployment.apps/nginx-deployment paused
# 2、观察更新状态
# - your_deploy_name 你的deploy名称
# - your_namespace 你的命名空间名称
[root@master ~]# kubectl rollout status deploy your_deploy_name -n your_namespace
Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 4 new replicas have been updated...
# 3、监控更新的过程,可以看到已经新增了一个资源,但是并未按照预期的状态去删除一个旧的资源,就是因为使用了pause暂停命令
# - your_namespace 你的命名空间名称
[root@master ~]# kubectl get rs -n your_namespace -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES
nginx-deployment-5d89bdfbf9 3 3 3 19m nginx nginx:1.17.1
nginx-deployment-675d469f8b 0 0 0 14m nginx nginx:1.17.2
nginx-deployment-6c9f56fcfb 2 2 2 3m16s nginx nginx:1.17.4
# - your_namespace 你的命名空间名称
[root@master ~]# kubectl get pods -n your_namespace
NAME READY STATUS RESTARTS AGE
nginx-deployment-5d89bdfbf9-rj8sq 1/1 Running 0 7m33s
nginx-deployment-5d89bdfbf9-ttwgg 1/1 Running 0 7m35s
nginx-deployment-5d89bdfbf9-v4wvc 1/1 Running 0 7m34s
nginx-deployment-6c9f56fcfb-996rt 1/1 Running 0 3m31s
nginx-deployment-6c9f56fcfb-j2gtj 1/1 Running 0 3m31s
# 4、确保更新的pod没问题了,继续更新
# - your_deploy_name 你的deploy名称
# - your_namespace 你的命名空间名称
[root@master ~]# kubectl rollout resume deploy your_deploy_name -n your_namespace
deployment.apps/nginx-deployment resumed
# 5、查看最后的更新情况
# - your_namespace 你的命名空间名称
[root@master ~]# kubectl get rs -n your_namespace -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES
nginx-deployment-5d89bdfbf9 0 0 0 21m nginx nginx:1.17.1
nginx-deployment-675d469f8b 0 0 0 16m nginx nginx:1.17.2
nginx-deployment-6c9f56fcfb 4 4 4 5m11s nginx nginx:1.17.4
# - your_namespace 你的命名空间名称
[root@master ~]# kubectl get pods -n your_namespace
NAME READY STATUS RESTARTS AGE
nginx-deployment-6c9f56fcfb-7bfwh 1/1 Running 0 37s
nginx-deployment-6c9f56fcfb-996rt 1/1 Running 0 5m27s
nginx-deployment-6c9f56fcfb-j2gtj 1/1 Running 0 5m27s
nginx-deployment-6c9f56fcfb-rf84v 1/1 Running 0 37s
1.6 删除控制器方法
# 删除控制器方法1
[root@master ~]# kubectl delete deployments myweb
deployment.apps "myweb" deleted
# 删除控制器方法2
[root@master ~]# kubectl delete -f mydeploy.yaml
deployment.apps "myweb" deleted
2. DaemonSet
DaemonSet控制器
- 无法自定义副本数量
- 所创建的Pod与node节点绑定
- 每个node上都会允许一个Pod
- 当有新Node加入集群时,会为他新增Pod副本,当Node从集群移除时,这些Pod也会被回收,典型应用:kube-proxy
[root@master ~]# vim myds.yaml
---
kind: DaemonSet # 资源对象类型
apiVersion: apps/v1 # 版本
metadata: # 元数据
name: myds # 名称
spec: # 详细定义
selector: # 定义标签选择器
matchLabels: # 支持 matchExpressions 表达式语法
app: httpd # 通过标签来确定那个 Pod 由它来管理
template: # 定义用来创建 Pod 的模板,以下为 Pod 定义
metadata:
labels:
app: httpd
spec:
restartPolicy: Always
containers:
- name: webserver
image: myos:httpd
imagePullPolicy: Always
[root@master ~]# kubectl apply -f myds.yaml
daemonset.apps/myds created
[root@master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
NOMINATED NODE READINESS GATES
myds-78b2h 1/1 Running 0 31s 10.244.153.154 node-0005
<none> <none>
myds-78pgb 1/1 Running 0 31s 10.244.243.226 node-0003
<none> <none>
myds-cg2sv 1/1 Running 0 31s 10.244.147.30 node-0002
<none> <none>
myds-pp7s6 1/1 Running 0 31s 10.244.240.162 node-0004
<none> <none>
myds-qrp82 1/1 Running 0 32s 10.244.21.155 node-0001
<none> <none>
2.1 DS控制器会受到污点策略的影响
[root@master ~]# kubectl taint node node-0001 k=v:NoSchedule
node/node-0001 tainted
[root@master ~]# kubectl delete -f myds.yaml
daemonset.apps "myds" deleted
[root@master ~]# kubectl apply -f myds.yaml
daemonset.apps/myds created
# 有污点不会部署,特殊需求可以设置容忍策略
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
myds-fxlgq 1/1 Running 0 33s
myds-j5779 1/1 Running 0 33s
myds-nb6bv 1/1 Running 0 33s
myds-vkk6x 1/1 Running 0 33s
# 删除污点后会立即部署
[root@master ~]# kubectl taint node node-0001 k=v:NoSchedule-
node/node-0001 untainted
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
myds-bq2nv 1/1 Running 0 3s
myds-fxlgq 1/1 Running 0 114s
myds-j5779 1/1 Running 0 114s
myds-nb6bv 1/1 Running 0 114s
myds-vkk6x 1/1 Running 0 114s
# 删除控制器
[root@master ~]# kubectl delete -f myds.yaml
daemonset.apps "myds" deleted
3. Job/CronJob
3.1 Job
- 单任务控制器,执行一次任务
- CronJob是Job的升级版,基于时间管理的Job控制器
- restartPOlicy策略会判断exit状态码,状态为0表示正常,其他都是失败
- 任务执行出错,会重新执行该任务
[root@master ~]# vim myjob.yaml
---
kind: Job
apiVersion: batch/v1
metadata:
name: myjob
spec:
template: # 以下定义 Pod 模板
spec:
restartPolicy: OnFailure
containers:
- name: myjob
image: myos:8.5
command: ["/bin/bash"]
args:
- -c
- |
sleep 3
exit $((RANDOM%2))
[root@master ~]# kubectl apply -f myjob.yaml
job.batch/myjob created
# 失败了会重启
[root@master ~]# kubectl get pods -l job-name=myjob -w
NAME READY STATUS RESTARTS AGE
myjob-plnhc 1/1 Running 0 3s
myjob-plnhc 0/1 Completed 0 4s
myjob-plnhc 0/1 Completed 0 5s
myjob-plnhc 0/1 Completed 0 6s
myjob-plnhc 0/1 Completed 0 6s
[root@master ~]# kubectl get jobs.batch
NAME COMPLETIONS DURATION AGE
myjob 1/1 6s 91s
# 删除Job控制器
[root@master ~]# kubectl delete -f myjob.yaml
job.batch "myjob" deleted
3.2 CronJob
- 时间定义 schedule: 分 时 日 月 周
- 会按照时间周期运行
- 只保留执行三次的结果,多余被删除
[root@master ~]# vim mycj.yaml
---
kind: CronJob
apiVersion: batch/v1
metadata:
name: mycj
spec:
schedule: "* * * * 1-5"
jobTemplate: # 以下定义Job模板
spec:
template:
spec:
restartPolicy: OnFailure
containers:
- name: myjob
image: myos:8.5
command: ["/bin/bash"]
args:
- -c
- |
sleep 3
exit $((RANDOM%2))
[root@master ~]# kubectl apply -f mycj.yaml
cronjob.batch/mycj created
[root@master ~]# kubectl get cronjobs
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
mycj * * * * 1-5 False 0 <none> 14s
# 按照时间周期,每分钟触发一个任务
[root@master ~]# kubectl get jobs -w
NAME COMPLETIONS DURATION AGE
mycj-28263259 1/1 29s 70s
mycj-28263260 1/1 6s 10s
mycj-28263261 0/1 0s
mycj-28263261 0/1 0s 0s
mycj-28263261 0/1 2s 2s
mycj-28263261 0/1 5s 5s
mycj-28263261 0/1 5s 5s
# 保留三次结果,多余的会被删除
[root@master ~]# kubectl get jobs
NAME COMPLETIONS DURATION AGE
mycj-28263261 1/1 24s 2m13s
mycj-28263262 1/1 27s 73s
mycj-28263263 1/1 6s 13s
# 删除CJ控制器
[root@master ~]# kubectl delete -f mycj.yaml
cronjob.batch "mycj" deleted
4. 基础控制器的区别
4.1 Deployment
Deployment 控制器是最常用的 Controller,可以管理 Pod 的多个副本,并确保 Pod 按照期望的状态运行。它支持两种更新策略:滚动更新和重新创建,默认为滚动更新。在 Deployment 中,如果存在容器异常退出,会自动创建新的 Pod 进行替代;同时,异常多出来的容器也会自动回收。当某个 Pod 发生故障需要删除并重新启动时,Pod 的名称会发生变化,同时 StatefulSet 会保证副本按照固定的顺序启动、更新或者删除。
4.2 DaemonSet
DaemonSet 控制器主要用于在每个节点最多只运行一个 Pod 副本的场景。它的名称暗示了其通常用于运行守护进程(daemon)。当有新的节点加入集群时,DaemonSet 控制器会自动在该节点上创建一个 Pod 副本,当有节点从集群中移除时,DaemonSet 控制器会自动回收该节点上的 Pod 副本。
4.3 CronJob/Job
主要用于运行结束就删除的应用。它并不适合长期持续运行的任务。相反,它的设计目的是为了处理一些特定的、一次性的任务,例如批处理任务、定时任务等。一旦任务完成,Job 控制器就会自动删除相关的 Pod。
5. StatefulSet
- StatefulSet控制器 - StatefulSet旨在与有状态的应用及分布式统一使用,涉及了Headless服务、存储卷、DNS等相关知识,是一个宽泛而复杂的话题
- Headless服务 - 在配置StatefulSets的时候,首先要定义一个Headless的服务- 在创建Pod的时候会自动把<Pod名称>注册为域名
4.1 headless服务
# 配置 headless 服务
[root@master ~]# vim mysvc2.yaml
---
kind: Service
apiVersion: v1
metadata:
name: mysvc2 # 服务名称
spec:
type: ClusterIP
clusterIP: None # 设置IP为None
selector:
app: httpd
ports:
- protocol: TCP
port: 80
targetPort: 80
[root@master ~]# kubectl get service mysvc2
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
mysvc2 ClusterIP None <none> 80/TCP 17s
4.2 StatefulSet资源配置文件
[root@master ~]# vim mysts.yaml
---
kind: StatefulSet # 资源对象类型
apiVersion: apps/v1 # 版本
metadata: # 元数据
name: mysts # 名称
spec: # 详细定义
serviceName: mysvc2 # 控制器名称
replicas: 3 # 副本数量
selector: # 定义标签选择器
matchLabels: # 支持 matchExpressions 表达式语法
app: httpd # 通过标签来确定那个 Pod 由它来管理
template: # 定义用来创建 Pod 的模板,以下为 Pod 定义
metadata:
labels:
app: httpd
spec:
restartPolicy: Always
containers:
- name: webserver
image: myos:httpd
imagePullPolicy: Always
[root@master ~]# kubectl apply -f mysts.yaml
statefulset.apps/mysts created
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
mysts-0 1/1 Running 0 8s
mysts-1 1/1 Running 0 7s
mysts-2 1/1 Running 0 6s
[root@master ~]# host mysts-0.mysvc2.default.svc.cluster.local 10.245.0.10
Using domain server:
Name: 10.245.0.10
Address: 10.245.0.10 #53
Aliases:
mysts-0.mysvc2.default.svc.cluster.local has address 10.244.153.159
[root@master ~]# host mysvc2.default.svc.cluster.local 10.245.0.10
Using domain server:
Name: 10.245.0.10
Address: 10.245.0.10 #53
Aliases:
mysvc2.default.svc.cluster.local has address 10.244.147.37
mysvc2.default.svc.cluster.local has address 10.244.153.159
mysvc2.default.svc.cluster.local has address 10.244.240.164
# 删除sts控制器
[root@master ~]# kubectl delete -f mysts.yaml -f mysvc2.yaml
statefulset.apps "mysts" deleted
service "mysvc2" deleted
6. Horizontal Pod Autoscaler(HPA)控制器
- 可在k8s集群中基于CPU利用率或其他应用程序提供的度量指标实现水平自动伸缩的功能,自动缩放POD的数量
- 要在集群中运行,所以先创建集群
- 也需要ClusterIP服务
创建被监控的资源对象
# 为 Deploy 模板添加资源配额
[root@master ~]# vim mydeploy.yaml
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: myweb
spec:
replicas: 1 # 修改副本数量
selector:
matchLabels:
app: httpd
template:
metadata:
labels:
app: httpd
spec:
restartPolicy: Always
containers:
- name: webserver
image: myos:httpd
imagePullPolicy: Always
resources: # 为该资源设置配额
requests: # HPA控制器会根据配额使用情况伸缩集群
cpu: 200m # CPU配额
创建HPA
[root@master ~]# vim myhpa.yaml
---
kind: HorizontalPodAutoscaler # 资源对象类型
apiVersion: autoscaling/v1 # 版本
metadata: # 元数据
name: myweb # 资源对象名称
spec: # 详细定义
minReplicas: 1 # 最少保留的副本数量
maxReplicas: 5 # 最大创建的副本数量
targetCPUUtilizationPercentage: 50 # 警戒值,以百分比计算
scaleTargetRef: # 监控的资源对象
kind: Deployment # 资源对象类型
apiVersion: apps/v1 # 版本
name: myweb # 资源对象名称
[root@master ~]# kubectl apply -f myhpa.yaml
horizontalpodautoscaler.autoscaling/myweb created
# 刚刚创建 unknown 是正常现象,最多等待 60s 就可以正常获取数据
[root@master ~]# kubectl get horizontalpodautoscalers.autoscaling
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS
myweb Deployment/myweb <unknown>/50% 1 5 0
[root@master ~]# kubectl get horizontalpodautoscalers.autoscaling
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
myweb Deployment/myweb 0%/50% 1 5 1 59s
六、service
容器带来的问题:
- 自动调度: 在Pod创建之前,用户无法预知Pod所在节点以及Pod的IP地址
- 一个已经存在的Pod在运行过程中,出现故障,Pod也会在新的节点使用新的IP进行部署
- 应用程序访问服务时,地址是不能经常转变的
- 多个相同的Pod如何访问他们上面的服务
** service服务原理:**
- 自动感知: 服务会创建一个clusterIP,对应资源地址,不管Pod如何变化,服务总能找到对应的Pod,且clusterIP保持不变
- 负载均衡: 若服务器后端对应多个Pod,则会通过IPTables/LVS规则 访问请求最终映射到Pod容器内部,自动实现多个容器的负载均衡
- 自动发现: 服务创建时会自动在内部dns上注册域名
- 域名: <服务名称>.<名称空间>.svc.cluster.local
Service可以看作是一组同类Pod对外的访问接口。借助Service,应用可以方便地实现服务发现和负载均衡。
Service有4种类型:
- ClusterIP:默认值,它是Kubernetes系统自动分配的虚拟IP,只能在集群内部访问
- NodePort:将Service通过指定的Node上的端口暴露给外部,通过此方法,就可以在集群外部访问服务
- LoadBalancer:使用外接负载均衡器完成到服务的负载分发,注意此模式需要外部云环境支持
- ExternalName: 把集群外部的服务引入集群内部,直接使用
6.1 ClusterIP
默认的ServiceType,通过集群的内部IP暴露服务,选择该值时服务只能够在集群内部访问
- **默认类型: **实现Pod的自动感知与负载均衡,是最核心的服务类型,但ClusterIP不能对外发布服务,相对外发布服务只能使用NodePort或lngress
- 工作原理: kube-proxy 是在所有节点上运行的代理,可以实现简单的数据转发,设置更新IPTables/LVS规则,服务创建时,还提供服务地址DNS自动注册与服务发现功能
- 查看DNS IP: kubectl -n kube-system get service kube-dns
- 解析域名的软件包: bind-utils
- 创建service资源文件模板: kubectl create service clusterip mysvc --tcp=80:80 --dry-run=client -o yaml
[root@master ~]# vim mysvc.yaml
---
kind: Service # 资源对象类型
apiVersion: v1 # 版本
metadata: # 元数据
name: mysvc # 资源对象名称
spec: # 详细信息
type: ClusterIP # 服务类型
clusterIP: 10.245.1.80 # 可以设置ClusterIP
selector: # 选择算符
app: web # Pod标签
ports: # 端口
- protocol: TCP # 协议
port: 80 # 监听的端口,service端口
targetPort: 80 # 后端服务器端口,pod端口
nodePort: 31122 # 主机端口
- NodePort:将Service通过指定的Node上的端口暴露给外部,通过此方法,就可以在集群外部访问服务
- 在 /root/init/init.yaml 查看固定IP的范围及Pod IP的范围 CluseterIP是随机分配的,可以自定义但必须满足CIDR
创建service
[root@master ~]# kubectl apply -f mysvc.yaml
service/mysvc created
[root@master ~]# kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.245.0.1 <none> 443/TCP 9d
mysvc ClusterIP 10.245.186.38 <none> 80/TCP 8s
** 域名解析**
# 安装工具软件包
[root@master ~]# dnf -y install bind-utils
# 查看 DNS 服务地址
[root@master ~]# kubectl -n kube-system get service kube-dns
NAME TYPE LUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.245.0.10 <none> 53/UDP,53/TCP,9153/TCP 9d
# 域名解析测试
[root@master ~]# host mysvc.default.svc.cluster.local 10.245.0.10
Using domain server:
Name: 10.245.0.10
Address: 10.245.0.10#53
Aliases:
mysvc.default.svc.cluster.local has address 10.245.186.38
6.2 nodePort
对外发布应用
- ClusterIP服务可以解决集群内应用互访的问题,但外部的应用无法访问集群内的资源,某些应
- 用需要访问集群内的资源,我们就需要对外发布服务。
- ClusterIP:默认类型,可以实现Pod的自动感知与负载均衡,是最核心的服务类型,但 ClusterIP不能对外发布服务,如果想对外发布服务可以使用NodePort 或Ingress
- NodePort与Ingress: - NodePort: 使用基于端口映射(默认值: 30000-32767)的方式对外发布服务,可以任意发布服务(四层)- Ingress: 使用Ingress控制器(一般由Nginx或HAProxy构成),用来发布http,https服务(七层,只能发布这俩个服务)- 7层负载均衡比4层负载均衡更加智能 4层负载均衡比7层负载均衡更加简洁高效
[root@master ~]# vim mysvc1.yaml
---
kind: Service
apiVersion: v1
metadata:
name: mysvc1
spec:
type: NodePort # 服务类型
selector:
app: web
ports:
- protocol: TCP
port: 80
nodePort: 30080 # 映射端口号
targetPort: myhttp
发布服务
[root@master ~]# kubectl apply -f mysvc1.yaml
service/mysvc1 created
[root@master ~]# kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.245.0.1 <none> 443/TCP 3h53m
mysvc ClusterIP 10.245.1.80 <none> 80/TCP 3h35m
mysvc1 NodePort 10.245.235.255 <none> 80:30080/TCP 15s
6.3 Ingress
- Ingress服务由(规则 + 控制器)组成
- 使用Ingress控制器(一般由Nginx或HAProxy构成),用来发布http,https服务(七层,只能发布这俩个服务)
获取ingress
# 创建文件夹
[root@master ~]# mkdir ingress-controller
[root@master ~]# cd ingress-controller/
# 获取ingress-nginx,本次案例使用的是0.30版本
[root@master ingress-controller]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml
[root@master ingress-controller]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml
# 修改mandatory.yaml文件中的仓库
# 修改quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0
# 为registry.aliyuncs.com/google_containers/nginx-ingress-controller:0.30.0
# 创建ingress-nginx
[root@master ingress-controller]# kubectl apply -f ./
# 查看ingress-nginx
[root@master ingress-controller]# kubectl get pod -n ingress-nginx
NAME READY STATUS RESTARTS AGE
pod/nginx-ingress-controller-fbf967dd5-4qpbp 1/1 Running 0 12h
# 查看service
[root@master ingress-controller]# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx NodePort 10.98.75.163 <none> 80:32240/TCP,443:31335/TCP 11h
创建ingress
[root@master ingress]# vim mying.yaml
---
kind: Ingress # 资源对象类型
apiVersion: networking.k8s.io/v1 # 资源对象版本
metadata: # 元数据
name: mying # 资源对象名称
spec: # 资源对象定义
ingressClassName: nginx # 使用的类名称
rules: # ingress规则定义
- host: nsd.tedu.cn # 域名定义,没有可以不写
http: # 协议
paths: # 访问的路径定义
- path: / # 访问的url路径
pathType: Prefix # 路径类型:Exact、Prefix
backend: # 后端服务
service: # 服务声明
name: mysvc # 服务名称
port: # 端口号声明
number: 80 # 访问服务的端口号
[root@master ingress]# kubectl apply -f mying.yaml
ingress.networking.k8s.io/mying created
[root@master ingress]# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
mying nginx nsd.tedu.cn 192.168.1.51 80 10s
[root@master ingress]# curl -H "Host: nsd.tedu.cn" http://192.168.1.51
Welcome to The Apache.
七、存储卷管理
容器中的文件在磁盘上是临时存放的,所以:
- 当容器崩溃或重启,kubelet重启容器后,历史数据会消失
- 容器被删除,容器内的数据也会消失
- 多个容器有共享文件或目录的需求
卷概述:
- 卷是一个抽象化的存储设备
- 卷可以解决容器崩溃或重启,数据丢失的问题
- 可以解决容器或Pod被删后数据持久保存的问题
- 可以解决在多个容器内共享数据的问题
- Pod可以同时使用任意数目的卷
持久卷:持久卷是集群中的存储资源,里面的内容不会随着Pod的删除而消失
临时卷:有些应用程序需要额外的存储,但并不关心数据在重启后是否仍可用,卷会遵从Pod的生命周期,与Pod一起创建和删除
使用存储卷:
- 在Pod.spec下添加volumes字段,配置外部存储卷
- 在Pod.spec.containers[*]中添加 vloumeMounts字段,声明卷在容器中挂载位置
1. 持久卷
1.1 hostPath
- 本质是使用本地设备,如磁盘,分区,目录等,hostPath的可用性取决于底层节点的可用性,如果节点变的不健康,那hostPath也将不可访问
- hostPath卷里面的数据不会随着Pod的结束而消失
[root@master ~]# vim web1.yaml
---
kind: Pod
apiVersion: v1
metadata:
name: web1
spec:
volumes: # 卷定义
- name: logdata # 卷名称
hostPath: # 资源类型
path: /var/weblog # 宿主机路径
type: DirectoryOrCreate # 目录不存在就创建
containers:
- name: nginx
image: myos:nginx
volumeMounts: # mount 卷
- name: logdata # 卷名称
mountPath: /usr/local/nginx/logs # 容器内路径
type类型:
type类型 说明说明DirectoryOrCreate卷映射对象是一个目录,如果不存在就创建它Directory卷映射对象是一个目录,且必须存在FileOrCreate卷映射对象是一个文件,如果不存在创建它File卷映射对象是一个文件,且必须存在Socket卷映射对象是一个Socket套接字,且必须存在CharDevice卷映射对象是一个字符设备,且必须存在BlockDevice卷映射对象是一个块设备,且必须存在
1.2 NFS
NFS 存储
k8s中允许将nfs存储以卷的方式挂载到你的Pod中。在删除Pod时,nfs存储卷会被卸载(umount),而不是被删除。nfs卷可以在不同节点的Pod之间共享数据。
NFS卷的用途
NFS最大的功能就是在不同节点的不同Pod中共享读写数据。本地NSF的客户端可以透明地读写位于远端NFS服务器上的文件,就像访问本地文件一样。
** 部署 **
- 需要一台NFS服务器
- 在所有节点都需安装NFS(因为Pod是随机调度的,所以为保证NFS存储卷可以正确加载,需在所有node节点上都安装NFS软件工具包)
[root@master ~]# vim nfs.yaml
---
kind: Pod
apiVersion: v1
metadata:
name: web1
spec:
volumes: # 卷定义
- name: website # 卷定义
nfs: # NFS 资源类型
server: 192.168.1.10 # NFS 服务器地址
path: /var/webroot # NFS 共享目录
containers:
- name: nginx
image: myos:nginx
volumeMounts: # mount 卷
- name: website # 卷名称
mountPath: /usr/local/nginx/html # 容器内路径
[root@master ~]# kubectl apply -f nfs.yaml
pod/nfs created
1.3 PV/PVC
- PV: 持久卷,资源提供者,有管理员配置,PV的全称是Persistent Volume,是持久卷
- VC: 持久卷声明,资源使用者,根据业务需求来配置,PVC的全称是Persistent VolumeClaim,是持久卷声明
- PVC会根据客户的需求,自动找到PV绑定
** accessMode:存储卷能提供的访问方式:**
ReadWriteOnce: 单节点读写
ReadOnlyMany: 多节点只读
ReadWriteMang: 多节点读写
ReadWriteOnceMangy: 在一个Pod中只读
volumeMode: 提供资源的类型:
- Filesystem:文件系统,直接mount就可以使用
- Block:块设备,要先格式化在mount
持久卷PV
[root@master ~]# vim pv.yaml
---
kind: PersistentVolume
apiVersion: v1
metadata:
name: pv-local
spec:
volumeMode: Filesystem # 提供资源的类型[Filesystem,Block]
accessModes: # 存储卷能提供的访问模式
- ReadWriteOnce # 卷支持的模式,支持多种(hostPAth 只支持 RWO)
capacity: # 存储卷能提供的存储空间
storage: 30Gi # 空间大小
persistentVolumeReclaimPolicy: Retain # 数据回收方式(手工回收)
hostPath: # hostPath配置
path: /var/weblog
type: DirectoryOrCreate
---
kind: PersistentVolume
apiVersion: v1
metadate:
name: pv-nfs
spec:
volumeMode: Filesystem # 提供Filesystem访问方式
accessModes: # NFS支持多种访问方式
- ReadWriteOnce # RWO、ROX、RWX
- ReadOnlyMany
- ReadWriteMany
capacity:
storage: 20Gi # 提供的磁盘空间大小
persistentVolumeReclaimPolicy: Retain # 数据手动回收
mountOptions: # mount的参数
- nolock
nfs: # NFS配置
server: 192.168.1.10
path: /var/webroot
[root@master ~]# kubectl apply -f pv.yaml
persistentvolume/pv-local created
persistentvolume/pv-nfs created
[root@master ~]# kubectl get persistentvolume
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-local 30Gi RWO Retain Available 2s
pv-nfs 20Gi RWO,ROX,RWX Retain Available 2s
持久卷声明 PVC
[root@master ~]# vim pvc.yaml
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: pvc1
spec: # 定义需求
volumeMode: Filesystem # 需要使用Filesystem的存储卷
accessModes:
- ReadWriteOnce # 需要支持RWO的存储卷
resources:
requests:
storage: 25Gi # 最小磁盘空间需求
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: pvc2
spec: # 定义需求
volumeMode: Filesystem # 需要使用Filesystem的存储卷
accessModes:
- ReadWriteMany # 需要支持RWX的存储卷
resources:
requests:
storage: 15Gi # 最小磁盘空间需求
[root@master ~]# kubectl apply -f pvc.yaml
persistentvolumeclaim/pvc1 created
persistentvolumeclaim/pvc2 created
[root@master ~]# kubectl get persistentvolumeclaims
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
pvc1 Bound pv-local 30Gi RWO 17s
pvc2 Bound pv-nfs 20Gi RWO,ROX,RWX 17s
** Pod 挂载 PVC**
[root@master ~]# vim web1.yaml
---
kind: Pod
apiVersion: v1
metadata:
name: web1
spec:
volumes: # 卷定义
- name: logdata # 卷名称
persistentVolumeClaim: # 通过PVC引用存储资源
claimName: pvc1 # PVC名称
- name: website # 卷名称
persistentVolumeClaim: # 通过PVC引用存储资源
claimName: pvc2 # 卷名称
containers:
- name: nginx
image: myos:nginx
volumeMounts: # mount 卷
- name: logdata # 卷名称
mountPath: /usr/local/nginx/logs # 容器内路径
- name: website # 卷名称
mountPath: /usr/local/nginx/html # 容器内路径
2. 临时卷
2.1 configMap
- 提供了向Pod注入配置数据的方法,允许你将配置文件与镜像分离,使容器化的应用具有可移植性
- 在使用之前就要创建好,不是用来保存数据的,其保存的数据不可超过1MiB
- 配置环境变量,修改配置文件的参数,数据库地址等
[root@master ~]# vim timezone.yaml
---
kind: ConfigMap
apiVersion: v1
metadata:
name: timezone
data:
TZ: Asia/Shanghai
[root@master ~]# kubectl apply -f timezone.yaml
configmap/timezone created
[root@master ~]# kubectl get configmaps
NAME DATA AGE
kube-root-ca.crt 1 9d
timezone 1 9s
tz 1 3m57s
[root@master ~]# vim web1.yaml
---
kind: Pod
apiVersion: v1
metadata:
name: web1
spec:
volumes: # 卷定义
- name: logdata # 卷名称
persistentVolumeClaim: # 通过PVC引用存储资源
claimName: pvc1 # PVC名称
- name: website # 卷名称
persistentVolumeClaim: # 通过PVC引用存储资源
claimName: pvc2 # 卷名称
containers:
- name: nginx
image: myos:nginx
envFrom: # 配置环境变量
- configMapRef: # 调用资源对象
name: timezone # 资源对象名称
volumeMounts: # mount 卷
- name: logdata # 卷名称
mountPath: /usr/local/nginx/logs # 容器内路径
- name: website # 卷名称
mountPath: /usr/local/nginx/html # 容器内路径
[root@master ~]# kubectl delete pods web1
pod "web1" deleted
[root@master ~]# kubectl apply -f web1.yaml
pod/web1 created
[root@master ~]# kubectl exec -it web1 -- date +%T
17:25:37
2.2 secret
- 类似于ConfigMap,专门用于保存机密数据,因为是加密的
- 一般用于: - 配置一些需要加密的环境变量或文件(如 https 证书)- 访问需要认证登录的私有镜像仓库(如 harbor 私有仓库)
通用类型
kubectl createsecret generic 名称 [选项/参数]
用于认证登录私有仓库的子类型
kubectl create secret docker-registry 名称 [选项/参数]
用于创建TLS证书的子类型
kubectl create secret tls 名称 [选项/参数]
配置登录密钥
root@master ~]# kubectl create secret docker-registry harbor-auth --docker server=harbor:443 --docker-username="admin" --docker-password="admin123"
secret/harbor-auth created
[root@master ~]# kubectl get secrets harbor-auth -o yaml
apiVersion: v1
data:
.dockerconfigjson:
eyJhdXRocyI6eyJoYXJib3I6NDQzIjp7InVzZXJuYW1lIjoiYWRtaW4iLCJwYXNzd29yZCI6ImFkbWluM
TIzIiwiYXV0aCI6IllXUnRhVzQ2WVdSdGFXNHhNak09In19fQ== # 经过加密的数据
kind: Secret
metadata:
creationTimestamp: "2023-09-22T10:03:02Z"
name: harbor-auth
namespace: default
resourceVersion: "285856"
uid: 14112a73-d723-48a4-b172-0bff7c3ed1ea
type: kubernetes.io/dockerconfigjson
[root@master ~]# kubectl get secrets harbor-auth
NAME TYPE DATA AGE
harbor-auth kubernetes.io/dockerconfigjson 1 2m23s
认证私有仓库
[root@master ~]# vim web2.yaml
---
kind: Pod
apiVersion: v1
metadata:
name: web2
spec:
imagePullSecrets: # 引用secret数据
- name: harbor-auth # 资源对象名称
containers:
- name: apache
image: harbor:443/myimg/httpd:latest # 使用私有仓库里的镜像
[root@master ~]# kubectl apply -f web2.yaml
pod/web2 created
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
web1 2/2 Running 0 46m
web2 1/1 Running 0 5s
2.3 emptyDir
- 本质是一个空目录
- 可以提供临时空间,同一个Pod中的容器也可以来共享数据
- 随着Pod创建而创建,Pod在该节点上运行期间,一直存在,当Pod被节点删除时,临时卷中的数据也会被永久删除
- 重启Pod不会造成emptyDir数据的丢失
临时空间
[root@master ~]# vim web2.yaml
---
kind: Pod
apiVersion: v1
metadata:
name: web2
spec:
imagePullSecrets:
- name: harbor-auth
volumes: # 卷配置
- name: cache # 卷名称,在容器内引用
emptyDir: {} # 资源类型
containers:
- name: apache
image: harbor:443/myimg/httpd:latest
volumeMounts: # 挂载卷
- name: cache # 卷名称
mountPath: /var/cache # 路径如果不存在,就创建出来,如果存在,就覆盖
[root@master ~]# kubectl apply -f web2.yaml
pod/web2 created
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
web1 2/2 Running 0 58m
web2 1/1 Running 0 8s
[root@master ~]# kubectl exec -it web2 -- bash
[root@web2 html]# mount | grep cache
/dev/sda1 on /var/cache type ext4 (rw,relatime)
版权归原作者 我爱云计算 所有, 如有侵权,请联系我们删除。