01k8s--pod入门
pod概念
pod概念
Pod是Kubernetes中的最小调度单元,k8s是通过定义一个Pod的资源,然后在Pod里面运行容器,容器需要指定一个镜像,这样就可以用来运行具体的服务。一个Pod封装一个容器(也可以封装多个容器),Pod里的容器共享存储、网络等。也就是说,应该把整个pod看作虚拟机,然后每个容器相当于运行在虚拟机的进程。
Pod中可以同时运行多个容器。同一个Pod中的容器会自动的分配到同一个 node 上。同一个Pod中的容器共享资源、网络环境,它们总是被同时调度,
pod网络
Pod是有IP地址的,每个pod都被分配唯一的IP地址(IP地址是靠网络插件calico、flannel、weave等分配的),POD中的容器共享网络名称空间,包括IP地址和网络端口。 Pod内部的容器可以使用localhost相互通信。 Pod中的容器也可以通过网络插件calico与其他节点的Pod通信。
pod存储
创建Pod的时候可以指定挂载的存储卷。 POD中的所有容器都可以访问共享卷,允许这些容器共享数据。 Pod只要挂载持久化数据卷,Pod重启之后数据还是会存在的。
初识pod
[root@master ~]# cat pod-new.yaml
apiVersion: v1 ##版本,v1代表稳定版
kind: Pod ##类型
metadata: ##元数据
name: pod-new ##pod的名字
spec: ##pod中容器的详细定义
containers: ##pod中容器列表,
- name: con-pod ##容器名称
image: nginx ##容器的镜像
运行
[root@master ~]# kubectl apply -f pod-new.yaml
pod工作方式
在K8s中,所有的资源都可以使用一个yaml文件来创建,创建Pod也可以使用yaml配置文件。或者使用kubectl run在命令行创建Pod(不常用)。
自主式pod
所谓的自主式Pod,就是直接定义一个Pod资源
[root@master ~]# vi pod-tomcal.yaml
apiVersion: v1
kind: Pod
metadata:
name: tomcat-test
namespace: default
labels:
app: tomcat
spec:
containers:
- name: tomcat-java
ports:
- containerPort: 8080
image: xianchao/tomcat-8.5-jre8:v1
imagePullPolicy: IfNotPresent
###导入镜像
[root@node1 ~]# docker load -i tomcat.tar.gz
[root@node2 ~]# docker load -i tomcat.tar.gz
###更新资源文件
[root@master ~]# kubectl apply -f pod-tomcal.yaml
pod/tomcat-test created
###查看是否创建成功
[root@master ~]# kubectl get pods -o wide -l app=tomcat
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
tomcat-test 1/1 Running 0 51s 10.122.104.4 node2 <none> <none>
但是自主式Pod是存在一个问题的,假如我们不小心删除了pod:
[root@master ~]# kubectl delete pods tomcat-test
pod "tomcat-test" deleted
#查看pod是否还在
[root@master ~]# kubectl get pods -o wide -l app=tomcat
No resources found in default namespace
###结果是空,说明pod已经被删除
通过上面可以看到,如果直接定义一个Pod资源,那Pod被删除,就彻底被删除了,不会再创建一个新的Pod,这在生产环境还是具有非常大风险的,所以今后我们接触的Pod,都是控制器管理的。
控制器管理的pod
常见的管理Pod的控制器:Replicaset、Deployment、Job、CronJob、Daemonset、Statefulset。
控制器管理的Pod可以确保Pod始终维持在指定的副本数运行。
如,通过Deployment管理Pod
[root@master ~]# vi tomcat-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: tomcat-test
labels:
app: tomcat-deploy
spec:
selector:
matchLabels:
app: tomcat
replicas: 2
template:
metadata:
labels:
app: tomcat
spec:
containers:
- name: my-tomcat
image: xianchao/tomcat-8.5-jre8:v1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
###更新资源清单
[root@master ~]# kubectl apply -f tomcat-deploy.yaml
deployment.apps/tomcat-test created
查看deployment
[root@master ~]# kubectl get deploy -l app=tomcat-deploy
NAME READY UP-TO-DATE AVAILABLE AGE
tomcat-test 2/2 2 2 67s
查看Replicaset
[root@master ~]# kubectl get rs -l app=tomcat
NAME DESIRED CURRENT READY AGE
tomcat-test-55946f7dbc 2 2 2 89s
##查看pod
[root@master ~]# kubectl get pods -o wide -l app=tomcat
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
tomcat-test-55946f7dbc-5dnlc 1/1 Running 0 115s 10.122.104.6 node2 <none> <none>
tomcat-test-55946f7dbc-z6nld 1/1 Running 0 115s 10.122.104.5 node2 <none> <none>
###删除tomcat-test-55946f7dbc-5dnlc这个
[root@master ~]# kubectl delete pods tomcat-test-55946f7dbc-5dnlc
pod "tomcat-test-55946f7dbc-5dnlc" deleted
##
[root@master ~]# kubectl get pods -o wide -l app=tomcat
发现重新创建一个新的pod
通过上面可以发现通过deployment管理的pod,可以确保pod始终维持在指定副本数量
###删除之前所有创建的
[root@master ~]# kubectl delete -f tomcat-deploy.yaml
deployment.apps "tomcat-test" deleted
pod基本操作
pod帮助
[root@master ~]# kubectl --help
###实战--创建命名空间
####创建大部分命令都是create,所以现使用下面命令尝试是否能成功
[root@master ~]# kubectl create --help
####可以看到成功说明此命令正确,可看到命名空间是namespace
[root@master ~]# kubectl create namespace --help
Create a namespace with the specified name.
Aliases:
namespace, ns ##
Examples:
# Create a new namespace named my-namespace
kubectl create namespace my-namespace ####创建命令
Usage: ###下面是创建格式
kubectl create namespace NAME [--dry-run=server|client|none] [options]
####可看到上面命令很详细,创建名为test命名空间
[root@master ~]# kubectl create namespace test
namespace/test created
###上面创建命令可简写
[root@master ~]# kubectl create ns test
###查看
[root@master ~]# kubectl get namespace
创建pod
通过kubectl run创建
[root@master ~]# kubectl run tomcat --image=tomcat --image-pull-policy='IfNotPresent' --port=8080
默认会在node节点创建所以要在node节点拉取镜像
[root@node1 ~]# docker pull tomcat
查看状态
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
tomcat 1/1 Running 0 2m11s
资源清单yum创建
yum书写技巧
###查看api版本
[root@master ~]# kubectl --help api.versions
####查看pod资源有哪些字段
[root@master ~]# kubectl explain pod
KIND: Pod
VERSION: v1 ####kubectl api-versions可查看所以版本
FIELDS:
apiVersion <string> ####版本
kind <string> ###Kind是字符串类型的值,代表了要创建的资源
metadata <Object>###metadata是对象,定义元数据属性信息
spec <Object> ###spec制定了定义Pod的规格,里面包含容器的信息
status <Object> ####表示状态,这个不可以修改,定义pod的时候也不需要定义这个字段
......
##查看上面pod.metadata字段如何定义
[root@master ~]# kubectl explain pod.metadata
KIND: Pod
VERSION: v1
RESOURCE: metadata <Object> ####metadata是对象<Object>,下面可以有多个字段
FIELDS:
annotations <map[string]string> ###用来记录信息(build信息、release信息、Docker镜像信息等)
clusterName <string>####对象所属群集的名称。这是用来区分不同集群中具有相同名称和命名空间的资源。
creationTimestamp <string>
deletionGracePeriodSeconds <integer>
.....
labels <map[string]string> ###创建的资源具有的标签,labels是map类型,map类型表示对应的值是key-value键值对,
name <string> #创建的资源的名字
namespace <string> ####创建的资源所属的名称空间
#### namespaces划分了一个空间,在同一个namesace下的资源名字是唯一的,默认的名称空间是default。
###查看pod.spec字段定义
#Pod的spec字段是用来描述Pod的
[root@master ~]# kubectl explain pod.spec
KIND: Pod
VERSION: v1
RESOURCE: spec <Object>
activeDeadlineSeconds <integer> ####表示Pod可以运行的最长时间,达到设置的值后,Pod会自动停止
affinity <Object> ### #定义亲和性的
automountServiceAccountToken <boolean>
containers <[]Object> -required- ##containers是对象列表,用来定义容器的,是必须字段。对象列表下面的内容用 - 连接。
###查看pod.spec.containers字段如何定义
#container是定义在pod里面的,一个pod至少要有一个容器。
[root@master ~]# kubectl explain pod.spec.containers
KIND: Pod
VERSION: v1
RESOURCE: containers <[]Object>
image <string> ###image是用来指定容器需要的镜像的
imagePullPolicy <string> #镜像拉取策略,pod是要调度到node节点的,那pod启动需要镜像,可以根据这个字段设置镜像拉取策略,支持如下三种:
Always:不管本地是否存在镜像,都要重新拉取镜像
Never: 从不拉取镜像
IfNotPresent:如果本地存在,使用本地的镜像,本地不存在,从官方拉取镜像
name <string> -required- #name是必须字段,用来指定容器名字的
ports <[]Object> #port是端口,属于对象列表
###查看pod.spec.container.ports字段如何定义
[root@master ~]# kubectl explain pod.spec.containers.ports
KIND: Pod
VERSION: v1
RESOURCE: ports <[]Object>
containerPort <integer> -required- #containerPort是必须字段, pod中的容器需要暴露的端口。
hostIP <string> #将容器中的服务暴露到宿主机的端口上时,可以指定绑定的宿主机 IP。
hostPort <integer> #容器中的服务在宿主机上映射的端口
name <string> #端口的名字
创建pod
[root@master ~]# cat pod-first.yaml
apiVersion: v1 #api版本
kind: Pod #创建的资源
metadata:
name: pod-first #Pod的名字
namespace: default #Pod所在的名称空间
labels:
app: tomcat-pod-first #Pod具有的标签
spec:
containers:
- name: tomcat-first #Pod里容器的名字
ports:
- containerPort: 8080 #容器暴露的端口
image: tomcat:8.5-jre8-alpine #容器使用的镜像
imagePullPolicy: IfNotPresent #镜像拉取策略
导入镜像
####创建的pod默认会创建在工作节点node节点上所以在node节点拉取镜像
[root@node1 ~]# docker load -i tomcat.tar.gz
创建
[root@master ~]# kubectl apply -f pod-first.yaml
pod/pod-first created
查看是否创建成功
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
pod-first 1/1 Running 0 9s
[root@master ~]# kubectl get pods -o wide -l app=tomcat-pod-first
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-first 1/1 Running 0 6m50s 10.244.1.2 node1 <none> <none>
查看日志
[root@master ~]# kubectl logs pod-first
查看pod里指定容器的日志
[root@master ~]# kubectl logs pod-first -c tomcat-first
进入刚刚创建的容器
[root@master ~]# kubectl exec -it pod-first -- /bin/bash
bash-4.4#
假如pod里有多个容器,进入到pod里的指定容器
[root@master ~]# kubectl exec -it pod-first -c tomcat-first -- /bin/bash
bash-4.4#
查看pod
###查看pod状态
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
liveness-exec 1/1 Running 105 98d
###查看指定pod
[root@master ~]# kubectl get pods myapp-pod
###查看所有命名空间下的pod
[root@master yam]# kubectl get pods -A
###持续查看
[root@master ~]# kubectl get pods -w
###查看指定命名空间下的pod
[root@master ~]# kubectl get pods -n kube-system
###查看有哪些命名空间
[root@master yam]# kubectl get namespace
###查看更多概要信息
[root@master ~]# kubectl get pods -o wide
[root@master ~]# kubectl get pods pod-first -o wide
###多种格式输出
[root@master ~]# kubectl get pods pod-first --output yaml
[root@master ~]# kubectl get pods pod-first --output json
###pod-first:pod名称
###查看详细信息
[root@master ~]# kubectl describe pod pod-first
###过滤查看
###kubectl get 支持go tempalte方式过滤出指定的信息
###查询pod的完整状态
[root@master ~]# kubectl get pod pod-first --output=go-template --template={{.status.phase}}
Running
###查看日志
[root@master ~]# kubectl logs pod-first
#持续查看
[root@master ~]# kubectl attach pod-first
##查看pod下容器日志
[root@master ~]# kubectl attach pod-first confirst
###confirst:是创建的容器名称,containers:参数下的
###查看pod支持的字段
[root@master ~]# kubectl explain pod
###继续查看pod中的字段
[root@master ~]# kubectl explain pod.spec
修改pod
pod中有很多属性不可修改,如containers的image属性,spec下的activeDeadline..等,若一定要修改要加上 --force参数
###更改文件内容
强制执行
[root@master ~]# kubectl apply -f pod-first.yaml --force #强制修改
删除
[root@master ~]# kubectl delete pod-first
###若有依赖关系可直接使用文件进行删除
[root@master ~]# kubectl delete -f pod-first.yaml
###删除全部
[root@master ~]# kubectl delete pod --all
登入
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
pod-first 1/1 Running 0 4s
[root@master ~]# kubectl exec -it pod-first -- bash
###登入到pod中的指定容器
[root@master ~]# kubectl exec -it pod-first -c tomcat-first -- bash
bash-4.4#
拷贝
#####从本地中拷贝文件到容器中
[root@master ~]# kubectl cp pod-first:/root /bach
tar: removing leading '/' from member names ###报错
###本地拷贝到容器
# kubectl cp /tmp/nginx.log nginx:/tmp/nginx.log
# kubectl exec nginx cat /tmp/nginx.log
pod与容器
(1)volumeMounts配置信息
pod中的容器可以访问共同的数据卷来实现文件系统的共享。所以kubernetes中的数据卷是pod级别的,而不是容器级别的。pod中的容器可以访问共同的数据卷,实现容器间的数据共享。
EmptyDir
[root@master ~]# cat pod-volume.yaml
apiVersion: v1
kind: Pod
metadata:
name: exam-volume
spec:
containers:
- name: con-write #容器1,向数据卷写入数据------
image: mysql:5.7
imagePullPolicy: IfNotPresent
command: ['sh','-c']
args: ['echo "test data!"; > /write_dir/data ; sleep 3600']
volumeMounts:
- name: filedata #引用下面存储卷
mountPath: /write_dir #存储卷在容器内挂载的绝对路径
- name: con-read #容器2----------------
image: mysql:5.7
imagePullPolicy: IfNotPresent
command: ['sh','-c']
args: ['cat /read_dir/data; sleep 3600']
volumeMounts:
- name: filedata #引用下面
mountPath: /read_dir #容器内数据卷地址
volumes: #创建存储卷-----------------------
- name: filedata #被容器设置中的数据卷所引用
emptyDir: {} #类型emptyDir
[root@master ~]# kubectl apply -f pod-volume.yaml
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
exam-volume 2/2 Running 0 5s
###查看pod中con-write容器
[root@master ~]# kubectl logs exam-volume con-write
test data!
[root@master ~]# kubectl logs exam-volume con-read
####此实验没有共享一个目录所有目的只是实现一个容器读一个容器写,而不是第一个容器写入第二个容器读取
----本列创建了两个容器。一个存储卷
1con-write,它向数据卷写入数据,会向/write_dir/data文件写入test data文本,
创建pod容器内数据卷地址为/write_dir,它引用的存储卷为filedata
2con-read,会从/read_dir/data文件中读取文本,并将其输出到控制台,容器内数据卷地址为/read_dir,它引用的存储卷为filedata
进入容器
root@master ~]# kubectl exec -it exam-volume con-write -- /bin/bash
在宿主机中查看
###在pod所创建在的主机上查看此处是node1
###在/var/lib/kubelet/pods目录中查看
实例2
HostDir
在宿主机上指定一个目录,挂载到Pod的容器中
[root@master ~]# cat pod-volume2.yaml
apiVersion: v1
kind: Pod
metadata:
name: con-volume2
spec:
containers:
- name: con-writer2
image: mysql:5.7
imagePullPolicy: IfNotPresent
command: ['sh','-c']
args: ['echo "hello worlds"; >> /data/hello ; sleep 3600']
volumeMounts:
- name: data
mountPath: /data
- name: con-read2
image: mysql:5.7
imagePullPolicy: IfNotPresent
command: ['sh','-c']
args: ['cat /data/hello; sleep 3600']
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
hostPath:
path: /home
[root@master ~]# kubectl apply -f pod-volume2.yaml
###
###此处是挂载在物理机中,挂载在pod所创建的节点本处是node1的/home节点
问题:共享的数据卷,和con-writer2没什么关系,使用lkubectl logs查看输出之前输入的内容,而查看con-read2却查看不到,对挂载在/home的卷操作,进如两个容器中查看,可以查看到但使用logs查看又是显示之前输入的内容
(2)ports配置信息
使用宿主机端口需要考虑端口冲突,幸运的是kubernetes在调度pod的时候,会检查宿主机端口是否冲突。若端口冲突,调度时就会将这两个pod调度到不同node上。若所以node端口都被占用,那么pod调度就会失败。
暴露端口,并映射到主机
[root@master ~]# cat pod-port.yaml
apiVersion: v1
kind: Pod
metadata:
name: exam-port2
spec:
containers:
- name: exam-nginx2
image: daocloud.io/library/nginx:1.13.2
imagePullPolicy: IfNotPresent
ports:
- name: portfoxnginx
containerPort: 80
hostPort: 8088
protocol: TCP
[root@master ~]# kubectl apply -f pod-port.yaml
查看运行
[root@master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
exam-port2 1/1 Running 0 4m47s 10.244.0.6 master <none> <none>
###此处运行在master节点上,因为node节点上8088端口已使用
查看详细信息
[root@master ~]# kubectl describe pods exam-port2
访问
[root@master ~]# curl 192.168.200.80:8088
(3)env配置信息
[root@master ~]# cat pod-env.yaml
apiVersion: v1
kind: Pod
metadata:
name: exam-env
spec:
containers:
- name: con-env
image: mysql:5.7
imagePullPolicy: IfNotPresent
env: ###环境变量
- name: para1
value: "good moring!"
- name: para2
value: "good might"
command: ['sh','-c']
args: ['echo "${para1} ${para2}";sleep 3600']
##上面环境变量类似于:
parameter1=good morning!
parameter2=good might!
----模板中定义了一个名为containerforenv的容器,向他传入了两个环境变量,
---将传入的两个环境变量拼接到一起
[root@master ~]# kubectl apply -f pod-env.yaml
查看输出日志
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
exam-env 1/1 Running 0 5m25s
[root@master ~]# kubectl logs exam-env
good moring! good might
过滤环境变量
[root@master ~]# kubectl exec exam-env env | grep para
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl kubectl exec [POD] -- [COMMAND] instead.
para2=good might
para1=good moring!
[root@master ~]# kubectl describe pod exam-env
Environment:
para1: good moring!
para2: good might
(4)pod的网络
[root@master ~]# kubectl get pod exam-env --template={{.status.podIP}}
10.244.1.3
#####exam-env pod名称
定义的pod设置为host网络模式
[root@master ~]# cat pod-host.yaml
apiVersion: v1
kind: Pod
metadata:
name: exam-host
spec:
containers:
- name: cont-host
image: nginx
imagePullPolicy: IfNotPresent
ports:
- name: web
containerPort: 80
protocol: TCP
hostNetwork: true
[root@master ~]# kubectl apply -f pod-host.yaml
[root@master ~]# kubectl get pod exam-host --template={{.status.podIP}}
192.168.200.30
###此pod使用的是node节点宿主机的ip
命名空间
概念
Kubernetes 支持多个虚拟集群,它们底层依赖于同一个物理集群。 这些虚拟集群被称为命名空间。
命名空间namespace是k8s集群级别的资源,可以给不同的用户、租户、环境或项目创建对应的命名空间,例如,可以为test、devlopment、production环境分别创建各自的命名空间。
namespace应用场景
命名空间适用于存在很多跨多个团队或项目的用户的场景。
名称空间及其资源对象
k8s集群默认提供了几个名称空间用于特定目的,例如,kube-system主要用于运行系统级资源,存放k8s一些组件的。而default则为那些未指定名称空间的资源操作提供一个默认值。
查看namespace资源
[root@master ~]# kubectl get namespace
#namespace:可简写为ns
查看特定的命名空间详细信息
[root@master ~]# kubectl describe namespace $NAME
查看指定命名空间
[root@master ~]# kubectl get pods -n kube-system
删除命名空间
###test是要自己手动创建的
[root@master ~]# kubectl delete ns test
管理namespace资源
namespace资源属性较少,通常只需要指定名称即可创建,如“kubectl create namespace qa”。namespace资源的名称仅能由字母、数字、下划线、连接线等字符组成。删除namespace资源会级联删除其包含的所有其他资源对象。
namespace使用案例
创建一个test命名空间
[root@master ~]# kubectl create ns test
namespace/test created
切换命名空间
####切换到kube-system的命名空间
[root@master ~]# kubectl config set-context --current --namespace=kube-system
Context "kubernetes-admin@kubernetes" modified.
####切换命名空间后,kubectl get pods 如果不指定-n,查看的就是kube-system命名空间的资源了。
查看哪些资源属于命名空间级别的
[root@master ~]# kubectl api-resources --namespace=true
使用yaml文件创建命名空间
[root@master ~]# cat kube-name.yaml
kind: Namespace
apiVersion: v1
metadata:
name: kube-logging
[root@master ~]# kubectl apply -f kube-name.yaml
###查看
[root@master ~]# kubectl get ns
namespace资源限额
namespace是命名空间,里面有很多资源,那么我们可以对命名空间资源做个限制,防止该命名空间部署的资源超过限制。
[root@master ~]# cat namespace-quota.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: mem-cpu-quota
namespace: test ###使用命名空间
spec:
hard:
requests.cpu: "2"
requests.memory: 2Gi
limits.cpu: "4"
limits.memory: 4Gi
####创建前要先有test不然可能会出错
-----
#创建的ResourceQuota对象将在test命名空间中添加以下限制:
每个容器必须设置内存请求(memory request),内存限额(memory limit),cpu请求(cpu request)和cpu限额(cpu limit)。
所有容器的CPU请求总额不得超过2 CPU。
所有容器的内存请求总额不得超过2GiB。
所有容器的CPU限额总额不得超过4CPU。
所有容器的内存限额总额不得超过4 GiB。
创建pod时候必须设置资源限额,否则创建失败,
[root@master ~]# cat pod-first.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-first
namespace: test ###使用上面做了限制的命名空间
labels:
app: tomcat-pod-first
spec:
containers:
- name: tomcat-first
ports:
- containerPort: 8080
image: tomcat:8.5-jre8-alpine
imagePullPolicy: IfNotPresent
[root@master ~]# kubectl apply -f pod-first.yaml
pod/pod-first created
[root@master ~]# kubectl get pods -n test
NAME READY STATUS RESTARTS AGE
pod-first 1/1 Running 0 25s
标签
概念
标签其实就一对 key/value ,被关联到对象上,标签可以在创建一个对象的时候直接定义,也可以在后期随时修改,每一个对象可以拥有多个标签,但是,key值必须是唯一的。创建标签之后也可以方便我们对资源进行分组管理。如果对pod打标签,之后就可以使用标签来查看、删除指定的pod。
给pod打上标签
######因为上面给这个pod更改默认命名空间了所以查看要加-n test
###查看
[root@master ~]# kubectl get pods -n test
NAME READY STATUS RESTARTS AGE
pod-first 1/1 Running 0 6m35s
####打标签(给pod-first打上标签)
[root@master ~]# kubectl label pods pod-first release=v1 -n test
pod/pod-first labeled
####若没加命名空间默认命名空间
[root@master ~]# kubectl label pods pod-first release=v1
查看标签
#####若时默认命名空间此处不用加上-n test
[root@master ~]# kubectl get pods pod-first --show-labels -n test
NAME READY STATUS RESTARTS AGE LABELS
pod-first 1/1 Running 0 7m54s app=tomcat-pod-first,release=v1
创建pod时打标签
[root@master ~]# cat pod-label.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-nginx
labels:
version: "3.0"
env: "test"
spec:
containers:
- image: nginx
name: con-pod
ports:
- name: nginx-port
containerPort: 801
protocol: TCP
[root@master ~]# kubectl apply -f pod-label.yaml
查看此pod标签
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
pod-nginx 1/1 Running 0 5m51s
###查看所以pod标签
[root@master ~]# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
pod-nginx 1/1 Running 0 2m20s env=test,version=3.0
##查看指定标签
[root@master ~]# kubectl get pods pod-nginx --show-labels
查看资源标签
更换默认命名空间
此步可不做
[root@master ~]# kubectl config set-context --current --namespace=test
Context "kubernetes-admin@kubernetes" modified.
查看节点命名空间
[root@master ~]# kubectl get nodes --show-labels
查看默认命名空间下所有资源pod标签
[root@master ~]# kubectl get pods --show-labels
#查看默认名称空间下指定pod具有的所有标签
#####上面更换了默认命名空间所以此处执行会报错,正确要加:-n test
[root@master ~]# kubectl get pods pod-first --show-labels
#列出默认名称空间下标签key是release的pod,不显示标签
[root@master ~]# kubectl get pods -l release
#列出默认名称空间下标签key是release、值是v1的pod,不显示标签
[root@master ~]# kubectl get pods -l release=v1
列出默认名称空间下标签key是release的所有pod
[root@master ~]# kubectl get pods -L release
#查看所有名称空间下的所有pod的标签
[root@master ~]# kubectl get pods --all-namespaces --show-labels
[root@master ~]# kubectl get pods -l release=v1 -L release
pod资源清单详细解读
apiVersion: v1 #版本号,例如v1
kind: Pod #资源类型,如Pod
metadata: #元数据
name: string # Pod名字
namespace: string # Pod所属的命名空间
labels: #自定义标签
- name: string #自定义标签名字
annotations: #自定义注释列表
- name: string
spec: # Pod中容器的详细定义
containers: # Pod中容器列表
- name: string #容器名称
image: string #容器的镜像名称
imagePullPolicy: [Always | Never | IfNotPresent] #获取镜像的策略 Alawys表示下载镜像 IfnotPresent表示优先使用本地镜像,否则下载镜像,Nerver表示仅使用本地镜像
command: [string] #容器的启动命令列表,如不指定,使用打包时使用的启动命令
args: [string] #容器的启动命令参数列表
workingDir: string #容器的工作目录
volumeMounts: #挂载到容器内部的存储卷配置
- name: string #引用pod定义的共享存储卷的名称,需用volumes[]部分定义的的卷名
mountPath: string #存储卷在容器内mount的绝对路径,应少于512字符
readOnly: boolean #是否为只读模式
ports: #需要暴露的端口库号
- name: string #端口号名称
containerPort: int #容器需要监听的端口号
hostPort: int #容器所在主机需要监听的端口号,默认与Container相同
protocol: string #端口协议,支持TCP和UDP,默认TCP
env: #容器运行前需设置的环境变量列表
- name: string #环境变量名称
value: string #环境变量的值
resources: #资源限制和请求的设置
limits: #资源限制的设置
cpu: string #cpu的限制,单位为core数
memory: string #内存限制,单位可以为Mib/Gib
requests: #资源请求的设置
cpu: string #cpu请求,容器启动的初始可用数量
memory: string #内存请求,容器启动的初始可用内存
livenessProbe: #对Pod内个容器健康检查的设置,当探测无响应几次后将自动重启该容器,检查方法有exec、httpGet和tcpSocket,对一个容器只需设置其中一种方法即可
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的重启策略,Always表示一旦不管以何种方式终止运行,kubelet都将重启,OnFailure表示只有Pod以非0退出码退出才重启,Nerver表示不再重启该Pod
nodeSelector: obeject #设置NodeSelector表示将该Pod调度到包含这个label的node上,以key:value的格式指定
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的存储卷,挂载集群与定义的secre对象到容器内部
scretname: string
items:
- key: string
path: string
configMap: #类型为configMap的存储卷,挂载预定义的configMap对象到容器内部
name: string
items:
- key: string
path: string
node节点选择器
在创建pod资源的时候,pod会根据schduler进行调度,那么默认会调度到随机的一个工作节点,如果我们想要pod调度到指定节点或者调度到一些具有相同特点的node节点,可以使用pod中的nodeName或者nodeSelector字段指定要调度到的node节点
nodeName
查看节点
[root@master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master Ready master 16d v1.18.1
node1 Ready <none> 16d v1.18.1
编写文件指定运行在master节点
[root@master ~]# cat pod-master.yaml
apiVersion: v1
kind: Pod
metadata:
name: demo-pod
namespace: default
labels:
app: myapp
env: dev
spec:
nodeName: master ###指定在master节点
containers:
- name: tomcat-pod-java
ports:
- containerPort: 8081
image: tomcat:8.5-jre8-alpine
imagePullPolicy: IfNotPresent
- name: busybox
image: busybox:latest
command:
- "/bin/sh"
- "-c"
- "sleep 3600"
拉取镜像
###在master节点拉取:因为文件中指定在master中创建
[root@master ~]# docker load -i busybox.tar.gz
[root@master ~]# docker load -i tomcat.tar.gz
[root@master yam]# kubectl apply -f pod-master.yaml
查看
##可看到上面创建的在master节点
[root@master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
demo-pod 2/2 Running 0 2m2s 10.244.0.6 master <none> <none>
nodeSelector
指定pod调度到具有哪些标签的node节点上
查看节点
[root@master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master Ready master 16d v1.18.1
node1 Ready <none> 16d v1.18.1
#给node节点打标签,打个具有disk=ceph的标签
[root@master ~]# kubectl label nodes node1 disk=ceph
node/node1 labeled
#定义pod的时候指定要调度到具有disk=ceph标签的node上
[root@master ~]# cat pod-node1.yaml
apiVersion: v1
kind: Pod
metadata:
name: demo-pod-1
namespace: default
labels:
app: myapp
env: dev
spec:
nodeSelector:
disk: ceph ###指定到含有ceph标签的节点上
containers:
- name: tomcat-pod-java
ports:
- containerPort: 8083
image: tomcat:8.5-jre8-alpine
imagePullPolicy: IfNotPresent
[root@master ~]# kubectl apply -f pod-node1.yaml
pod/demo-pod-1 created
查看
[root@master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
demo-pod-1 1/1 Running 0 13s 10.244.1.4 node1 <none> <none>
污点和容忍度
node节点亲和性
node节点亲和性调度:nodeAffinity
###查看文档
[root@master ~]# kubectl explain pods.spec.affinity
KIND: Pod
VERSION: v1
RESOURCE: affinity <Object>
FIELDS:
nodeAffinity <Object>
podAffinity <Object>
podAntiAffinity <Object>
[root@master ~]# kubectl explain pods.spec.affinity.nodeAffinity
KIND: Pod
VERSION: v1
RESOURCE: nodeAffinity <Object>
DESCRIPTION:
preferredDuringSchedulingIgnoredDuringExecution <[]Object>
requiredDuringSchedulingIgnoredDuringExecution <Object>
prefered表示有节点尽量满足这个位置定义的亲和性,这不是一个必须的条件,软亲和性
require表示必须有节点满足这个位置定义的亲和性,这是个硬性条件,硬亲和性
[root@master ~]# kubectl explain pods.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution
KIND: Pod
VERSION: v1
FIELDS:
nodeSelectorTerms <[]Object> -required-
[root@master ~]# kubectl explain pods.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms
KIND: Pod
VERSION: v1
FIELDS:
matchExpressions <[]Object>
matchFields <[]Object>
[root@master ~]# kubectl explain pods.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms.matchFields
KIND: Pod
VERSION: v1
FIELDS:
key <string> -required-
operator <string> -required-
values <[]string>
[root@master ~]# kubectl explain pods.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms.matchExpressions
KIND: Pod
VERSION: v1
FIELDS:
key <string> -required- ###检查label
operator <string> -required- ###做等值选则还是不等值选则
values <[]string> ###给定值
例1:使用requiredDuringSchedulingIgnoredDuringExecution硬亲和性
硬亲和:若节点没有和标签相同的则不运行
在node1节点拉取镜像
[root@node1 ~]# docker load -i myapp-v1.tar.gz
[root@master ~]# cat pod-nodeaffinity-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-node-affinity-demo
namespace: default
labels:
app: myapp
tier: frontend
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
affinity: #####
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: zone ###检查zone标签
operator: In
values:
- foo ###值
- bar ###值
#####我们检查当前节点中有任意一个节点拥有zone标签的值是foo或者bar,就可以把pod调度到这个node节点的foo或者bar标签上的节点上
[root@master ~]# kubectl apply -f pod-nodeaffinity-demo.yaml
pod/pod-node-affinity-demo created
查看
[root@master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-node-affinity-demo 0/1 Pending 0 7s <none> <none> <none> <none>
status的状态是pending,上面说明没有完成调度,因为没有一个拥有zone的标签的值是foo或者bar,而且使用的是硬亲和性,必须满足条件才能完成调度
###给node1节点打zone标签,值为foo
[root@master ~]# kubectl label nodes node1 zone=foo
node/node1 labeled
[root@master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-node-affinity-demo 1/1 Running 0 58s 10.244.1.5 node1 <none> <none>
扩展--参数编写技巧
[root@master ~]# kubectl explain pod.spec| grep affi
例2:使用preferredDuringSchedulingIgnoredDuringExecution软亲和性
软亲和:优先在节点找和标签相同的没有也会运行
[root@master ~]# cat pod-nodeaffinity-demo-2.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-node-affinity-demo-2
namespace: default
labels:
app: myapp
tier: frontend
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- preference:
matchExpressions:
- key: zone1
operator: In
values:
- fool
- barl
weight: 60
[root@master ~]# kubectl apply -f pod-nodeaffinity-demo-2.yaml
pod/pod-node-affinity-demo-2 created
[root@master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-node-affinity-demo-2 1/1 Running 0 17s 10.244.1.6 node1 <none> <none>
####上面说明软亲和性是可以运行这个pod的,尽管没有运行这个pod的节点定义的zone1标签
Node节点亲和性针对的是pod和node的关系,Pod调度到node节点的时候匹配的条件
pod节点亲和性
pod自身的亲和性调度有两种表示形式
podaffinity:pod和pod更倾向腻在一起,把相近的pod结合到相近的位置,如同一区域,同一机架,这样的话pod和pod之间更好通信
podunaffinity:pod和pod更倾向不腻在一起,如果部署两套程序,那么这两套程序更倾向于反亲和性,这样相互之间不会有影响。
第一个pod随机选则一个节点,做为评判后续的pod能否到达这个pod所在的节点上的运行方式,这就称为pod亲和性;
以节点名称为标准,这个节点名称相同的表示是同一个位置,节点名称不相同的表示不是一个位置。
[root@master ~]# kubectl explain pods.spec.affinity.podAffinity
KIND: Pod
VERSION: v1
FIELDS:
preferredDuringSchedulingIgnoredDuringExecution <[]Object>
requiredDuringSchedulingIgnoredDuringExecution <[]Object>
requiredDuringSchedulingIgnoredDuringExecution: 硬亲和性
preferredDuringSchedulingIgnoredDuringExecution:软亲和性
[root@master ~]# kubectl explain pods.spec.affinity.podAffinity.requiredDuringSchedulingIgnoredDuringExecution
KIND: Pod
VERSION: v1
FIELDS:
labelSelector <Object>
namespaces <[]string>
topologyKey <string> -required- ###位置拓扑的键,这个是必须字段
怎么判断是不是同一个位置:
rack=rack1
row=row1
使用rack的键是同一个位置
使用row的键是同一个位置
labelSelector:
我们要判断pod跟别的pod亲和,跟哪个pod亲和,需要靠labelSelector,通过labelSelector选则一组能作为亲和对象的pod资源
namespace:
labelSelector需要选则一组资源,那么这组资源是在哪个名称空间中呢,通过namespace指定,如果不指定namespaces,那么就是当前创建pod的名称空间
[root@master ~]# kubectl explain pods.spec.affinity.podAffinity.requiredDuringSchedulingIgnoredDuringExecution.labelSelector
KIND: Pod
VERSION: v1
FIELDS:
matchExpressions <[]Object>
matchLabels <map[string]string>
例1:pod节点亲和性
定义两个pod,第一个pod做为基准,第二个pod跟着它走
[root@master ~]# kubectl delete pods pod-first
[root@master ~]# cat pod-required-affinity-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-first
labels:
app2: myapp2
tier: frontend
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
---
apiVersion: v1
kind: Pod
metadata:
name: pod-second
labels:
app: backup
tier: db
spec:
containers:
- name: busybox
image: busybox:latest
imagePullPolicy: IfNotPresent
command: ["sh","-c","sleep 3600"]
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- {key: app2, operator: In, values: ["myapp2"]}
topologyKey: kubernetes.io/hostname
#上面表示创建的pod必须与拥有app=myapp标签的pod在一个节点上
[root@master ~]# kubectl apply -f pod-required-affinity-demo.yaml
pod/pod-first created
pod/pod-second created
查看
[root@master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-first 1/1 Running 0 15s 10.244.1.7 node1 <none> <none>
pod-second 1/1 Running 0 15s 10.244.1.8 node1 <none> <none>
###查看标签
[root@master ~]# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
pod-first 1/1 Running 0 80s app2=myapp2,tier=frontend
pod-second 1/1 Running 0 80s app=backup,tier=db
上面说明第一个pod调度到哪,第二个pod也调度到哪,这就是pod节点亲和性
####删除
[root@master ~]# kubectl delete -f pod-required-affinity-demo.yaml
例2:pod节点反亲和性
定义两个pod,第一个pod做为基准,第二个pod跟它调度节点相反
[root@master ~]# cat pod-required-anti-affinity-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-first
labels:
app1: myapp1
tier: frontend
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
---
apiVersion: v1
kind: Pod
metadata:
name: pod-second
labels:
app: backend
tier: db
spec:
containers:
- name: busybox
image: busybox:latest
command: ["sh","-c","sleep 3600"]
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- {key: app1, operator: In, values: ["myapp1"]}
topologyKey: kubernetes.io/hostname
[root@master ~]# kubectl apply -f pod-required-anti-affinity-demo.yaml
pod/pod-first unchanged
pod/pod-second created
[root@master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-first 1/1 Running 0 113s 10.244.1.9 node1 <none> <none>
pod-second 0/1 ContainerCreating 0 11s <none> master <none> <none>
#####删除
[root@master ~]# kubectl delete -f pod-required-anti-affinity-demo.yaml
例3:换一个topologykey
[root@master ~]# kubectl label nodes node1 zone=foo
[root@master ~]# kubectl label nodes master zone=foo --overwrite
[root@master ~]# kubectl get nodes --show-labels
[root@master ~]# cat pod-first-required-anti-affinity-demo-1.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-first
labels:
app3: myapp3
tier: frontend
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
[root@master ~]# cat pod-second-required-anti-affinity-demo-1.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-second
labels:
app: backend
tier: db
spec:
containers:
- name: busybox
image: busybox:latest
imagePullPolicy: IfNotPresent
command: ["sh","-c","sleep 3600"]
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- {key: app3 ,operator: In, values: ["myapp3"]}
topologyKey: zone
[root@master ~]# kubectl apply -f pod-first-required-anti-affinity-demo-1.yaml
pod/pod-first created
[root@master ~]# kubectl apply -f pod-second-required-anti-affinity-demo-1.yaml
pod/pod-second created
[root@master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-first 1/1 Running 0 19s 10.244.1.10 node1 <none> <none>
pod-second 0/1 Pending 0 9s <none> <none> <none> <none>
第二个节点现是pending,因为两个节点是同一个位置,现在没有不是同一个位置的了,而且我们要求反亲和性,所以就会处于pending状态,如果在反亲和性这个位置把required改成preferred,那么也会运行。
podaffinity:pod节点亲和性,pod倾向于哪个pod
nodeaffinity:node节点亲和性,pod倾向于哪个node
污点,容忍度
给了节点选则的主动权,我们给节点打一个污点,不容忍的pod就运行不上来,污点就是定义在节点上的键值属性数据,可以决定拒绝那些pod;
taints是键值数据,用在节点上,定义污点;
tolerations是键值数据,用在pod上,定义容忍度,能容忍哪些污点
pod亲和性是pod属性;但是污点是节点的属性,污点定义在nodeSelector上
查看master节点是否有污点
[root@master ~]# kubectl describe nodes master
Taints: <none> ###可看到master节点没有污点
[root@master ~]# kubectl explain node.spec.taints
KIND: Node
VERSION: v1
FIELDS:
effect <string> -required-
key <string> -required-
timeAdded <string>
value <string>
在pod对象定义容忍度的时候支持两种操作:
1.等值密钥:key和value上完全匹配
2.存在性判断:key和effect必须同时匹配,value可以是空
在pod上定义的容忍度可能不止一个,在节点上定义的污点可能多个,需要琢个检查容忍度和污点能否匹配,每一个污点都能被容忍,才能完成调度,如果不能容忍,那就需要看pod的容忍度了
查看pod容忍度
[root@master ~]# kubectl describe pods kube-apiserver-master -n kube-system
Node-Selectors: <none>
Tolerations: :NoExecute
Events:
可以看到这个pod的容忍度是NoExecute,则可以调度到master上
管理节点污点
[root@master ~]# kubectl taint --help
例1:把node1当成是生产环境专用的,其他node是测试的
[root@master ~]# kubectl taint node node1 node-type=production:NoSchedule
node/node1 tainted
给node1打污点,pod如果不能容忍就不会调度过来)
[root@master ~]# cat pod-taint.yaml
apiVersion: v1
kind: Pod
metadata:
name: taint-pod
namespace: default
labels:
tomcat: tomcat-pod
spec:
containers:
- name: taint-pod
ports:
- containerPort: 8083
image: tomcat:8.5-jre8-alpine
imagePullPolicy: IfNotPresent
[root@master ~]# kubectl apply -f pod-taint.yaml
[root@master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
taint-pod 1/1 Running 0 74s 10.244.0.6 master <none> <none>
可以看到都被调度到master上了,因为node1这个节点打了污点,而我们在创建pod的时候没有容忍度,所以node1上不会有pod调度上去的
例2:给master也打上污点
[root@master ~]# kubectl taint node master node-type=dev:NoExecute
node/master tainted
[root@master ~]# kubectl get pods -o wide
可以看到已经存在的pod节点都被撵走了
[root@master ~]# cat pod-demo-1.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp-deploy
namespace: default
labels:
app: myapp
release: canary
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
ports:
- name: http
containerPort: 83
tolerations:
- key: "node-type"
operator: "Equal"
value: "production"
effect: "NoExecute"
tolerationSeconds: 3600
[root@master ~]# kubectl apply -f pod-demo-1.yaml
pod/myapp-deploy created
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
myapp-deploy 0/1 Pending 0
还是显示pending,因为我们使用的是equal(等值匹配),所以key和value,effect必须和node节点定义的污点完全匹配才可以,把上面配置effect: "NoExecute"变成
effect: "NoSchedule"; tolerationSeconds: 3600这行去掉
[root@master ~]# kubectl delete -f pod-demo-1.yaml
[root@master ~]# vi pod-demo-1.yaml
...
value: "production"
effect: "NoSchedule"
[root@master ~]# kubectl apply -f pod-demo-1.yaml
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
myapp-deploy 1/1 Running 0 5s
上面就可以调度到node上了,因为在pod中定义的容忍度能容忍node节点上的污点
例3:再次修改
[root@master ~]# kubectl delete -f pod-demo-1.yaml
[root@master ~]# vi pod-demo-1.yaml
tolerations:
- key: "node-type"
operator: "Exists"
value: ""
effect: "NoSchedule"
只要对应的键是存在的,exists,其值被自动定义成通配符
[root@master ~]# kubectl apply -f pod-demo-1.yaml
[root@master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
myapp-deploy 1/1 Running 0 19s 10.244.1.3 node1 <none> <none>
发现还是调度到node1上
再次修改:
[root@master ~]# kubectl delete -f pod-demo-1.yaml
[root@master ~]# vi pod-demo-1.yaml
tolerations:
- key: "node-type"
operator: "Exists"
value: ""
effect: ""
有一个node-type的键,不管值是什么,不管是什么效果,都能容忍
[root@master ~]# kubectl apply -f pod-demo-1.yaml
[root@master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
myapp-deploy 1/1 Running 0 8s 10.244.1.4 node1 <none> <none>
node1和master节点都有可能有pod被调度
删除污点
查看
[root@master ~]# kubectl describe nodes master | grep Taints
Taints: node-type=dev:NoExecute
删除
[root@master ~]# kubectl taint nodes master node-type=dev:NoExecute-
[root@master ~]# kubectl taint nodes node1 node-type-
pod常见状态和重启策略
常见状态
Pod的status定义在PodStatus对象中,其中有一个phase字段。它简单描述了Pod在其生命周期的阶段。
挂起(Pending):我们在请求创建pod时,条件不满足,调度没有完成,没有任何一个节点能满足调度条件,已经创建了pod但是没有适合它运行的节点叫做挂起,调度没有完成,处于pending的状态会持续一段时间:包括调度Pod的时间和通过网络下载镜像的时间。
运行中(Running):Pod已经绑定到了一个节点上,Pod 中所有的容器都已被创建。至少有一个容器正在运行,或者正处于启动或重启状态。
成功(Succeeded):Pod 中的所有容器都被成功终止,并且不会再重启。
失败(Failed):Pod 中的所有容器都已终止了,并且至少有一个容器是因为失败终止。也就是说,容器以非0状态退出或者被系统终止。
未知(Unknown):未知状态,所谓pod是什么状态是apiserver和运行在pod节点的kubelet进行通信获取状态信息的,如果节点之上的kubelet本身出故障,那么apiserver就连不上kubelet,得不到信息了,就会看Unknown
扩展
Evicted状态:出现这种情况,多见于系统内存或硬盘资源不足,可df-h查看docker存储所在目录的资源使用情况,如果百分比大于85%,就要及时清理下资源,尤其是一些大文件、docker镜像。
CrashLoopBackOff:容器曾经启动了,但可能又异常退出了
Error 状态:Pod 启动过程中发生了错误
重启策略
pod的重启策略是指当pod中的容器中终止退出后,重启容器的策略。
重器容器的做法实际上就是重建容器,所有容器中数据会丢失。
Pod的重启策略(RestartPolicy)应用于Pod内的所有容器,并且仅在Pod所处的Node上由kubelet进行判断和重启操作。
Pod的重启策略包括:Always、OnFailure和Never,默认值为Always
Always:当容器失败时,由kubelet自动重启该容器。
OnFailure:当容器终止运行且退出码不为0时,由kubelet自动重启该容器。
Never:不论容器运行状态如何,kubelet都不会重启该容器。
[root@master ~]# cat pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: demo-pod
namespace: default
labels:
app: myapp
spec:
restartPolicy: Always #####重启策略
containers:
- name: tomcat-pod-java
ports:
- containerPort: 8084
image: tomcat:8.5-jre8-alpine
imagePullPolicy: IfNotPresent
[root@master ~]# kubectl apply -f pod.yaml
创建一个pod,其中的容器将异常退出(exit 1)
[root@master ~]# cat pod-exit.yaml
apiVersion: v1
kind: Pod
metadata:
name: exam-exit
spec:
containers:
- name: con-exit
image: mysql:5.7
command: ["bash","-c","exit 1"]
restartPolicy: OnFailure
[root@master ~]# kubectl apply -f pod-exit.yaml
[root@master ~]# kubectl get pods -w
NAME READY STATUS RESTARTS AGE
exam-exit 0/1 CrashLoopBackOff 1 7s
exam-exit 0/1 Error 2 19s
exam-exit 0/1 CrashLoopBackOff 2 33s
查询每个容器的重启次数
[root@master ~]# kubectl get pod exam-exit --template="{{range .status.containerStatuses}}{{.name}}:{{.restartCount}}{{end}}"
con-exit:5
pod生命周期
pod的生命周期可用简单描述为,首先pod被创建,接着pod被调度到node进行部署运行。
Init容器
Pod 里面可以有一个或者多个容器,部署应用的容器可以称为主容器,在创建Pod时候,Pod 中可以有一个或多个先于主容器启动的Init容器,这个init容器就可以成为初始化容器,初始化容器一旦执行完,它从启动开始到初始化代码执行完就退出了,它不会一直存在,所以在主容器启动之前执行初始化,初始化容器可以有多个,多个初始化容器是要串行执行的,先执行初始化容器1,在执行初始化容器2等,等初始化容器执行完初始化就退出了,然后再执行主容器,主容器一退出,pod就结束了,主容器退出的时间点就是pod的结束点,它俩时间轴是一致的;
Init容器就是做初始化工作的容器。可以有一个或多个,如果多个按照定义的顺序依次执行,只有所有的初始化容器执行完后,主容器才启动。由于一个Pod里的存储卷是共享的,所以Init Container里产生的数据可以被主容器使用到,Init Container可以在多种K8S资源里被使用到,如Deployment、DaemonSet, StatefulSet、Job等,但都是在Pod启动时,在主容器启动前执行,做初始化工作。
Init容器与普通的容器区别是:
1、Init 容器不支持 Readiness,因为它们必须在Pod就绪之前运行完成
2、每个Init容器必须运行成功,下一个才能够运行
3、如果 Pod 的 Init 容器失败,Kubernetes 会不断地重启该 Pod,直到 Init 容器成功为止,然而,如果Pod对应的restartPolicy值为 Never,它不会重新启动。
初始化容器的官方地址:
https://kubernetes.io/docs/concepts/workloads/pods/init-containers/#init-containers-in-use
[root@master init]# cat init.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: busybox:latest
command: ['sh','-c','echo The app is running! && sleep 3600']
initContainers:
- name: init-myservice
image: busybox:latest
command: ['sh','-c',"until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"]
- name: init-mydb
image: busybox:latest
command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]
本例pod中包含一个名为myapp-container的容器和二个名为init-my..的初始化容器,其中初始化容器用于执行初始化脚本,会执行2s
[root@master init]# kubectl apply -f init.yaml
[root@master init]# kubectl get pods
NAME READY STATUS RESTARTS AGE
myapp-pod 0/1 Init:0/2 0 4s
[root@master init]# cat service.yaml
---
apiVersion: v1
kind: Service
metadata:
name: myservice
spec:
ports:
- protocol: TCP
port: 84
targetPort: 9376
---
apiVersion: v1
kind: Service
metadata:
name: mydb
spec:
ports:
- protocol: TCP
port: 84
targetPort: 9377
[root@master init]# kubectl apply -f service.yaml
service/myservice created
service/mydb created
[root@master init]# kubectl get pods -w
NAME READY STATUS RESTARTS AGE
myapp-pod 0/1 Init:1/2 0 13m
myapp-pod 0/1 Init:1/2 0 14m
myapp-pod 0/1 PodInitializing 0 14m
myapp-pod 1/1 Running 0 14m
查询pod处于生命周期哪个阶段
[root@master ~]# kubectl get pods myapp-pod --template="{{.status.phase}}"
Running
主容器
容器钩子
初始化容器启动之后,开始启动主容器,在主容器启动之前有一个post start hook(容器启动后钩子)和pre stop hook(容器结束前钩子),无论启动后还是结束前所做的事我们可以把它放两个钩子,这个钩子就表示用户可以用它来钩住一些命令,来执行它,做开场前的预设,结束前的清理,如awk有begin,end,和这个效果类似;
postStart:该钩子在容器被创建后立刻触发,通知容器它已经被创建。如果该钩子对应的hook handler执行失败,则该容器会被杀死,并根据该容器的重启策略决定是否要重启该容器,这个钩子不需要传递任何参数。
preStop:该钩子在容器被删除前触发,其所对应的hook handler必须在删除该容器的请求发送给Docker daemon之前完成。在该钩子对应的hook handler完成后不论执行的结果如何,Docker daemon会发送一个SGTERN信号量给Docker daemon来删除该容器,这个钩子不需要传递任何参数。
在k8s中支持两类对pod的检测,第一类叫做livenessprobe(pod存活性探测):
存活探针主要作用是,用指定的方式检测pod中的容器应用是否正常运行,如果检测失败,则认为容器不健康,那么Kubelet将根据Pod中设置的 restartPolicy来判断Pod 是否要进行重启操作,如果容器配置中没有配置 livenessProbe,Kubelet 将认为存活探针探测一直为成功状态。
第二类是状态检readinessprobe(pod就绪性探测):用于判断容器中应用是否启动完成,当探测成功后才使Pod对外提供网络访问,设置容器Ready状态为true,如果探测失败,则设置容器的Ready状态为false。
pod容器探测和钩子
容器钩子
postStart:容器创建成功后,运行前的任务,用于资源部署、环境准备等。
preStop:在容器被终止前的任务,用于优雅关闭应用程序、通知其他系统等。
演示postStart和preStop用法
containers:
- image: sample:v2
name: war
lifecycle:
postStart:
exec: #在容器中执行指定的命令
command: #需要执行的命令
- “cp”
- “/sample.war”
- “/app”
prestop:
httpGet:
host: monitor.com #请求的ip
path: /waring #请求的URL路径
port: 8080 #请求的端口
scheme: HTTP #请求的协议
以上示例中,定义了一个Pod,包含一个JAVA的web应用容器,其中设置了PostStart和PreStop回调函数。即在容器创建成功后,复制/sample.war到/app文件夹中。而在容器终止之前,发送HTTP请求到http://monitor.com:8080/waring,即向监控系统发送警告。
优雅的删除资源对象
当用户请求删除含有pod的资源对象时(如RC、deployment等),K8S为了让应用程序优雅关闭(即让应用程序完成正在处理的请求后,再关闭软件),K8S提供两种信息通知:
1)、默认:K8S通知node执行docker stop命令,docker会先向容器中PID为1的进程发送系统信号SIGTERM,然后等待容器中的应用程序终止执行,如果等待时间达到设定的超时时间,或者默认超时时间(30s),会继续发送SIGKILL的系统信号强行kill掉进程。
2)、使用pod生命周期(利用PreStop回调函数),它执行在发送终止信号之前。
默认情况下,所有的删除操作的优雅退出时间都在30秒以内。kubectl delete命令支持--grace-period=的选项,以运行用户来修改默认值。0表示删除立即执行,并且立即从API中删除pod。在节点上,被设置了立即结束的的pod,仍然会给一个很短的优雅退出时间段,才会开始被强制杀死。如下:
spec:
containers:
- name: nginx-demo
image: centos:nginx
lifecycle: ###用于在容器运行前或关闭前的一些动作
preStop: ####容器被终止前,用于关闭应用程序,通知其他系统等
exec:
# nginx -s quit gracefully terminate while SIGTERM triggers a quick exit
command: ["/usr/local/nginx/sbin/nginx","-s","quit"]
ports:
- name: http
containerPort: 80
[root@master ~]# cat pod-prestop.yaml
apiVersion: v1
kind: Pod
metadata:
name: exam-prestart.yaml
spec:
containers:
- name: con-start
image: busybox
imagePullPolicy: IfNotPresent
command: ['sh','-c']
args: ['echo "Hello kubernetes!"; sleep 3600']
lifecycle: ###用于在容器运行前或关闭前的一些动作
postStart: ###容器创建成功后,运行前的任务
httpGet:
host: www.baidu.com ##请求的ip
path: / ##请求的URL路径
port: 80 ##请求的端口
scheme: HTTP ##请求的协议
preStop: ####容器被终止前,用于关闭应用程序,通知其他系统等
exec:
command: ['sh','-c','echo "preStop callback done!";sleep 60']
----本实验使用了postStart事件执行HttpGet回调,postStart执行命令并输入一段文本,之后停留60s
开启新终端持续查看
[root@master ~]# kubectl get pods -w
NAME READY STATUS RESTARTS AGE
exam-prestart.yaml 0/1 Pending 0 0s
exam-prestart.yaml 0/1 ContainerCreating 0 0s
exam-prestart.yaml 1/1 Running 0 18s
exam-prestart.yaml 1/1 Terminating 0 69s
exam-prestart.yaml 0/1 Terminating 0 102s
exam-prestart.yaml 0/1 Terminating 0 107s
exam-prestart.yaml 0/1 Terminating 0 107s
exam-exit 0/1 Error 10 26m
exam-exit 0/1 CrashLoopBackOff 10 26m
[root@master ~]# kubectl apply -f pod-prestop.yaml
---设置了60s的等待时间,在执行删除命令时,由于要回调,因此要等60s才正式开始删除pod,在这段时间内,pod仍然处于可访问的运行状态
[root@master ~]# kubectl delete -f pod-prestop.yaml
###执行删除命令后查看日志文件依然可以查看到
[root@master ~]# kubectl logs exam-prestart.yaml
Hello kubernetes!
存活性探测livenessProbe和就绪性探测readinessProbe
livenessProbe:存活性探测
许多应用程序经过长时间运行,最终过渡到无法运行的状态,除了重启,无法恢复。K8S提供livenessProbe来检测容器是否正常运行,并且对相应状况进行相应的补救措施。
readinessProbe:就绪性探测
在没有配置readinessProbe的资源对象中,pod中的容器启动完成后,就认为pod中的应用程序可以对外提供服务,该pod就会加入相对应的service,对外提供服务。但有时一些应用程序启动后,需要较长时间的加载才能对外服务,如果这时对外提供服务,执行结果必然无法达到预期效果,影响用户体验。
目前LivenessProbe和ReadinessProbe两种探针都支持下面三种探测方法:
1、ExecAction:在容器中执行指定的命令,如果执行成功,退出码为 0 则探测成功。
2、TCPSocketAction:通过容器的 IP 地址和端口号执行 TCP 检 查,如果能够建立 TCP 连接,则表明容器健康。
3、HTTPGetAction:通过容器的IP地址、端口号及路径调用 HTTP Get方法,如果响应的状态码大于等于200且小于400,则认为容器健康
探针探测结果有以下值:
1、Success:表示通过检测。
2、Failure:表示未通过检测。
3、Unknown:表示检测没有正常进行。
Pod探针相关的属性:
探针(Probe)有许多可选字段,可以用来更加精确的控制Liveness和Readiness两种探针的行为
initialDelaySeconds: Pod启动后首次进行检查的等待时间,单位“秒”。
periodSeconds: 检查的间隔时间,默认为10s,单位“秒”。
timeoutSeconds: 探针执行检测请求后,等待响应的超时时间,默认为1s,单位“秒”。
successThreshold:连续探测几次成功,才认为探测成功,默认为 1,在 Liveness 探针中必须为1,最小值为1。
failureThreshold: 探测失败的重试次数,重试一定次数后将认为失败,在 readiness 探针中,Pod会被标记为未就绪,默认为 3,最小值为 1
两种探针区别:
ReadinessProbe 和 livenessProbe 可以使用相同探测方式,只是对 Pod 的处置方式不同:
readinessProbe 当检测失败后,将 Pod 的 IP:Port 从对应的 EndPoint 列表中删除。
livenessProbe 当检测失败后,将杀死容器并根据 Pod 的重启策略来决定作出对应的措施。
Pod探针使用示例:
1、LivenessProbe 探针使用示例
(1)、通过exec方式做健康探测
ExecAction:在容器内部执行指定命令。若状态码为0退出,则测定为诊断成功
[root@master ~]# cat liveness-exec.yaml
apiVersion: v1
kind: Pod
metadata:
name: liveness-exec
labels:
app: liveness
spec:
containers:
- name: liveness
image: busybox
args: ####创建测试探针探测的文件
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
livenessProbe:
initialDelaySeconds: 10 ####延迟检测时间
periodSeconds: 5 ####检测时间间隔
exec:
command: #命令列表
- cat
- /tmp/healthy
打开一个新终端执行持续查看
[root@master ~]# kubectl get pods -w
NAME READY STATUS RESTARTS AGE
#####执行后的结果
liveness-exec 0/1 Pending 0 0s
liveness-exec 0/1 Pending 0 0s
liveness-exec 0/1 ContainerCreating 0 0s
liveness-exec 1/1 Running 0 17s
liveness-exec 1/1 Running 1 117s
执行
[root@master ~]# kubectl apply -f liveness-exec.yaml
pod/liveness-exec created
容器启动设置执行的命令:
/bin/sh -c "touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600"
容器在初始化后,首先创建一个 /tmp/healthy 文件,然后执行睡眠命令,睡眠 30 秒,到时间后执行删除 /tmp/healthy 文件命令。而设置的存活探针检检测方式为执行 shell 命令,用 cat 命令输出 healthy 文件的内容,如果能成功执行这条命令,存活探针就认为探测成功,否则探测失败。在前 30 秒内,由于文件存在,所以存活探针探测时执行 cat /tmp/healthy 命令成功执行。30 秒后 healthy 文件被删除,所以执行命令失败,Kubernetes 会根据 Pod 设置的重启策略来判断,是否重启 Pod。
(2)、通过HTTP方式做健康探测
HTTPGetAction对容器IP地址的指定端口和执行HttpGet请求,若范围为200~400则检测成功
[root@master ~]# cat liveness-http.yaml
apiVersion: v1
kind: Pod
metadata:
name: liveness-http
labels:
test: liveness
spec:
containers:
- name: liveness
image: mydlqclub/springboot-helloworld:0.0.1
livenessProbe:
initialDelaySeconds: 20 #####延迟加载时间
periodSeconds: 5 #####重试时间间隔
timeoutSeconds: 10 #####超时时间设置
httpGet:
scheme: HTTP ##请求的协议
port: 8085 #指定端口号
path: /actuator/health #指定的路径
新开起一个终端持续查看
[root@master ~]# kubectl get pods -w
NAME READY STATUS RESTARTS AGE
liveness-http 0/1 Pending 0 0s
liveness-http 0/1 Pending 0 0s
liveness-http 0/1 ContainerCreating 0 0s
liveness-http 1/1 Running 0 2s
liveness-http 1/1 Running 1 35s
liveness-http 1/1 Running 2 65s
liveness-http 0/1 CrashLoopBackOff 4 2m35s
[root@master ~]# kubectl apply -f liveness-http.yaml
上面 Pod 中启动的容器是一个 SpringBoot 应用,其中引用了 Actuator 组件,提供了 /actuator/health 健康检查地址,存活探针可以使用 HTTPGet 方式向服务发起请求,请求 8081 端口的 /actuator/health 路径来进行存活判断:
任何大于或等于200且小于400的代码表示探测成功。
任何其他代码表示失败。
如果探测失败,则会杀死 Pod 进行重启操作。
httpGet探测方式有如下可选的控制字段:
scheme: 用于连接host的协议,默认为HTTP。
host:要连接的主机名,默认为Pod IP,可以在http request head中设置host头部。
port:容器上要访问端口号或名称。
path:http服务器上的访问URI。
httpHeaders:自定义HTTP请求headers,HTTP允许重复headers。
(3)、通过TCP方式做健康探测
TCPSocketAction对容器ip地址的指定端口执行TCP检测,若端口是打开的,则测定成功
[root@master ~]# cat liveness-tcp.yaml
apiVersion: v1
kind: Pod
metadata:
name: liveness-tcp
labels:
app: liveness
spec:
containers:
- name: liveness
image: nginx
livenessProbe:
initialDelaySeconds: 15
periodSeconds: 20
tcpSocket:
port: 87 #检查的TCP端口
新开一个终端持续查看
[root@master ~]# kubectl get pods -w
NAME READY STATUS RESTARTS AGE
liveness-tcp 0/1 Pending 0 0s
liveness-tcp 0/1 Pending 0 0s
liveness-tcp 0/1 ContainerCreating 0 1s
liveness-tcp 1/1 Running 0 40s
liveness-tcp 1/1 Running 1 2m
liveness-tcp 1/1 Running 1 2m
[root@master ~]# kubectl apply -f liveness-tcp.yaml
TCP 检查方式和 HTTP 检查方式非常相似,在容器启动 initialDelaySeconds 参数设定的时间后,kubelet 将发送第一个 livenessProbe 探针,尝试连接容器的 80 端口,如果连接失败则将杀死 Pod 重启容器。
2、ReadinessProbe 探针使用示例
Pod 的ReadinessProbe 探针使用方式和 LivenessProbe 探针探测方法一样,也是支持三种,只是一个是用于探测应用的存活,一个是判断是否对外提供流量的条件。这里用一个 Springboot 项目,设置 ReadinessProbe 探测 SpringBoot 项目的 8081 端口下的 /actuator/health 接口,如果探测成功则代表内部程序以及启动,就开放对外提供接口访问,否则内部应用没有成功启动,暂不对外提供访问,直到就绪探针探测成功。
[root@master ~]# cat readiness-exec.yaml
apiVersion: v1
kind: Service
metadata:
name: springboot
labels:
app: springboot
spec:
type: NodePort
ports:
- name: server
port: 8082
targetPort: 8082
nodePort: 31180
- name: management
port: 8083
targetPort: 8083
nodePort: 31181
selector:
app: springboot
---
apiVersion: v1
kind: Pod
metadata:
name: springboot
labels:
app: apringboot
spec:
containers:
- name: springboot
image: mydlqclub/springboot-helloworld:0.0.1
ports:
- name: server
containerPort: 8082
- name: management
containerPort: 8083
readinessProbe:
initialDelaySeconds: 20
periodSeconds: 5
timeoutSeconds: 10
httpGet:
scheme: HTTP
port: 8083
path: /actuator/health
[root@master ~]# kubectl apply -f readiness-exec.yaml
service/springboot created
pod/springboot created
3、ReadinessProbe + LivenessProbe 配合使用示例
一般程序中需要设置两种探针结合使用,并且也要结合实际情况,来配置初始化检查时间和检测间隔,下面列一个简单的 SpringBoot 项目的 Deployment 例子。
[root@master ~]# cat readiness-libe.yaml
apiVersion: v1
kind: Service
metadata:
name: springboot
labels:
app: springboot
spec:
type: NodePort
ports:
- name: server
port: 8082
targetPort: 8082
nodePort: 31180
- name: management
port: 8083
targetPort: 8083
nodePort: 31181
selector:
app: springboot
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: springboot
labels:
app: springboot
spec:
replicas: 1
selector:
matchLabels:
app: springboot
template:
metadata:
name: springboot
labels:
app: springboot
spec:
containers:
- name: readiness
image: mydlqclub/springboot-helloworld:0.0.1
ports:
- name: server
containerPort: 8082
- name: management
containerPort: 8083
readinessProbe:
initialDelaySeconds: 20
periodSeconds: 5
timeoutSeconds: 10
httpGet:
scheme: HTTP
port: 8083
path: /actuator/health
livenessProbe:
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
httpGet:
scheme: HTTP
port: 8083
path: /actuator/health
[root@master ~]# kubectl apply -f readiness-libe.yaml
service/springboot unchanged
deployment.apps/springboot created
pod模板
# yaml格式的pod定义文件完整内容:
apiVersion: v1 #必选,版本号,例如v1
kind: Pod #必选,Pod
metadata: #必选,元数据
name: string #必选,Pod名称
namespace: string #必选,Pod所属的命名空间
labels: #自定义标签
- name: string #自定义标签名字
annotations: #自定义注释列表
- name: string
spec: #必选,Pod中容器的详细定义
containers: #必选,Pod中容器列表
- name: string #必选,容器名称
image: string #必选,容器的镜像名称
imagePullPolicy: [Always | Never | IfNotPresent] #获取镜像的策略 Alawys表示下载镜像 IfnotPresent表示优先使用本地镜像,否则下载镜像,Nerver表示仅使用本地镜像
command: [string] #容器的启动命令列表,如不指定,使用打包时使用的启动命令
args: [string] #容器的启动命令参数列表
workingDir: string #容器的工作目录
volumeMounts: #挂载到容器内部的存储卷配置
- name: string #引用pod定义的共享存储卷的名称,需用volumes[]部分定义的的卷名
mountPath: string #存储卷在容器内mount的绝对路径,应少于512字符
readOnly: boolean #是否为只读模式
ports: #需要暴露的端口库号列表
- name: string #端口号名称
containerPort: int #容器需要监听的端口号
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 #内存清楚,容器启动的初始可用数量
livenessProbe: #对Pod内个容器健康检查的设置,当探测无响应几次后将自动重启该容器,检查方法有exec、httpGet和tcpSocket,对一个容器只需设置其中一种方法即可
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的重启策略,Always表示一旦不管以何种方式终止运行,kubelet都将重启,OnFailure表示只有Pod以非0退出码退出才重启,Nerver表示不再重启该Pod
nodeSelector: obeject #设置NodeSelector表示将该Pod调度到包含这个label的node上,以key:value的格式指定
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的存储卷,挂载集群与定义的secre对象到容器内部
scretname: string
items:
- key: string
path: string
configMap: #类型为configMap的存储卷,挂载预定义的configMap对象到容器内部
name: string
items:
- key: string
path: string
编辑日期:2021-12-26