pod介绍

pod定义与分类

Pod(豆荚) 是Kubernetes集群管理与调度的最小单元

2.一个Pod可以封装一个容器或多个容器(主容器或sidecar边车容器)

一个pod内的多个容器之间共享部分命名空间,例如:Net Namespace,UTS Namespace,IPC Namespace及存储资源、

用户pod默认会被调度运行在node节点之上(不运行在master节点上, 但也有例外情况)

pod内的IP不是固定的,集群外不能直接访问pod

可参考: https://kubernetes.io/zh/docs/concepts/workloads/pods/

pod可分为:

1.无控制器管理的自主式pod 没有副本控制器控制,删除自主式pod后不会重新创建

2.控制器管理的pod 控制器可以控制pod的副本数,扩容与裁剪,版本更新与回滚等

查看pod方法

pod是一种资源,可以通过kubectl get pod来查看

kubectl get pod # pod或pods都可以, 不指定namespace,默认是名为default的namespace

kubectl get pod -n kube-system

pod的YAML资源清单格式

先看一个yaml格式的pod定义文件解释

# yaml格式的pod定义文件完整内容:

apiVersion: v1       #必选,api版本号,例如v1

kind: Pod       #必选,Pod

metadata:       #必选,元数据

name: string       #必选,Pod名称

namespace: string    #Pod所属的命名空间,默认在default的 namespace

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的存储卷,挂载集群与定义的 secret对象到容器内部

scretname: string

items:

- key: string

path: string

configMap:     #类型为configMap的存储卷,挂载预定义的 configMap对象到容器内部

name: string

items:

- key: string

path: string

YAML格式查找帮助方法回顾

kubectl explain namespace #查找namespace

kubectl explain pod #查找pod

kubectl explain pod.spec #查找pod.spec

kubectl explain pod.spec.containers #pod.spec.containers

pod创建与验证

命令创建pod(v1.18变化)

k8s之前版本中, kubectl run命令用于创建deployment控制器 在v1.18版本中, kubectl run命令改为创建pod

1, 创建一个名为pod-nginx的pod

kubectl run nginx1 --image=nginx:1.15-alpine

2, 验证

kubectl get pods

6779129df934714840946882a93d9e85.png

kubectl describe pod nginx1

f3fd6c97d96874c71c4b88fbd4bd80c3.png

3.YAML创建pod

1, 准备yaml文件

vim pod1.yml

apiVersion: v1

kind: Pod

metadata:

name: memory-demo

spec:

containers:

- name: memory-demo-ctr

image: poLinux/stress

command: ["stress"]

args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"]

解释如下:

apiVersion: v1 # api版本

kind: Pod # 资源类型为Pod

metadata:

name: memory-demo # 自定义pod的名称

spec:

containers: # 定义pod里包含的容器

- name: memory-demo-ctr # 自定义pod中的容器名

image: poLinux/stress # 启动容器的镜像名

command: ["stress"] # 自定义启动容器时要执行的命令 (类似dockerfile里的CMD)

args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"] # 自定义启动容器执行命令的参数

# poLinux/stress这个镜像用于压力测试,在启动容器时传命令与参数就是

相当于分配容器运行时需要的压力

2, 通过yaml文件创建pod

kubectl apply -f pod1.yml

查看pod信息

查看pod信息

kubectl get pod

f7ba72416f955f2d4a8124edc92f94a3.png

查看pod详细信息

kubectl get pod -o wide

caca499233609f887481ee854d344a68.png

描述pod详细信息

kubectl describe pod memory-demo

7941e341a3814b12860b5854bc623272.png

删除pod

单个pod删除

方法1:

kubectl delete pod memory-demo

方法2:

kubectl delete -f pod1.yml

多个pod删除

方法1: 后接多个pod名

kubectl delete pod pod名1 pod名2 pod名3

方法2: 通过awk截取要删除的pod名称,然后管道给xargs

kubectl get pods |awk 'NR>1 {print $1}' |xargs kubectl delete pod

方法3: 如果要删除的pod都在同一个非default的命名空间,则可直接删除 命名空间

kubectl delete ns xxxx

镜像拉取策略

由imagePullPolicy参数控制

Always : 不管本地有没有镜像,都要从仓库中下载镜像

Never : 从来不从仓库下载镜像, 只用本地镜像,本地没有就算了

IfNotPresent: 如果本地存在就直接使用, 不存在才从仓库下载

默认的策略是:

当镜像标签版本是latest,默认策略就是Always

如果指定特定版本默认拉取策略就是IfNotPresent。

1.将上面的pod删除再创建,使用下面命令查看信息

