- 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/
1.无控制器管理的自主式pod 没有副本控制器控制,删除自主式pod后不会从新建立
2.控制器管理的pod 控制器能够控制pod的副本数,扩容与裁剪,版本更新与回滚等node
pod是一种资源,能够经过kubectl get pod来查看
kubectl get pod # pod或pods均可以, 不指定namespace,默认是名为default的namespace
kubectl get pod -n kube-systemlinux
先看一个yaml格式的pod定义文件解释nginx
# 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
kubectl explain namespace #查找namespace
kubectl explain pod #查找pod
kubectl explain pod.spec #查找pod.spec
kubectl explain pod.spec.containers #pod.spec.containers算法
命令建立pod(v1.18变化)
k8s以前版本中, kubectl run命令用于建立deployment控制器 在v1.18版本中, kubectl run命令改成建立poddocker
kubectl run nginx1 --image=nginx:1.15-alpinevim
kubectl get podsapi
kubectl describe pod nginx1bash
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"]
解释以下: app
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
kubectl get pod
kubectl get pod -o wide
kubectl describe pod memory-demo
方法1:
kubectl delete pod memory-demo
方法2:
kubectl delete -f pod1.yml
方法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。
kubectl delete -f pod1.yml
kubectl apply -f pod1.yml
kubectl describe pod memory-demo
说明: 能够看到第二行信息仍是pulling image下载镜像
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 # 增 加了这一句
kubectl delete -f pod1.yml
kubectl apply -f pod1.yml
kubectl describe pod pod-stress
说明: 第二行信息是说镜像已经存在,直接使用了
为pod设置label,用于控制器经过label与pod关联
语法与前面学的node标签几乎一致
kubectl get pods --show-labels
kubectl label pod memory-demo region=huanai zone=A env=test bussiness=game
kubectl get pods --show-labels
kubectl get pods -l zone=A
kubectl get pods -l "zone in (A,B,C)"
kubectl label pod memory-demo region- zone- env- bussiness-
kubectl get pods --show-labels
pod的label与node的label操做方式几乎相同 node的label用于pod调度到指定label的node节点 pod的label用于controller关联控制的pod
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
kubectl apply -f pod1.yaml
kubectl get pods --show-labels
参考: https://kubernetes.io/zh/docs/tasks/configure-pod-container/ass ign-memory-resource/
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"]
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被杀死
一旦pod中的容器挂了,容器会有重启策略,以下
Always:表示容器挂了老是重启,这是默认策略
OnFailures:表容器状态为错误时才重启,也就是容器正常终止时才重
启
Never:表示容器挂了不予重启
对于Always这种策略,容器只要挂了,就会当即重启,这样是很耗费 资源的。因此Always重启策略是这么作的:第一次容器挂了当即重 启,若是再挂了就要延时10s重启,第三次挂了就等20s重启...... 依次 类推
测试完后删除kubectl delete ns ns1
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"]
kubectl apply -f pod4.yml
kubectl get pods -o wide -n ns1
能够看到有2个容器,运行在192.168.5.11(node2)节点
4,在node2上验证,确实产生了2个容器
docker ps -a |grep stress
命令帮助
kubectl exec -h
不用交互直接执行命令
格式为: 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
不指定容器名,则默认为pod里的第1个容器
kubectl exec pod4 -n ns1 -- touch /222
kubectl exec pod4 -c c1 -n ns1 -- ls /222
和docker exec几乎同样
kubectl exec -it pod4 -c c1 -- /bin/bash
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
kubectl apply -f pod-nginx.yaml
kubectl get pods |grep nginx
kubectl describe pod nginx
有一个启不来,由于一个容器中两个pod是共用网络的,因此不能两个都占用 80端口
经过查找192.168.5.11(node2)上面的容器,而后docker logs查 看,获得以下的报错,说明是端口被占用
kubectl describe pod nginx #查看
[root@node2 ~]# docker ps -a
docker logs -f -t --tail 100 e188eded7a01 #查看容器日志
kubernetes会经过算法将pod调度到node节点上运行
pod调度流程
咱们为了实现容器主机资源平衡使用, 可使用约束把pod调度到指定的 node节点
nodeName 用于将pod调度到指定的node名称上
nodeSelector 用于将pod调度到匹配Label的node上
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
kubectl apply -f pod-nodename.yml
kubectl describe pod pod-nodename |tail -6
倒数第3行没有使用scheduler,而是直接给node1了,说明nodeName约束生效
kubectl label nodes 192.168.5.11 bussiness=game
vim pod-nodeselector.yml
apiVersion: v1 kind: Pod metadata: name: pod-nodeselect spec: nodeSelector: bussiness: game containers: - name: nginx image: nginx:1.15-alpine
kubectl apply -f pod-nodeselector.yml
kubectl describe pod pod-nodeselect |tail -6
仍然通过了scheduler,但确实分配到了node2(192.168.5.11)上有兴趣能够再删除后再建立,重复几回验证