1. Podskubernetes集群中最小的管理单元,Pod封装了应用程序的容器(或者,在某些情况下,多个容器),存储资源,唯一的网络IP以及管理容器应该如何运行的选项。<br />Kubernetes集群中的Pod可以以两种主要方式使用:<br />运行单个容器的Pod:“one-container-per-Pod”模型是最常见的Kubernetes用例; 在这种情况下,您可以将Pod视为单个容器的包装,而Kubernetes直接管理Pod而不是容器。<br /> 运行多个需要协同工作的容器的PodPod可以封装由多个容器组成的应用程序,这些容器紧密耦合并需要共享资源。<br />如何管理多个容器?<br />网络:每个Pod都会分配唯一的IP地址。Pod中的每个容器都共享网络命名空间,包括IP地址和网络端口。Pod内的容器可以使用相互通信localhost。当Pod中的容器与Pod 外部的实体通信时,必须协调它们如何使用共享网络资源(例如端口)。<br />存储:Pod可以指定一组共享存储卷 Pod中的所有容器都可以访问共享卷,从而允许这些容器共享数据。如果需要重新启动其中一个容器,则卷还允许Pod中的持久数据存活。<br /> pause容器:<br />每启动一个pod,同时也会启动一个伴随容器(pause容器),pause伴随着pod的启动而启动,pod的删除而删除。通过pause容器实现pod内的容器共享网络空间。<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/116294/1585038874031-e0211f37-c87e-4265-9867-69cb6de78da7.png#height=147&id=ZCWH6&name=image.png&originHeight=228&originWidth=347&originalType=binary&ratio=1&size=33220&status=done&style=none&width=223)** **![image.png](https://cdn.nlark.com/yuque/0/2020/png/116294/1585038881015-f337ff3a-7261-40e6-9010-cb9a0c6649d1.png#height=131&id=UM1rh&name=image.png&originHeight=176&originWidth=279&originalType=binary&ratio=1&size=68996&status=done&style=none&width=207)

生命周期
07-Pods - 图1
07-Pods - 图2

Pods调度流程

image.png

用户提交Create Pod的请求;
API Server讲请求的信息写入到etcd,此时写入etcd的信息并没有Nodename;
API Server与Scheduler通过watch机制监控到有新的Pod请求,根据请求的资源进行调度,调度成功后进行bind pod的操作,返回给API Server将分配的Nodename写入etcd中
API Server与kubelet通过watch机制监控到有新的bound Pod信息,调用Docker API执行docker run的操作

Sidecar—init container

image.png

Pod 能够具有多个容器,应用运行在容器里面,但是它也可能有一个或多个先于应用容器启动的Init 容器。Init容器是一种专用的容器,在应用程序容器启动之前运行,一般包括一些应用镜像中不存在的实用工具和安装脚本。Init 容器与普通的容器非常类似,除了如下点:
Init 容器总是运行到成功完成为止。
如果 Pod 的 Init 容器失败,Kubernetes 会不断地重启该 Pod,直到 Init 容器成功为止。然而,如果 Pod 对应的 restartPolicy 为 Never,它不会重新启动。
如果为一个 Pod 指定了多个 Init 容器,那些容器会按顺序一次运行一个。 每个 Init 容器必须运行成功,下一个才能够运行。 当所有的 Init 容器运行完成时,Kubernetes 初始化 Pod 并像平常一样运行应用容器。
应用场景:
进行应用的初始化,如,从git或svn拉取应用的最新配置或动态生成配置文件。
进行应用的依赖检查,如一些web服务,必须要数据库服务先启动,然后在去启动web服务,否则会启动失败,此时在web应用pod内定义一个init容器,通过init容器去对数据库容器进行检测,一旦检测到数据库容器启动成功,就启动web应用pod。

Static Pod
Static Pods由特定节点上的kubelet守护进程直接管理,而不需要API Server进行管理。
kubelet监视每个静态Pod(如果它崩溃,则重新启动它)Static Pods总是绑定到特定节点上的一个Kubelet。
Kubelet自动尝试在Kubernetes API Server上为每个静态Pod创建一个镜像Pod。
这意味着运行在节点上的pod在API Server上是可见的,但不能从那里进行控制。
RKE部署kubernetes集群的Static Pod的存放路径默认为:/etc/kubernetes/manifests/

1 pod简略信息
NAME: Pod名字
READY: Pod 是否为READY
STATUS: Pod状态
RESTARTS:容器的重启次数
AGE:生命周期

  1. cat << EOF > nginx-pod.yaml
  2. apiVersion: v1
  3. kind: Pod
  4. metadata:
  5. name: nginx
  6. labels:
  7. app: nginx
  8. spec:
  9. containers:
  10. - name: nginx
  11. image: nginx:latest
  12. ports:
  13. - containerPort: 80
  14. EOF

2 pods的生命周期

