2、pod详解

一、pod基本介绍

pod是一组容器,一组容器可以是多个容器也可以是单个容器(不包括系统内置的容器),当一个pod包含多个容器时,多个容器运行在同一个工作节点上,一个pod中的多个容器绝不会跨多个节点。

1、pod的名称空间

pod中可以包含多个容器或单个容器,pod中包含多个容器时,多个容器是共享命名空间的,pod中多个容器可以进行进程通信,可以共享网络空间。但pod中每个容器的文件系统是相互隔离的,不过可以通过Volume进行文件系统共享。

2、pod的网络空间

pod中的容器共享网络命名空间,因此pod中容器共享相同的IP和端口,这就要求pod中的容器不能绑定到相同的端口,否则会导致端口冲突,对于不同的pod不会导致端口冲突。共享网络命名空间允许pod中的容器可以通过localhost进行通信。
k8s集群中pod共享网络地址地址空间,允许一个pod通过另一个pod的IP地址进行访问。

3、pod优点

  1. 有利于进程隔离
    每个pod中运行一个容器,每个容器中只运行一个进程,当一个进程崩溃后不会影响到其它进程的执行。如果是以前的胖系统中,所有的应用都部署在一起,当其中的一个应用进程崩溃后导致整个系统崩溃,现在每个应用部署在一个pod的容器中,当一个应用崩溃后不会导致其它的pod中的应用崩溃。

  2. 有利于横向扩缩pod
    像以前胖系统中,所有应用部署在一起,当修改其中的一个应用后就要对整个系统进行变更,有个pod后,每个应用部署在不同的pod中,当一个应用变更时,只需要修改相应pod的应用就可以,减小了整个系统的风险。另外对于胖系统,如果某个应用访问量大,如果要扩容就要对整个系统就行扩容,导致资源浪费,有了pod后,只需要对访问量大的pod进行横向扩展pod就可以了,减少了资源的浪费。

二、pod基本操作

1、创建pod

以nginx为例,通过yaml创建运行nginx的pod,下面建立niginx的yaml文件
pod_nginx.yaml

apiVersion: v1				#k8s的版本
kind: Pod 					#资源类型
metadata:  					#描述信息
  name: nginxpod  			#pod的名称
spec:   					#pod的说明信息
  containers: 				#定义pod中运行的容器
 - image: nginx 			#运行容器的镜像
    name: nginxcontainer	#pod中运行的容器的名字	
    ports: 					#定义容器暴露的端口
    - containerPort: 80 	#容器端口
      protocol: TCP  		#端口协议

创建完pod的yaml描述信息后,下面通过yaml描述的pod

 kubectl create -f pod_nginx.yaml

在这里插入图片描述
表示创建pod成功。

2、查询pod

  • 查看创建的pod
kubectl get pod

在这里插入图片描述

  • 查看pod的节点等详细信息
 kubectl get pod -o wide

在这里插入图片描述

  • 获取pod的yaml完整描述
 kubectl get pod -o yaml
  • 查看pod日志
    如果pod中只有一个容器,可以直接获取pod的日志
 kubectl logs nginxpod

如果pod中有多个容器,可以用-c指定查看哪个容器中日志

kubectl logs nginxpod -c nginxcontainer

3、pod标签

k8s集群中有大规模的pod,通过pod的标签可以有效的获取、筛选、组织pod,pod标签在pod创建时进行添加。

  • 创建带标签的pod
 apiVersion: v1
kind: Pod
metadata:
  name: nginxpod
  labels:
    app: nginx 		#pod的标签为app和sit,可以添加一个或多个标签
    env: sit
spec:
  containers:
 - image: nginx
    name: nginxcontainer
    ports:
    - containerPort: 80
      protocol: TCP
  • 查询带标签的pod
    –show-labels表示查询显示pod时,带上标签信息
 kubectl get pod --show-labels

查询pod时,按指定的app,env标签显示pod信息。

kubectl get pod -L app,env
  • 修改标签
    创建pod时未添加标签的,可以手动添加标签
kubectl label pod nginxpod2 app=nginxpod2

创建pod时带标签,后期想修改覆盖原标签

kubectl label pod nginxpod env=debug --overwrite

4、标签选择器

  • 筛选出app=nginx的标签的pod
 kubectl get pod -l app=nginx
  • 筛选出所有含有app标签的pod
kubectl get pod -l app
  • 筛选出不含有app标签的pod
 kubectl get pod -l '!app'  #注意添加引号
  • 筛选出标签为app,但值不为nginx的pod
kubectl get pod -l app!=nginx
  • 筛选出标签app等于nginx或者js的pod
kubectl get pod -l 'app in (nginx,js)'
  • 筛选出标签app不等于nginx和js的pod
kubectl get pod -l 'app notin (nginx,js)'
  • pod调度到指定标签的节点上
 apiVersion: v1
kind: Pod
metadata:
  name: nginxpod
  labels:
    app: nginx
    env: sit