kubectl delete -f pod1.yml

kubectl apply -f pod1.yml

kubectl describe pod memory-demo

963b91ab3b311a35b3826c304f0d7025.png

说明: 可以看到第二行信息还是pulling image下载镜像

2. 修改YAML

vim pod1.yml

apiVersion: v1

kind: Pod

metadata:

name: memory-demo

spec:

containers:

- name: memory-demo-ctr

image: poLinux/stress

command: ["stress"]

args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"]

imagePullPolicy: IfNotPresent # 增

加了这一句

3.再次删除再创建

kubectl delete -f pod1.yml

kubectl apply -f pod1.yml

kubectl describe pod pod-stress

430b7e71d1bcac2dfdea80ff019f2596.png

说明: 第二行信息是说镜像已经存在,直接使用了

pod的标签

为pod设置label,用于控制器通过label与pod关联

语法与前面学的node标签几乎一致

通过命令管理标签

1. 查看pod的标签

kubectl get pods --show-labels

2. 打标签,再查看

kubectl label pod memory-demo region=huanai zone=A env=test bussiness=game

kubectl get pods --show-labels

bb34e3c6f63ffa665d2516c044f2a715.png

3. 通过等值关系标签查询

kubectl get pods -l zone=A

fea69e63701e5e795a1b8ef5a8496e15.png

4. 通过集合关系标签查询

kubectl get pods -l "zone in (A,B,C)"

38993d803b4f33fae9ea3866f2b8538c.png

5. 删除标签后再验证

kubectl label pod memory-demo region- zone- env- bussiness-

kubectl get pods --show-labels

c6cce9d362e6d211ba9629c8218bb8de.png

小结:

pod的label与node的label操作方式几乎相同 node的label用于pod调度到指定label的node节点 pod的label用于controller关联控制的pod

通过YAML创建标签

1.修改 yaml

vim pod1.yml

apiVersion: v1

kind: Pod

metadata:

name: memory-demo

namespace: default

labels:

env: dev

app: nginx # 直接在原来的yaml里加上多个标签 spec:

spec:

containers:

- name: memory-demo-ctr

image: poLinux/stress

command: ["stress"]

args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"]

imagePullPolicy: IfNotPresent

2, 直接apply应用

kubectl apply -f pod1.yaml

3, 验证

kubectl get pods --show-labels

d74e34a37a8d9ad9cdd010c91e14b304.png

pod资源限制

参考: https://kubernetes.io/zh/docs/tasks/configure-pod-container/ass ign-memory-resource/

1.准备2个不同限制方式的创建pod

vim pod2.yml

apiVersion: v1

kind: Namespace

metadata:

name: ns1

---

apiVersion: v1

kind: Pod

metadata:

name: pod2

namespace: ns1

spec:

containers:

- name: memory-demo-ctr

image: poLinux/stress

imagePullPolicy: IfNotPresent

resources:

limits:

memory: "200Mi"

requests:

memory: "100Mi"

command: ["stress"]

args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"]

329eee06c198012f1f62a7d377f4a726.png

vim pod3.yml

apiVersion: v1

kind: Namespace

metadata:

name: ns1

---

apiVersion: v1

kind: Pod

metadata:

name: pod3

namespace: ns1

spec:

containers:

- name: memory-demo-ctr

image: poLinux/stress

imagePullPolicy: IfNotPresent

resources:

limits:

memory: "200Mi"

requests:

memory: "100Mi"

command: ["stress"]

args: ["--vm", "1", "--vm-bytes", "250M", "--vm-hang", "1"]

kubectl apply -f pod2.yml

kubectl apply -f pod3.yml

kubectl describe pod pod3 -n ns1

查看会发现pod-stress3这个pod状态变为OOMKilled,因为它是内存不足所 以显示Container被杀死

5e21b70c37ac7330682733b0aeb630c3.png

说明:

一旦pod中的容器挂了,容器会有重启策略,如下

Always:表示容器挂了总是重启,这是默认策略

OnFailures:表容器状态为错误时才重启,也就是容器正常终止时才重

Never:表示容器挂了不予重启

对于Always这种策略,容器只要挂了,就会立即重启,这样是很耗费 资源的。所以Always重启策略是这么做的:第一次容器挂了立即重 启,如果再挂了就要延时10s重启,第三次挂了就等20s重启...... 依次 类推

测试完后删除

kubectl delete ns ns1

pod包含多个容器

1.准备yml文件

vim pod4.yml

kind: Pod

metadata:

name: pod4

namespace: ns1

spec:

containers:

- name: c1

image: poLinux/stress

imagePullPolicy: IfNotPresent