Pending 已创建pod、1个或多个容器的镜像没有创建和下载镜像的过程
Running pod内全部容器都已创建且至少有1个容器已经处于运行的状态、启动的状态或正在重启的状态
Succeeded pod内的容器成功运行后退出且不会再重启
Failed pod内的所有容器已退出且至少有一个容器退出为失败运行的状态
Unknown 无法获取到pod的状态

3 pod 重启策略(RestartPolicy) 默认值:Always

Always 容器启动失败时由kubelet自动重启此容器
OnFailure 当容器停止运行且退出码不为0时由kubelet自动重启此容器
Never 不管容器运行状态如何、kubelet都不会重启此容器

kubelet重启容器时间间隔以乘以2n计算 如:1 2 4 8
最长延迟5分钟且成功重启后10分钟后重置该时间
**资源对象镜像的下载策略
 Always:每次都下载镜像(*默认)
 Never:只使用本地镜像,从不下载
 IfNotPresent:只有当本地没有的时候才下载镜像

  1. cat << EOF > imagePullPolicy.yaml
  2. apiVersion: v1
  3. kind: Pod
  4. metadata:
  5. name: imagePullPolicy
  6. spec:
  7. containers:
  8. - name: nginx
  9. image: nginx:1.7.9
  10. imagePullPolicy: IfNotPresent
  11. EOF
  1. [rancher@rmaster01 ~]$ kubectl run app --image=nginx --dry-run=client -o yaml
  2. apiVersion: v1
  3. kind: Pod
  4. metadata:
  5. creationTimestamp: null
  6. labels:
  7. run: app
  8. name: app
  9. spec:
  10. containers:
  11. - image: nginx
  12. name: app
  13. resources: {}
  14. dnsPolicy: ClusterFirst
  15. restartPolicy: Always
  16. status: {}
  17. [rancher@rmaster01 ~]$

[liwm@rmaster01 ~]$ kubectl create -f imagepullpolicy.yaml
pod/imagepullpolicy created
[liwm@rmaster01 ~]$ kubectl get pod imagepullpolicy -o yaml |grep imagePull
imagePullPolicy: IfNotPresent
[liwm@rmaster01 ~]$ vim imagepullpolicy.yaml
[liwm@rmaster01 ~]$ kubectl delete pod imagepullpolicy
pod “imagepullpolicy” deleted
[liwm@rmaster01 ~]$ kubectl create -f imagepullpolicy.yaml
pod/imagepullpolicy created
[liwm@rmaster01 ~]$ kubectl get pod imagepullpolicy -o yaml |grep imagePull
imagePullPolicy: IfNotPresent
[liwm@rmaster01 ~]$ cat imagepullpolicy.yaml
apiVersion: v1
kind: Pod
metadata:
name: imagepullpolicy
spec:
containers:
- name: nginx
image: nginx:1.7.9
#imagePullPolicy: Always
#imagePullPolicy: IfNotPresent
[liwm@rmaster01 ~]$

4 初始化容器 initContainers
启动nginx之前 busybox使用wget创建一个访问主页

  1. cat << EOF > nginx-install.yaml
  2. apiVersion: v1
  3. kind: Pod
  4. metadata:
  5. name: nginx
  6. annotations:
  7. spec:
  8. initContainers:
  9. - name: install
  10. image: busybox
  11. command:
  12. - wget
  13. - "-O"
  14. - "/work-dir/index.html"
  15. - http://kubernetes.io
  16. volumeMounts:
  17. - name: workdir
  18. mountPath: "/work-dir"
  19. containers:
  20. - name: nginx
  21. image: nginx
  22. ports:
  23. - containerPort: 80
  24. volumeMounts:
  25. - name: workdir
  26. mountPath: /usr/share/nginx/html
  27. dnsPolicy: Default
  28. volumes:
  29. - name: workdir
  30. emptyDir: {}
  31. EOF

[liwm@rmaster01 ~]$ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx 1/1 Running 0 3m23s 10.42.4.125 node01
[liwm@rmaster01 ~]$ curl 10.42.4.125

  1. cat << EOF > initcontainers.yaml
  2. apiVersion: v1
  3. kind: Pod
  4. metadata:
  5. name: init-test
  6. labels:
  7. app: myapp
  8. spec:
  9. containers:
  10. - name: container
  11. image: busybox:1.28
  12. command: ['sh', '-c', 'echo The app is running! && sleep 3600']
  13. initContainers:
  14. - name: init-test
  15. image: busybox:1.28
  16. command: ['sh', '-c', 'echo init containers test && sleep 10']
  17. EOF

5 pod容器共享Volume

  1. cat << EOF > volume-pod.yaml
  2. apiVersion: v1
  3. kind: Pod
  4. metadata:
  5. name: volume-pod
  6. spec:
  7. containers:
  8. - name: tomcat
  9. image: tomcat
  10. ports:
  11. - containerPort: 8080
  12. volumeMounts:
  13. - name: app-logs
  14. mountPath: /usr/local/tomcat/logs
  15. - name: busybox
  16. image: busybox
  17. command: ["sh", "-c", "tail -f /logs/catalina*.log"]
  18. volumeMounts:
  19. - name: app-logs
  20. mountPath: /logs
  21. volumes:
  22. - name: app-logs
  23. emptyDir: {}
  24. EOF