spec:
  nodeSelector: #pod调度到含有标签nas=true的节点上
    nas: "true"
  containers:
 - image: nginx
    name: nginxcontainer
    ports:
    - containerPort: 80
      protocol: TCP

5、对pod添加注解

pod中注解起到注释信息的作用,就想java程序中的注释信息一样。
下面为创建的pod添加注解信息

kubectl annotate pod nginxpod pod/author="lzj default"

为nginxpod添加了注解信息pod/author=“lzj default”,添加注解信息后,可以通过kubectl describe pod nginxpod 查看添加的注解信息。添加注解信息时也可以在yaml中配置。

6、删除pod

  • 按名称删除pod
kubectl delete pod mypod  #按pod名称删除pod
  • 按标签选择器删除pod
 kubectl delete pod -l app=nginx #删除标签为nginx的pod
  • 删除名称空间中所有pod
kubectl delete namespace myspace  #删除myspace名称空间中所有的pod	
kubectl delete pod --all #删除默认名称空间中所有的pod
  • 删除所有资源
kubectl delete all --all

三、pod生命周期

在这里插入图片描述
一般pod中运行一个应用容器,但除了主应用容器外还有其他容器,当一个pod被创建后,首先启动的是pause容器,也是每个pod都会默认创建的容器,用于初始pod中网络;其次pod也可以有一个或多个init初始化容器,也可没有,主要负责应用启动前的初始化工作,注意一点,不管有几个init容器,一定是一个init容器停止后,另一个init容器才会创建;等init容器创建并停止后,主应用容器被创建,主应用容器也可以由start和stop操作;最后主应用容器被创建后,也可以为应用容器添加探针容器,主要用于pod中主应用容器的健康检查。

四、Init容器

pod中可以有一个或多个先于主应用容器的Init容器,每一个Init容器都必须成功结束后才会启动下一个Init容器或者主应用容器。如果Init容器启动失败,k8s会不断的重启pod,如果restartPolicy为Never,则k8s不会重新启动pod。
Init应用场景:

  • 为应用安装的工具;
  • 应用之前的初始化工作;
  • 可以访问系统的Secret权限;
  • 提供了一种简单的阻塞或延迟应用容器启动的方法。

下面通过一个示例演示Init容器的用法,以pod_init.yaml为例:

metadata:
  name: mypod
  labels:
    app: pod
    env: sit
spec:
  containers:
  - image: busybox
    imagePullPolicy: IfNotPresent
    name: main-container
    command: ['sh', '-c', 'echo main-container is successfully > /root/test.txt && sleep 3600']
  initContainers:
  - name: init-container
    image: busybox
    imagePullPolicy: IfNotPresent
    command: ['sh', '-c', 'sleep 30']

首先在创建main-container主应用服务器之前创建了init-container初始化容器,镜像都为busybox,Init服务器创建后休眠30s,然后退出,Init容器成功退出后,main-container主应用容器才开始创建,主应用容器创建后,把日志写入/root/test.txt文件中,并休眠1小时。下面通过kubectl create -f pod_init.yaml创建pod,然后查看init容器和主容器运行情况

在这里插入图片描述
注意

  1. Pod启动过程中,Init容器必须在pause容器启动后启动;
  2. Init容器如果启动失败,会根据pod的restartPolicy策略进行重启;
  3. Init容器没有成功之前,Pod不会变成ready状态,Init的端口也不会在service进行聚集;
  4. 如果pod重启,所有的Init容器都必须重启;
  5. 修改Init容器的镜像就会导致pod重启。

五、探针

有时候pod中容器进程没有崩溃,但容器中运行的程序崩溃,不会导致k8s重启pod,因此就不方便知道应用是否正常。通过探针对容器定期进行诊断,可实时了解容器内部运行情况,探针是由kubelet对容器进行的定期诊断。kubelet可以通过如下三种方式对对容器进行诊断:

  • ExecAction: 在容器内执行命令,如果命令退出时返回码为0则认为诊断成功;
  • TCPSocketAction: 对指定端口上的容器IP进行TCP检查,如果端口打开,则诊断成功;
  • HTTPGetAction: 对指定的端口和路径上的IP执行http get请求,如果响应状态码大于等于200且小于400,则诊断成功。

每次探测结果都是如下情况:

  • 成功:容器诊断成功;
  • 失败:容器诊断失败,根据重启策略决定pod重启;
  • 未知:不会采取任何行动

探针分两种形式:

  • livenessProbe: 指示容器是否正在运行。如果存活检测失败,则kubelet会杀死容器,并将pod根据重启策略进行重启,如果容器不提供存活探针,默认状态为success,pod不会重启。
  • readinessProbe: 指示容器是否准备好服务请求。如果ReadinessProbe探针检测到失败,则Pod的状态被修改。Endpoint Controller将从Service的Endpoint中删除包含该容器所在Pod的Endpoint。

两种探针用法相同,下面以livenessProbe探针为例

1、通过ExecAction形式进行诊断