resources:

limits:

memory: "200Mi"

requests:

memory: "100Mi"

command: ["stress"]

args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"]

- name: c2

image: poLinux/stress

imagePullPolicy: IfNotPresent

resources:

limits:

memory: "200Mi"

requests:

memory: "100Mi"

command: ["stress"]

args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"]

2.应用yml文件创建pod

kubectl apply -f pod4.yml

3. 查看pod在哪个节点

kubectl get pods -o wide -n ns1

4c7ee4db237307ef8a17b260dbc20caf.png

可以看到有2个容器,运行在192.168.5.11(node2)节点

4,在node2上验证,确实产生了2个容器

docker ps -a |grep stress

52a6c399831488df570f3e4ac2691b23.png

对pod里的容器进行操作

命令帮助

kubectl exec -h

58aaa837a52870cdeca99d3157cfd8bd.png

不用交互直接执行命令

格式为: kubectl exec pod名 -c 容器名 -- 命令

注意:

-c 容器名为可选项,如果是1个pod中1个容器,则不用指定;

如果是1个pod中多个容器,不指定默认为第1个。

kubectl exec pod4 -c c2 -n ns1 -- touch /111

kubectl exec pod4 -c c2 -n ns1-- ls /111

917129cdbcfb7f7624e58260fcf0e080.png

不指定容器名,则默认为pod里的第1个容器

kubectl exec pod4 -n ns1 -- touch /222

f80b3ec3ca22327071df81506b509355.png

kubectl exec pod4 -c c1 -n ns1 -- ls /222

efcc6c04507fb49e72133feff537fe7c.png

和容器交互操作

和docker exec几乎一样

kubectl exec -it pod4 -c c1 -- /bin/bash

cd5e8ad71dc7a81dc492236dfc8dfd22.png

验证pod中多个容器网络共享

1, 编写YAML

vim pod-nginx.yaml

apiVersion: v1

kind: Pod

metadata:

name: nginx

spec:

containers:

- name: c1

image: nginx:1.15-alpine

- name: c2

image: nginx:1.15-alpine

2. 应用YAML

kubectl apply -f pod-nginx.yaml

3.查看pod信息与状态

kubectl get pods |grep nginx

565d68e678126da87ab71ce72894ac6e.png

kubectl describe pod nginx

有一个启不来,因为一个容器中两个pod是共用网络的,所以不能两个都占用 80端口

139bbfe8e69f439f9145cfb2c6678bb4.png

通过查找192.168.5.11(node2)上面的容器,然后docker logs查 看,得到如下的报错,说明是端口被占用

kubectl describe pod nginx #查看

2aed5e277304bda9674d139461d87f79.png

[[email protected] ~]# docker ps -a

3f3a8d210a2bb78aafd8f0c051569aff.png

docker logs -f -t --tail 100 e188eded7a01 #查看容器日志

7f86726345d967ce244943b71f1ac74c.png

四、pod调度

kubernetes会通过算法将pod调度到node节点上运行

pod调度流程

e5570083212b0564d13f9ef7372c9e2d.png

调度约束方法

我们为了实现容器主机资源平衡使用, 可以使用约束把pod调度到指定的 node节点

nodeName 用于将pod调度到指定的node名称上

nodeSelector 用于将pod调度到匹配Label的node上

案例1: nodeName

1. 编写YAML文件

vim pod-nodename.yml

apiVersion: v1

kind: Pod

metadata:

name: pod-nodename

spec:

nodeName: 192.168.5.10

containers:

- name: nginx

image: nginx:1.15-alpine

2.应用YAML文件创建pod

kubectl apply -f pod-nodename.yml

3. 验证

kubectl describe pod pod-nodename |tail -6

倒数第3行没有使用scheduler,而是直接给node1了,说明nodeName约束生效

1e02f7005a38b71d6f1a5cf8fc7bf621.png

案例2: nodeSelector

1.为192.168.5.11(node2)打标签

kubectl label nodes 192.168.5.11 bussiness=game

2. 编写YAML文件

vim pod-nodeselector.yml

apiVersion: v1

kind: Pod

metadata:

name: pod-nodeselect

spec:

nodeSelector:

bussiness: game

containers:

- name: nginx

image: nginx:1.15-alpine

3.应用YAML文件创建pod

kubectl apply -f pod-nodeselector.yml

4.验证

kubectl describe pod pod-nodeselect |tail -6

485a8b467049ca449b697fe6aa3b712e.png

仍然经过了scheduler,但确实分配到了node2(192.168.5.11)上

有兴趣可以再删除后再创建,重复几次验证

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