[liwm@rmaster01 ~]$ kubectl get pod
NAME READY STATUS RESTARTS AGE
volume-pod 2/2 Running 0 3m38s

查看tomcat的日志
[liwm@rmaster01 ~]$ kubectl exec -it volume-pod -c tomcat — ls /usr/local/tomcat/logs
catalina.2020-03-21.log localhost_access_log.2020-03-21.txt
host-manager.2020-03-21.log manager.2020-03-21.log
localhost.2020-03-21.log
[liwm@rmaster01 ~]$ kubectl exec -it volume-pod -c tomcat — ls /usr/local/tomcat/logs/catalina.2020-03-21.log
/usr/local/tomcat/logs/catalina.2020-03-21.log
[liwm@rmaster01 ~]$ kubectl exec -it volume-pod -c tomcat — tail /usr/local/tomcat/logs/catalina.2020-03-21.log
21-Mar-2020 13:01:47.293 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true].

[liwm@rmaster01 liwm]$ kubectl exec -it volume-pod -c busybox — tail /logs/catalina.2020-03-22.log

使用busybox查看tomcat的日志
[liwm@rmaster01 ~]$ kubectl logs volume-pod busybox

6 一个pod里可以有多个容器

  1. cat << EOF > memory-demo.yaml
  2. apiVersion: v1
  3. kind: Pod
  4. metadata:
  5. name: memory-demo
  6. spec:
  7. containers:
  8. - name: demo1
  9. image: polinux/stress
  10. imagePullPolicy: IfNotPresent
  11. command: ["stress"]
  12. args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"]
  13. - name: demo2
  14. image: polinux/stress
  15. imagePullPolicy: IfNotPresent
  16. #command: ["stress"]
  17. args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"]
  18. EOF

pod封装多个容器
[liwm@rmaster01 yaml]$ kubectl exec -it -c demo1 memory-demo bash

[liwm@rmaster01 yaml]$ kubectl get pod
NAME READY STATUS RESTARTS AGE
memory-demo 1/2 CrashLoopBackOff 5 4m1s
[liwm@rmaster01 yaml]$ kubectl exec -it -c demo1 memory-demo — ls /
bin etc lib mnt proc run srv tmp var
dev home media opt root sbin sys usr
[liwm@rmaster01 yaml]$

7 apply、edit与patch的使用

执行yaml
kubectl apply -f pod.yaml

查看pod的label
kubectl get pod —show-labels

apply更新本地的yaml,通过apply更新配置
kubectl apply -f pod.yaml

edit
kubectl edit pod memory-demo

patch
kubectl get pod memory-demo -o json
kubectl patch pod memory-demo -p ‘{“metadata”: {“labels”: {“app”: “damon”}}}’

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: nginx
  5. annotations: #描述信息,但和lable不同于它不能用于节点选择器,只作为元数据展示,使用kubectl describe时可以看到
  6. linuxe.cn/created-by: "cluster admin"
  7. namespace: web
  8. labels:
  9. app: nginx
  10. version: 1.7.9
  11. spec:
  12. containers: #定义容器
  13. - name: nginx #pod的名称,可以定义多个
  14. image: nginx:1.7.9 #使用仓库的哪个镜像
  15. imagePullPolicy: IfNotPresent #该字段不写的话默认为IfNotPresent,代表镜像不存在才会拉取,Always代表总会拉取。如果镜像使用latest也会去拉取
  16. volumeMounts: #引用共享存储
  17. - name: storage #共享存储名
  18. mountPath: /tmp/storage #共享存储在容器中的路径
  19. ports: #需要容器暴露的端口
  20. - name: http
  21. containerPort: 80 #需要暴露的容器端口,会随机在宿主机中生成一个端口作为映射
  22. protocol: TCP
  23. resources: # 容器资源限制,这里的值会决定服务质量QOS的类型
  24. requests: # 容器请求的资源大小
  25. cpu: 0.5 # 0.5代表500M
  26. memory: 500M
  27. limits: #容器最大能分配的资源,实际资源是在请求的资源和最大资源之间波动
  28. cpu: 1
  29. memory: 1000M
  30. volumes:
  31. - name: storage #定义存储名,上面有调用
  32. emptyDir: {} #数据共享策略,EmptyDir是同Pod中所有容器数据共享,Pod删除后数据也会删除;HostPath是把数据存放在宿主机中共享,删除Pod数据还在;NFS则是网络存储
  33. command: ["nginx"] #nginx镜像运行后所执行的命令,如果没写的话则是镜像默认命令
  34. args: ["-s","reload"] #command命令接收的参数
  35. #nodeSelector: #节点选择器,pod会创建在符合条件的node上,还有一种nodeName可以直接指定某个节点去创建pod而不需要条件。
  36. restartPolicy: #容器停止运行时的重启策略,默认Always=容器一停就进行重启,不管是不是真的需要;OnFailure=容器错误退出就重启;Never=不重启
  37. OnFailure