创建yaml如下

apiVersion: v1
kind: Pod
metadata:
  name: live-exec-pod
  namespace: default
spec:
  containers:
  - name: live-exec-container
    image: busybox
    imagePullPolicy: IfNotPresent
    command: ["/bin/sh", "-c", "echo hello > /tmp/hello.txt; sleep 10; rm /tmp/hello.txt; sleep 3600"]
    livenessProbe:
      exec:
        command: ["test", "-e", "/tmp/hello.txt"]
      initialDelaySeconds: 1  #容器启动后1s后开始探测
      periodSeconds: 3		  #每隔3秒钟探测一次

上面yaml定义了,当live-exec-container启动后,会有一个livenessProbe探测器,从容器启动后1s后开始通过[“test”, “-e”, “/tmp/hello.txt”]命令探测容器,如果返回0,探测成功,如果返回非0,探测失败,pod重启

[root@k8s-master01 work]# kubectl create -f pod_live_exec.yaml 
pod/live-exec-pod created
[root@k8s-master01 work]# kubectl get pod -w
NAME            READY   STATUS    RESTARTS   AGE
live-exec-pod   1/1     Running   0          4s
live-exec-pod   1/1     Running   1          49s
live-exec-pod   1/1     Running   2          97s
live-exec-pod   1/1     Running   3          2m26s
..............

2、通过HTTPGetAction形式进行诊断

创建yaml如下

apiVersion: v1
kind: Pod
metadata:
  name: live-http-pod
  namespace: default
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
    livenessProbe:
      httpGet:
        port: 80
        path: /hello.html
      initialDelaySeconds: 0   	#nginx容器启动后开始执行探针
      periodSeconds: 5  		#探针每5秒钟探测一次
      timeoutSeconds: 20 		#20s后探针退出

创建nginx容器后,livenessProbe探针会对/hello.html路径和端口80进行http get请求,每5s进行探测一次,超时时间为20s。

[root@k8s-master01 work]# kubectl create -f pod_live_http.yaml 
pod/live-http-pod created
[root@k8s-master01 work]# kubectl get pod -w
NAME            READY   STATUS    RESTARTS   AGE
live-http-pod   1/1     Running   0          11s
live-http-pod   1/1     Running   1          15s
live-http-pod   1/1     Running   2          30s
live-http-pod   1/1     Running   3          45s
live-http-pod   0/1     CrashLoopBackOff   3          59s

3、通过TCPSocketAction形式进行

创建yaml如下

apiVersion: v1
kind: Pod
metadata:
  name: live-sock-pod
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
    livenessProbe:
      initialDelaySeconds: 2
      timeoutSeconds: 1
      tcpSocket:
        port: 90

创建nginx容器后,探针会2s后对90端口进行探测,单次探测超时时间为1s,如果端口不通,会重启pod。

[root@k8s-master01 work]# kubectl create -f pod_live_sock.yaml
pod/live-sock-pod created
[root@k8s-master01 work]# kubectl get pod -w
NAME            READY   STATUS    RESTARTS   AGE
live-sock-pod   1/1     Running   0          8s
live-sock-pod   1/1     Running   1          27s
live-sock-pod   1/1     Running   2          57s

以上是livenessProbe的三种用法,readinessProbe用法完全相同。

六、主容器start/stop操作

pod中主容器启动启动后可以执行初始化内容,比如构建一些应用的环境变量等,或初始化数据库等;主容器结束前可以执行应用的清理工作、数据库清理工作等。可以通过postStart指定容器的初始化步骤,通过preStop指定容器的清理步骤。
创建yaml示例如下:

apiVersion: v1
kind: Pod
metadata:
  name: start-stop-pod
spec:
  containers:
 1. name: start-stop-container
    image: busybox
    imagePullPolicy: IfNotPresent
    command: ["/bin/sh", "-c", "sleep 20"]
    lifecycle:
      postStart: 	#执行初始化工作
        exec:
          command: ["/bin/sh", "-c", "echo start pod > /tmp/pod.txt"]
      preStop: 		#执行清理工作
        exec:
          command: ["/bin/sh", "-c", "rm -rf /tmp/pod.txt"]

七、pod生命周期状态

通过pod的状态可以得知pod运行情况,pod从创建到死亡全部的声明周期状态如下所示
1. Pending(挂起)
pod已被k8s管理,但pod中容器尚未全部创建,pod调度花费时间以及网络下载镜像事前全部在该状态下完成。
2. Running(运行中)
Pod中所有容器已被创建,Running状态不表示所有容器已经创建成功,可以表示容器已经正常启动成功,也可以表示容器正处于启动或重启过程中。

3. Succeeded(成功)
pod中所有容器被成功终止,并且不会再重新启动。

4. Failed(失败)
Pod中所有已被终止,并且至少有一个容器因失败为终止,容器以非0状态退出。

5. Unknow(未知)
无法与pod取得联系,一般pod脱离了k8s管理,通常原因pod与主机通信失败。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章