一、Pod 的概念
kubernetes并不直接管理容器,它的最小管理单元是Pod。Pod是一个或多个容器的组合,这些容器贡献存储,网络,命名空间以及运行规范。在Pod中所有容器被统一安排和调度,在共享上下文中运行(共享上下文是一种基于线程的内存位置)。Podshi他们的逻辑主机,包含多个容器,是一组共享命名空间,IP地址和端口容器的集合。
Pod 可以简单的理解为一组、一个或多个容器,每个 Pod 还包含一个 Pause 容器,Pause 容器是 Pod 的父容器,主要负责僵尸进程的回收管理。同时,通过 Pause 容器可以使同一个 Pod里面的不同容器共享存储、网络、PID、IPC 等,容器之间可以使用 Localhost:Port 的方式相互访问,可以使用 volume 实现数据共享。根据 Docker 的构造,Pod 可以被创建为一组具有共享命名空卷、IP 地址和端口的容器。
Pod 有两个必须知道的特点:
网络: 每一个 Pod 都会被指派一个唯一的 Ip 地址,在 Pod 中的每一个容器共享网络命名空间,包括 Ip 地址和网络端口。在同一个 Pod 中的容器可以同 locahost 进行互相通信。当Pod中的容器需要与 Pod 外的实体进行通信时,则需要通过端口等共享的网络资源。
存储: Pod 能够被指定共享存储卷的集合,在 od 中所有的容器能够访问共享存储卷,允许这些容器共享数据。存储卷也允许在一个 pod 持久化数据,以防止其中的容器需要被重启。
(1)kubectl 创建pod
[root@k8s-master ~]# ku run nginx --image=nginx:1.7.9 --labels="app=nginx"
pod/nginx created
(2)查看pod
[root@k8s-master ~]# ku get pods -n default
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 5m52s
(3)显示pod更多详细信息
[root@k8s-master ~]# ku get pod nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 0 7m14s 10.244.85.195 k8s-node01 <none> <none>
(4)查看pod日志
[root@k8s-master ~]# curl 10.244.85.195
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>........
[root@k8s-master ~]# ku logs nginx
10.244.235.192 - - [21/Aug/2024:01:35:54 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0"
(5)显示资源的详细描述信息
[root@k8s-master ~]# ku describe pod nginx
(6)在pod容器执行命令
[root@k8s-master ~]# ku exec nginx -c nginx -- date
Wed Aug 21 01:45:50 UTC 2024
备注:
-c :指定Pod中容器的名字
(7)登录到pod容器中
[root@k8s-master ~]# ku exec -it nginx -c nginx -- bash
root@nginx:/# exit
exit
(8)在线编辑运行资源对象
[root@k8s-master ~]# ku edit pod nginx
(9)将pod端口映射到宿主机
[root@k8s-master ~]# ku port-forward --address 0.0.0.0 pod/nginx 8080:80
Forwarding from 0.0.0.0:8080 -> 80
备注:
curl 192.168.10.101:8080
在前台运行,Ctrl+c停止
(10)在宿主机和pod容器之间拷贝文件
[root@k8s-master ~]# ku cp nginx:etc/fstab /opt/aaa.txt
[root@k8s-master ~]# cd /opt/
[root@k8s-master opt]# ls
aaa.txt cni containerd k8s
[root@k8s-master opt]# cat aaa.txt
# UNCONFIGURED FSTAB FOR BASE SYSTEM
[root@k8s-master opt]# ku cp /opt/aaa.txt nginx:etc/bbb.txt
(11)pod的状态
[root@k8s-master ~]# ku get pod
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 7s
状态 | 说明 |
Pending (挂起) | pod被k8s系统接收,但有一个或容器未被创建,通过kubectl describe查看pending状态 |
running(运行中) | pod 绑定到一个节点上,所有容器已经创建,至少有一个运行的状态,正在启动或者重启kubectl logs查看日志 |
succeeded(成功) | 所有容器启动成功,并终止。不会再次重启,通过kubectl logs查看 |
Failed(失败) | 所有容器都已终止,并且至少一个容器以失败的方式终止也就是说这个容器要么以非零状态退出,要么被系统终止,可以通过 logs 和 describe 查看 Pod 的日志和状态 |
Unknown (未知) | 通常是由于通信问题造成的无法获得 Pod 的状态 |
ImagePullBackoff ErrImagePull | 镜像拉取失败,一般是由于镜像不存在、网络不通或者需要登录认证引起的,可以使用 describe 命令查看具体的原因 |
CrashLoopBackoff | 启动失败,可以通过 logs 命令查看具体的原因,一般为启动命令不正确、健康检查不通过等原因 |
OOMKilled | 容器内存溢出,一般是容器的内存 Limit 设置的过小,或者程序本身有内存溢出,可以通过 logs 查看程序的启动日志 |
Terminating | Pod 正在被删除,可以通过 describe 查看状态 |
SysctlForbiden | Pod 自定义了内核配置,但 kubect1 没有添加内核配置或配置的内核参数不支持,可以通过 describe 查看具体原因 |
Completed | 容器内部主进程退出,一般计划任务执行结束会显示该该状态,此时可以通过 logs 查看容器日志 |
ContainerCreating | Pod 正在创建,一般正在下载镜像,或者有配置不当的地方,可以通过 describe 查看具体原因 |
(12)删除pod
[root@k8s-master ~]# ku delete pod nginx
pod "nginx" deleted
二、Pod 探针
在生产环境中,进程正常启动并不代表应用能正常处理请求,所以合理的设计应用的健康检查尤其重要。在使用裸机或裸容器部署时,一般很难对应用做很完善的健康检查,而 Pod 提供的
探针可以很方便的用来检测容器的应用是否正常。目前探针有 3 种检测方式,可以根据不同的场景选择合适的健康检查方式。
实现方式 | 说明 |
ExecAction | 在容器内执行一个指定的命令,如果命令返回值为 0,则认为容器健康 |
TCPSocketAction | 通过 TCP 连接检查容器指定的端口,如果端口开放,则认为容器健康 |
HTTPGetAction | 对指定的 URL 进行 Get 请求,如果状态码在 200-40 之间,则认为容器健康 |
状态 | 说明 |
Success (成功) | 容器通过检查 |
Failure (失败) | 容器检查失败 |
Unknown (未知) | 诊断失败,因此不采取任何措施 |
Pod 探针有三类,分别是: ivenessProbe (存活探针) 、readinessProbe (就绪探针)startupProbe (启动探针)。
livenessProbe (存活探针): 判断容器是否正常运行,如果失败则杀掉容器(不是 pod),再根据重启策略决定是否重启容器。
readinessProbe (就绪探针) : 判断容器是否能够进入 ready 状态,探针失败则进入noready 状态,并从 service 的 endpoints 中别除此容器。
startupProbe (启动探针) :判断容器内的应用是否启动成功,在 success 状态前,其它探针都处于无效状态。
三、Pod镜像拉取策略和重启策略
在发布应用或者更改适配器时,会触发pod的滚动更新,容器镜像会存在不同的拉去方式。
操作方式 | 说明 |
Always | 总是拉取,无论镜像是否存在,总是拉取 |
Never | 无论是否存在都不会拉取 |
IfNotPressent | 镜像不存在时拉取镜像,是 k8s 默认的策略但是如果 tag 为 latest,则总是拉取 |
(1)指定拉取策略
[root@k8s-master ~]# ku run nginx --image=nginx:1.7.9 --labels="app=nginx" --image-pull-policy=Always
(2)指定重启策略
[root@k8s-master ~]# ku delete pod nginx
[root@k8s-master ~]# ku run nginx --image=nginx:1.7.9 --labels="app=nginx" --restart=onFailure
四、创建Pod
(1)编写简单的Pod
[root@k8s-master ~]# vim nnginx-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
name: nginx
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containersPort: 80
(2) Pod文件资源清单
apiVersion: v1 #必选,接口版本版本号,例如v1
kind: Pod #必选,资源类型,例如 Pod
metadata: #必选,元数据
name: string #必选,Pod名称
namespace: string #Pod所属的命名空间,默认为"default"
labels: #自定义标签列表
- name: string
spec: #必选,Pod中容器的详细定义
containers: #必选,Pod中容器列表
- name: string #必选,容器名称
image: string #必选,容器的镜像名称
imagePullPolicy: [ Always|Never|IfNotPresent ] #获取镜像的策略
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 #内存请求,容器启动的初始可用数量
lifecycle: #生命周期钩子
postStart: #容器启动后立即执行此钩子,如果执行失败,会根据重启策略进行重启
preStop: #容器终止前执行此钩子,无论结果如何,容器都会终止
livenessProbe: #对Pod内各容器健康检查的设置,当探测无响应几次后将自动重启该容器
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的重启策略
nodeName: <string> #设置NodeName表示将该Pod调度到指定到名称的node节点上
nodeSelector: obeject #设置NodeSelector表示将该Pod调度到包含这个label的node上
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
(3)运行kubectl create 命令创建Pod
[root@k8s-master ~]# ku create -f frontend-localredis-pod.yaml
pod/redis-php created
或者
[root@k8s-master ~]# ku apply -f nginx-pod.yaml
pod/nginx created
(4) 查看已创建的Pod
[root@k8s-master ~]# ku get pod
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 9m43s
redis-php 2/2 Running 0 6s
(5) 查看Pod详细创建信息
[root@k8s-master ~]# ku get pod nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 0 13m 10.244.85.197 k8s-node01 <none> <none>
[root@k8s-master ~]# curl 10.244.85.197
<!DOCTYPE html>
<html>
........
<a href="http://nginx.com/">nginx.com</a>.</p><p><em>Thank you for using nginx.</em></p>
</body>
</html>
(6)暴露端口
[root@k8s-master ~]# ku expose pod nginx-php --port=8080 --target-port=80 -- type=NodePort --name=nginx-php01
备注:
--port=8080 暴露在外部端口
--target-port=80 容器内部端口
(7)查看端口映射
[root@k8s-master ~]# ku get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-php01 NodePort 10.96.48.45 <none> 8080:30486/TCP 12s
测试访问:
(8) 删除Pod
[root@k8s-master ~]# ku delete pod nginx-php
pod "nginx-php" deleted
五、静态Pod
静态 Pod 是由 kubelet 进行管理的仅存在于各个 Node 上的 Pod。他们不能通过 API Server进行管理,无法于 ReplicationController、Deployment 或者 DaemonSet 进行关联,并且kubelet 无法对他们进行健康检查。静态 Pod 总是由 kubelet 创建的,并且总在 kubelet 所在的 Node 上运行。
(1)编写yaml文件,查看Pod
[root@k8s-master ~]# cp nginx-pod.yaml /etc/kubernetes/manifests/
[root@k8s-master ~]# ku get pod
NAME READY STATUS RESTARTS AGE
nginx-k8s-master 1/1 Running 0 7s
[root@k8s-master ~]# ku get pod nginx-k8s-master -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-k8s-master 1/1 Running 0 162m 10.244.235.199 k8s-master <none>
备注:
/etc/kubernetes/manifests/ 资源清单
(2)删除静态Pod方法
[root@k8s-master ~]# rm -rf /etc/kubernetes/manifests/ nginx-pod.yaml
备注:
(1) Pending: 表示APIServer 创建了 Pod 资源对象并已经存入了 etcd 中,但是它并未被调度完成(比如还没有调度到某台 node 上),或者仍然处于从仓库下载镜像的过程中
(2) Running: Pod 已经被调度到某节点之上,并且 Pod 中所有容器都已经被 kubelet 创建至少有一个容器正在运行,或者正处于启动或者重启状态(也就是说 Running 状态下的 Pod 不-定能被正常访问)
(3) Succeeded: 有些 pod 不是长久运行的,比如 job、cronjob,一段时间后 Pod 中的所有容器都被成功终止,并且不会再重启。需要反馈任务执行的结果
(4) Failed: Pod 中的所有容器都已终止了,并且至少有一个容器是因为失败终止。也就是说,容器以非 状态退出或者被系统终止,比如 command 写的有问题
(5) Unknown: 表示无法读取 Pod 状态,通常是 kube-controller-manager 无法与 Pod 通
信