暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

k8s-pod详解01

原创 喵呜 2025-03-11
179

[TOC]
## 五、pod详解
```
官方文档:https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/assign-memory-resource/
yaml文件编写指导:https://www.cnblogs.com/Pigs-Will-Fly/p/17904421.html
```
### 5.1 pod介绍
```
1.pod是k8s最小基本操作单元,一个pod中可以包含一个或者多个紧密相关的容器,一个pod可以被一个容器化的环境看作应用层的逻辑宿主机。
2.一个pod中的多个容器应用通常是紧密耦合的,pod在<node>上被创建、启动或销毁。
3.每个pod里运行着一个特殊的称之为pause的容器,其他容器则为业务容器,这些业务容器共享pause容器的网络栈和volume挂载卷,因此他们之间通信和数据交换更为高效。
4.同一个pod里的容器之间仅需通过localhost就能互相通信。同一个pod里面的业务容器共享pause容器的ip地址,共享pause容器挂载的存储卷。
```

#### 5.1.1 pod的结构
> 每个pod中都可以包含一个或多个容器,这些容器可以分为两类:

![pod.png](https://note.youdao.com/yws/res/0/WEBRESOURCE295ed746dbab47338ff1ccc191762b60)

```
1. 用户程序所在的容器,数量可多可少。
2. pause容器,这是每个pod都会有的一个根容器,它的作用有两个:
a.可以以它为依据,评估整个pod的健康状态。
b.可以在根容器上设置ip,pod中的其他容器共享这个ip,容器之间可以通过localhost互相通信(这里是pod内部的通讯,pod之间的通讯采用虚拟二层网络技术来实现,我们当前环境用的是flannel)。
```
#### 5.1.2 pod资源清单详解
```
说明:
1.yaml文件中的字段遵循"驼峰命名法",即第一个单词的首字母小写,以后单词的首字母大写。
例如:apiVersion、imagePullPolicy、containerPort、postStart、matchLables、rollingUpdate等。

2.pod的属性类型:
> string 字符串型,用于表示一段文本。
> object 对象,表示一组键值对的集合,可以嵌套其它属性。它通常用于定义嵌套的结构,例如容器的定义、资源配置等。
> list 数组,一组按次序排列的值,又称序列(sequence)/列表(list),数组名后面加冒号,然后换行,每个数组元素前面加"破折号+空格",表示这是数组中的一个元素。
比如,多个容器、多个端口、多个环境变量等。

apiVersion: v1 [String] # 必选,版本号,例如v1
kind: Pod   [String] # 必选,资源类型,例如 Pod
metadata:   [Object] # 必选,元数据
name: string [String] # 必选,Pod名称,注意,仅可以使用小写字母大写字母会报错!!
namespace: string [String] # Pod所属的命名空间,默认为"default"
labels:    [map[string]string] # 自定义标签
name: string [String]
app: my-app [String]
spec: [Object] # 必选,Pod中容器的详细定义
containers: [list] # 必选,Pod中容器列表
- name: string [String] # 必选,容器名称
image: string [String] # 必选,容器的镜像名称
imagePullPolicy: [String] # 获取镜像的策略,有[ Always | Never | IfNotPresent ]
command: [string] [String] # 容器的启动命令列表,如不指定,使用打包时使用的启动命令
args: [string] [String] # 容器的启动命令参数列表
workingDir: string [String] # 容器的工作目录
volumeMounts: [list] # 挂载到容器内部的存储卷配置
- name: string [String] # 引用pod定义的共享存储卷的名称,需用volumes[]部分定义的的卷名
mountPath: string [String] # 存储卷在容器内mount的绝对路径,应少于512字符
readOnly: boolean [String] # 是否为只读模式
ports: [list] # 需要暴露的端口列表
- 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: # pod中容器的重启策略,有[Always | Never | OnFailure]
# 在k8s中,pod本身并没有直接的"重启"概念,此处的restartPolicy是针对容器的。根据探针的探测结果进行重启。
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
```
#### 5.1.3 kubectl explain查看资源的属性
```
1.查看某种资源可以配置的一级属性。
kubectl explain [资源类型]

2.查看二级属性
kubectl explain [资源类型.属性]

3.查看三级属性同上

4.在k8s中,基本所有资源的一级属性都是一样的,主要包含5部分(以下使用pod举例):
[root@master ~]# kubectl explain pod
FIELDS:
apiVersion <string> # 版本,由k8s内部定义,版本号必须可以用 kubectl api-versions 查到。
kind <string> # 资源类型,由k8s内部定义。
metadata <Object> # 元数据,主要是资源标识和说明,常用的有name、namespace、labels等。
spec <Object> # 描述,这是配置中最重要的一部分,里面是对各种资源配置的详细描述。
# spec specification的简写 /ˌspesɪfɪˈkeɪʃ(ə)n/ n. 规范;说明书。
status <Object> # 状态信息,里面的内容不需要定义,由k8s自动生成。
```
#### 5.1.4 yaml文件编写指导
```
1.yaml文件基础组成
常见的yaml文件中一般都包含apiVersion、kind、metadata、spec这四个元素,且这四个元素在书写时前面都不需要用空格。

2.通过 kubectl explain [资源类型] 的方法可以获取到该资源下有哪些参数配置。

3.yaml文件中的字段一般都遵循"驼峰命名法",即第一个单词的首字母小写,以后单词的首字母大写。
如:apiVersion、imagePullPolicy、containerPort、postStart、matchLables、rollingUpdate等。

4.如何确定元素前是否需要添加"- " ?
若通过 kubectl explain [资源类型] 返回的信息显示该资源的类型是 "<[] *>",即其中含"[]"则表示该参数是列表格式,则需要添加横线-。

# 如下示例所示:
[root@k8smaster1 ~]# kubectl explain pod.spec.containers
KIND: Pod
VERSION: v1
RESOURCE: containers <[]Object> # 则说明 containers 为列表,它内容的首行需加-
...
FIELDS:
args <[]string> # 则说明 args 为列表,它内容的首行需加-
...
command <[]string> # 则说明 command 为列表,它内容的首行需加-
```

### 5.2 pod的yaml文件基础配置
> 本小结主要来研究 pod.spec.containers 属性,这也是pod配置中最为关键的一项配置。

```
# 以下是 pod.spec 常见的属性:
[root@master ~]# kubectl explain pod.spec
FIELDS:
initContainers <[]Object> # 初始化容器
containers <[]Object> # 容器列表,用于定义容器的详细信息。
nodeName <string> # 根据nodeName的值将pod调度到指定的Node节点上。
nodeSelector <map[]> # 根据NodeSelector中定义的信息选择将该pod调度到包含这些label的Node上。
hostNetwork <boolean> # 是否使用主机网络模式,默认为false,如果设置为true,则表示使用宿主机网络。
volumes <[]Object> # 存储卷,用于定义pod上面挂载的存储信息。
restartPolicy <string> # 重启策略,表示pod在遇到故障的时候的处理策略。

# 以下是 pod.spec.containers 常见的属性:
[root@master ~]# kubectl explain pod.spec.containers
FIELDS:
name <string> # 容器名称
image <string> # 容器的镜像
imagePullPolicy <string> # 镜像拉取策略
command <[]string> # 容器的启动命令列表,如不指定,使用打包时使用的启动命令。
args <[]string> # 容器的启动命令需要的参数列表,arguments n.参数
env <[]Object> # 容器环境变量的配置
ports <[]Object> # 容器需要暴露的端口号列表
resources <Object> # 资源限制和资源请求的设置
lifecycle <Object> # 生命周期钩子
livenessProbe <Object> # 存活性探针
readinessProbe <Object> # 就绪性探针
```
> 镜像信息 - pod.spec.containers.name/image

```
spec:
containers:
- name: nginx
image: nginx:1.24.0
- name: busybox
image: busybox:1.30
```
> 镜像拉取 - pod.spec.containers.imagePullPolicy

```
# 示例:
spec:
containers:
- name: nginx
image: nginx:1.24.0
imagePullPolicy: Always

imagePullPolicy 用于设置镜像拉取策略,k8s支持以下三种拉取策略:
> Always # 总是从远程仓库拉取镜像(一直远程下载)。
> IfNotPresent # 本地有则使用本地镜像,本地没有则从远程仓库拉取。present /ˈprez(ə)nt/ adj.存在的
> Never # 只使用本地镜像,从不去远程仓库拉去,本地没有就报错(一直使用本地)。

说明:如果镜像的tag为具体版本号,默认策略是:IfNotPresent;如果镜像的tag为latest,默认策略是:Always
```
> 启动命令 - pod.spec.containers.command

```
# 在前面的案例中busybox一直没运行成功,原因是busybox并不是一个程序而是一个工具类的集合,
k8s集群启动后它会自动关闭,解决方法就是让它一直运行,这就用到了command配置。

# 示例:
spec:
containers:
- name: busybox
image: busybox:1.30
imagePullPolicy: IfNotPresent
command: ["/bin/sh","-c","touch /tmp/hello.txt;while true;do /bin/echo $(date +%T) >> /tmp/hello.txt; sleep 3; done;"]

1.说明
以上command的意思是,首先创建/tmp/hello.txt文件,然后每隔三秒写入一下当前时间到/tmp/hello.txt文件。

验证:
执行以下命令进入到 pod-command 的busybox容器中
[root@master ~]# kubectl exec -it pod-command -c busybox -n dev /bin/sh
/ # tail -f /tmp/hello.txt

附加:
kubectl exec [参数]
-it 以交互模式进入容器。
-c 指定容器,若不指定则选择pod中的第一个容器。

2.特别说明:
通过上面发现command已经可以完成启动命令和传递参数的功能,那为什么还要提供args选项用于传递参数呢?
其实这和docker有点关系,k8s中的command、args两项其实是实现覆盖dockerfile中的ENTRYPOINT的功能。
> 如果command和args均没有填写,那么用dockerfile的配置。
> 如果command和args都写了,那么dockerfile的配置被忽略,执行command并追加上args参数。
> 如果command写了,但是args没有写,那么dockerfile默认的配置会被忽略,执行输入的command。
> 如果command没写,但是args写了,那么dockerfile中配置的ENTRYPOINT的命令会被执行,使用当前的args参数。
```
> 环境变量 - pod.spec.containers.env

```
# env <[]Object> 容器环境变量的配置,数组类型,即,我们可以通过env向容器传递多个键值对作为环境变量,但该方法使用较少,不推荐,了解即可。

# 示例:
spec:
containers:
- name: busybox
image: busybox:1.30
command: ["/bin/sh","-c","while true;do /bin/echo $(date +%T);sleep 60; done;"]
env: # 设置环境变量列表
- name: "username"
value: "admin"
- name: "password"
value: "123456"

1.创建pod
[root@master ~]# kubectl create -f pod-env.yaml

2.进入到容器busybox中,并输出环境变量。
[root@master ~]# kubectl exec -it pod-env -c busybox /bin/sh -n dev
/ # echo $username
admin
/ # echo $password
123456
```
> 端口设置 - pod.spec.containers.ports

```
1.ports <[]Object> # 容器需要暴露的端口号列表,对象数组(因为一个容器可能不止一个端口)。

2.查看ports支持的子选项:
[root@master ~]# kubectl explain pod.spec.containers.ports
FIELDS:
name <string> # 端口名称(根据实际使用自定义),如果指定,则必须保证name在pod中是唯一的。
containerPort <integer> # 容器要监听(使用)的端口(0 - 65535)。
protocol <string> # 端口协议,必须是TCP、UDP或SCTP,默认是TCP。
hostIP <string> # 要将外部端口绑定到的主机ip(一般省略)。
hostPort <integer> # 容器要映射到主机上的端口,如果设置,则主机上只能运行容器的一个副本(一般省略),
# 因为多副本的话会运行多个pod,每个pod中都有这个容器,这些容器的端口相同,所以不能同时映射到主机的同一个端口(端口冲突)。
说明:访问容器中的程序时,需要使用pod的ip:containerPort

# 示例:
spec:
containers:
- name: nginx
image: nginx:1.26.0
imagePullPolicy: IfNotPresent
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
```
> 资源配额 - pod.spec.containers.resources

```
容器中的程序运行肯定要占用一定的资源,如CPU和内存等,如果不对容器的资源做限制,那么它就可能吃掉大量的资源,从而导致其它容器无法运行。
针对这种情况,k8s提供了对CPU和内存的资源进行配置的机制,这种机制主要通过 resources 选项实现,它有以下两个子选项:
- limits: 用于限制容器运行时的最大占用资源,当容器占用资源超过limits时会终止,并重启。
- requests:用于设置容器需要的最小资源,如果环境资源不够,容器将无法启动。

# 示例:
spec:
containers:
- name: nginx
image: nginx:1.26.0
imagePullPolicy: IfNotPresent
ports:
- name: port-nginx
containerPort: 80
protocol: TCP
resources:
limits:
cpu: "1"
memory: "1G"
requests:
cpu: "0.1"
memory: "10M"

说明:
cpu:core数,可以是整数,也可以是小数。
memory:内存大小,可以使用"Gi、Mi"或"G、M"等形式。
```

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论