Linux 常用资源对象清单配置速查手册-1
文章目录
- [1、Pod 容器集合](#1、Pod 容器集合)
- [2、Pod 的存储卷](#2、Pod 的存储卷)
- [3、Pod 的容器探针](#3、Pod 的容器探针)
- [4、ResourceQuota 全局资源配额管理](#4、ResourceQuota 全局资源配额管理)
- [5、PriorityClass 优先级类](#5、PriorityClass 优先级类)
- 管理多个资源对象清单文件常用方法:
- 使用 sed 流式编辑器批量修改脚本键值进行资源清单的创建,有助于日常测试工作:
yaml
for i in {1..5}
do
sed 's,web,&$i,' app.yaml | kubectl apply -f - # - 为标准输入占位符,表示上一个命令的输出
done
- -f 指定应用多个资源对象清单创建,有启动顺序:
kubectl apply -f
清单1 -f 清单2 -f 清单3 - -f 还可以应用文件夹内所有 yaml 清单: kubectl apply -f yaml/ # 无法保证 Pod 启动的顺序
- 合并多个资源对象管理文件,用于多个资源清单文件测试完毕后,统一合并使用:
bash
cat app/* > app.yaml # 先读取目录下所有文件后再重定向进行合并
- 资源对象清单配置模板获取方式:
- 常用模板使用创建命令获取:
kubectl create service --dry-run=client -o yaml > template.yaml
- 官方文档获取:https://kubernetes.io/zh-cn/docs/reference/kubernetes-api/
- 使用"解释"命令查询每一个子字段的解释与应用:
kubectl explain Pod.spec.containers.ports.
- 使用 AI 编写资源清单模板,再修改。
1、Pod 容器集合
Pod 的主要特点:
-
共享网络:Pod 中的所有容器共享同一个网络命名空间,这意味着它们能够访问相同的IP地址和端口范围,并且能够相互通信。
-
共享存储:Pod 中的容器能够访问相同的存储卷(Volumes),这使得它们可以共享数据和文件。
-
协同工作:Pod 中的容器设计为协同工作,它们可能是一个应用的不同组件,例如,一个容器处理用户请求,而另一个容器处理数据存储。
-
生命周期管理:Pods 拥有自己的生命周期,它们可以被创建、启动、停止和删除。Kubernetes 会保证 Pod 按照声明的状态运行。
-
重启策略:Pods 可以配置重启策略,以确定在容器崩溃时是否需要重启。
-
易于部署:通过定义Pod 的配置,可以很容易地部署和管理容器化应用。
-
不可变性:Pods 是短暂的,它们不应该被修改。如果需要更新 Pod ,应该创建一个新的 Pod ,并通过更新控制器(如Deployment)替换旧的Pod。
-
扩展性:虽然 Pods 可以包含多个容器,但它们通常用于运行单个应用程序或服务。对于需要水平扩展的应用,通常会使用多个 Pod 副本,并通过 Kubernetes 的控制器(如Deployment、StatefulSet或DaemonSet)来管理。
-
健康检查: Kubernetes 可以对Pod执行健康检查,以确保它们正常运行,并在检测到问题时进行适当的响应。
yaml
---
kind: Pod # 资源对象类型
apiVersion: v1 # api 版本,通过 kubectl api-resources 查看
metadata: # 元数据信息
name: web # 资源对象命名
namespace: work # 所属名称空间
labels: # <map> go 语言的 map 无序键值对集合数据类型
app: apache
type: web
spec:
activeDeadlineSeconds: 30
# Pod 最大生命周期,即使容器重启也不会重置,从 kubelet 通过 API-server
# 收到 scheduler 调度时,为 Pod 拉取容器镜像之前计时。到达时间 Pod 不会重启
terminationGracePeriodSeconds: 0
# 宽限期,Pod 停止前进行清理工作,比如保存状态、完成本地事务、结束服务的预留时间。
# nodeName: node-0002 # Pod 调度方式 1: 指定节点进行调度
nodeSelector:
kubernetes.io/hostname: node-0001
# <map> Pod 调度方式 2: 标签选择运算符,指定标签节点过滤进行调度
restartPolicy: OnFailure
#
# initContainers: # 在主容器之前运行,可进行依赖检查、资源准备、执行脚本
hostname: myweb # 指定 Pod 的主机名
hostAliases: # 写入 Pod 内容器的 hosts 文件映射,Pod 设置 hostNetwork 后不生效
- ip: 192.168.1.100 # IP 列表
hostnames: # IP 映射的主机名列表
- web
- nginx
containers:
- name: nginx
image: myos:nginx
imagePullPolicy: IfNotPresent
# Always 只拉取镜像仓库镜像,Nerver 只使用本地镜像,IfNotPresent 优先拉取本地镜像,无则拉取镜像仓库
env: # 传入一个环境变量列表
- name: TZ
value: "Asia/Shanghai" # 方式 1:指定传入单个确定值
# valueFrom:
# configMapKeyRef: # 方式 2: 通过配置映射的方式引用单个键值
# name: timezone # 可传入加密的键值对象,使用 secretKeyRef
# key: timezone
# envFrom: # 方式 3: 使用 configMap 或 secret 方式引入一组环境变量
# - configMapRef:
# name: timezone
command: ["/bin/sh"]
args:
- -c
- |
sleep 3
exit $((RANDOM%10))
lifecycle:
postStart: # 事件处理器/生命周期钩子函数,用于特定时刻执行代码,
exec: # 容器启动后执行,以下指定命令
command: ["/bin/sh","-c","|","sleep 1"]
# preStop: # 容器停止前执行,格式同上。用于执行容器结束前的清理工作。
resources: # 节点资源调配
requests: # 需求的配额
cpu: 300m # 300 毫核的CPU额定资源
memory: 400Mi # 400 Mi 的内存额定资源
limits: # 定义资源限额,会同时进行配额,默认配额大小等于限额
cpu: 500m
memory: 600Mi
hostPID: true # 开启特权容器,共享宿主机进程命名空间
hostNetwork: true # 必须开启系统进程特权,共享宿主机网络命名空间
status: {} # 由 kubelet 定期将 Pod 运行状态写入
2、Pod 的存储卷
Pod 支持多种存储卷 (volumes),有临时卷、持久卷、投射卷,通常需要创建此类资源对象,最后在 volumes 中声明,containers 内挂载使用,一个存储卷可被多个容器挂载,进行共享存储。持久卷可以在 Volume 内定义并挂载使用,也可以作为资源对象 PV 被创建,继而创建 PVC,在 Volumes 中调用 PVC,最后挂载使用。
临时卷有 emptyDir,configMap,secret 等,持久卷也有 hostPath、NFS、CephFS 等,投射卷则是指将多种其他卷投射到 Pod 容器内的一个目录。
1) Pod 内定义 PV 并使用
yaml
---
spec:
volumes: # 定义 Pod 的存储卷
- name: logdata
hostPath: # 该 PV 可以让 Pod 挂载所在节点的文件、目录,不过存在许多安全风险,且可用性取决于底层节点状态
path: /var/weblog # Pod 所在节点文件、目录
type: DirectoryOrCreate # 检查挂载路径的目录是否存在,不存在则创建
# FileOrCreate 同理,但不会创建父目录
- name: website
nfs: # 定义一个 nfs 类型的 PV 卷,用于共享前端页面
server: 192.168.1.30 # 需提供 nfs 共享的服务器 IP
path: /var/website # 挂载源路径
readOnly: true # 默认 false ,强制该类型 存储设备 使用只读权限挂载 nfs 导出,通用配置。
containers:
- name: nginx
image: myos:nginx
volumeMounts: # 使用容器预先定义的存储卷,进行卷挂载
- name: logdata # 定义的 PV 名
mountPath: /usr/local/nginx/logs
# 挂载到 Pod 内的路径
subPath: nginx # 用于指定所引用的卷内的子路径,而不是其根路径。即 /var/weblog/nginx
- name: website
mountPath: /usr/local/nginx/html
readOnly: true # 挂载时,定义 PV 存储设备时,均可强制以只读方式 挂载、导出,双重保障。
2) 创建 PV 与 PVC 持久卷声明 (申领、索要 PV)
PV 持久化存储卷可以持久存储容器数据,跟 Pod 生命周期不同,不会随着 Pod 被删除而丢失。同时具有不同资源回收策略,如 Retain,Delete。PV 没有命名空间限制,属于集群基础资源,PVC 是用命名空间进行隔离的。
K8S 靠 PV 与 PVC 对众多存储资源进行抽象的集合,PVC 允许用户按照需求声明存储资源,而无需关心具体的底层 PV 的存储细节,如存储容量是否足够,可供单个还是多个 Pod 读写等,直接通过 PVC 绑定合适的 PV 进行使用。
PV 与 PVC 的特点:
- PV 有自己的生命周期,它的状态包括可用(Available)、绑定(Bound)、释放(Released)、回收(Retained)等状态。
- PVC 与 PV 之间是一种声明与提供的关系。PVC 声明了对存储资源的需求,而 PV 则是提供这些资源的实际载体。
- PVC 可以指定所需的存储容量、访问模式等参数,但通常不需要指定具体的 PV,而是通过标签选择器来动态匹配 PV。
- 当 PVC 被删除时,绑定的 PV 不会被删除,而是变成了 Available 状态,可以被其他 PVC 绑定。当 PV 被删除时,绑定的 PVC 也会被删除。
yaml
---
kind: PersistentVolume # PV 持久卷的标准资源对象名
apiVersion: v1
metadata:
name: pv-nfs
labels: # <map> PVC 通过标签来寻找预先分类的 PV
pv: nfs
spec:
volumeMode: Filesystem # PV 卷的模式:文件系统,块设备 Block
accessModes:
- ReadWriteOnce
- ReadWriteMany
- ReadOnlyMany
capacity: # <map> 定义该 PV 的资源和容量
storage: 20Gi # 目前仅支持定义 容量,未来可能包括 IOPS、吞吐量等属性
persistentVolumeReclaimPolicy: Retain
# 资源回收策略: Retain 不删除 PV 与 数据,
# Delete 删除 PV 与 数据,目前 nfs 还保留了 Recycle 策略,不删除 PV,仅删除数据,PV 留着给其他 PVC 绑定。
mountOptions: # 支持对应存储设备的挂载选项
- nolock # nfs 挂载参数,不对文件进行 "写锁定"
nfs: # 该 PV 提供者的存储设备类型为 nfs
server: 192.168.1.30
path: /var/website
---
kind: PersistentVolumeClaim # 定义 PVC 存储卷声明 (申领,索要)
apiVersion: v1
metadata:
name: pvc-nfs
spec: # PVC 将自动寻找并绑定符合以下 spec 规约的 PV
volumeMode: Filesystem # 需要 文件系统类型的 PV
selector: # 通用的标签选择器
matchLabels: # <map> 匹配下列标签即满足条件,PVC 可进行绑定。
pv: nfs
accessModes:
- ReadWriteOnce # 只要定义了 RWO 访问模式的 PV
resources: # 定义对 PV 的资源请求,
requests: # 定义请求内容,目前只支持对 存储容量 的请求
storage: 15Gi # 需要有 15 GiB 存储容量的 PV
------------------------------------------------------------------------------------------------ # 在 Pod 中使用 PVC
---
spec:
volumes: # 定义一个 PVC 持久卷声明卷
- name: pvc-test
persistentVolumeClaim: # 引用 PVC 资源,定义 PVC 对象
claimName: pvc-nfs # 需要使用的 PVC 对象名称
containers:
‥‥‥‥‥‥
3) StorageClass 动态制备 PV
K8S有两种制作基础存储资源 PV 的方式,如下:
静态制备 PV:管理员需要预先创建满足各种需求的 PV,等待 PVC 申请使用
动态制备 PV:管理员无须预先创建 PV,而是通过 StorageClass 自动完成 PV 的创建以及与 PVC 的绑定。这在商业环境下需要数千 Pod 时,至关重要,手动制作需要动态变化的 PV 工作量巨大。
4) PV 卷的访问模式
每个 PV 持久卷的提供者能支持的访问模式都不同,如 NFS 可支持多个节点进行读写,而 hostPath 只支持单个节点进行读写,PV 卷中的 accessModes 描述的是本身的访问能力,可只定义当前 PV 所需的访问模式,在 PVC 中可以声明需要使用何种访问模式的 PV,进行绑定。
重要提醒!
每个卷同一时刻只能以一种访问模式挂载,即使该卷能够支持多种访问模式。
- RWO: ReadWriteOnce 仅供一个节点 读、写。
- RWX: ReadWriteMany 可供多个节点 读、写。
- ROX : ReadOnlyMany 可供多个节点 读,但不会对 PV 施加写保护,只是标记此 PV 有此属性。
- RWOP: ReadWriteOncePod 仅供单个 Pod 读、写。
5) 临时卷 (Ephemeral Volume)
① emptyDir :
该临时卷最初是空的,尽管 Pod 中其他容器挂载 emptyDir 卷的路径可能相同可能不同,该卷默认选择宿主机上的介质进行存储,可以是硬盘、SSD、或网络存储,也可以在 medium 中选择 Memory 挂载到 tmpfs 内存文件系统,但此时通常需要限制存储大小。
emptyDir 卷的一些用途:
- 缓存空间,例如基于磁盘的归并排序。
- 为耗时较长的计算任务提供检查点,以便任务能方便地从崩溃前状态恢复执行。
- 在 Web 服务器容器服务数据时,保存内容管理器容器获取的文件。
emptyDir 卷 YAML 示例
yaml
spec:
volumes: # 定义 存储卷
- name: cache-volume
emptyDir: # 定义 emptyDir 空目录存储卷
medium: Memory # 挂载到 tmpfs
sizeLimit: 500Mi
# empty: {} # 默认挂载到宿主机文件系统,无法指定路径
② configMap :
配置映射卷,可以集合生产环境配置、测试环境配置、开发环境配置等不同需求的配置,根据需求应用在不同命名空间的 Pod 内,对于生产环境下的 Pod,不能及时停服停机,也可以用 configMap 实现配置热更新的目的。只有通过 Kubernetes API 创建的 Pod 才能使用 configMap,kubelet 使用 manifest 创建的 static Pod 无法使用 configMap。
热更新配置,对于正在运行的 Pod,使用 configMap 挂载的 env 是在容器一创建好就注入其中,k8s 不会再更新 Pod 内的环境变量,且 pod 的环境变量是不断累加的,只要 Pod 不重启。对于 configMap 挂载的 Volume 来说,可以做到应用配置文件的动态更新,然而有不支持热更新的容器应用,可以使用滚动更新、或者蓝绿发布的方式。
注意 1:
configMap 不能用来存储大量数据,文件最好不要超过 1MB,因为 etcd 保证支持不超过 1MB 数据的 RPC 请求。
注意 2:
configMap 的 yaml 文件中键值行末存在空格会导致 data 中的 " | " 失效,键值末尾的换行符不能被正确转换,影响配置文件的应用。可用 sed 删除多余的行末空格:
sed -i 's/[[:space:]]*$//' 文件名.yaml
configMap 可以使用命令创建导入配置文件、目录、或单个键值对,也可以通过 sed 's,^, ,' nginx.conf >> nginx-config.yaml
控制缩进并手动导入配置文件内容到 YAML 中。
命令方式: kubectl create configmap nginx-config.yaml --from-file=nginx.config
也可以用 --from-file=conf/
的方式导入目录。
configMap 卷 YAML 示例
yaml
kind: ConfigMap
apiVersion: v1
metadata:
name: nginx-config
data: # 导入需要映射的配置文件内容
nginx.conf: | # 文件名为键名,文件内容为键值,注意使用 "|" 后的缩进
# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
···········
------------------------------------------------------------
spec:
volumes:
- name: nginx-config
configMap: # 定义 configMap 配置映射存储卷
name: nginx-config
containers:
- name: nginx
image: myos:nginx
volumeMounts: # 挂载上述定义的 configMap 配置文件
- name: nginx-config
mountPath: /usr/local/nginx/conf/nginx.conf # 默认挂载到 nginx.conf 目录,除非配置 subPath
subPath: nginx.conf
# 设定挂载卷内的子目录,在 configMap 挂载中指定把键名映射为文件名,键值即为文件内容。
③ secret 加密卷
secret 加密卷可以专门用于保存机密数据,在设置 secret.data 字段时,所有的键值必须是经过 base64 编码加密的字符串,所以需要通过命令的方式加密键值对,主要用来证书、token、环境变量、镜像仓库认证等敏感数据的加密:
kubectl create secret generic secret-tls --from-file=cret.pem --dry-run=client
3、Pod 的容器探针
针对启动探针、就绪性探针、存活探针的容器探针检查机制:
- exec : 用于在容器内执行指定命令,命令退出码为 0 则诊断成功
- grpc : 使用 gRPC 健康检查协议,检测容器内进程存活状态
- httpGet : 对容器的 IP 地址上指定路径、端口执行 HTTP GET 请求,200 <= 响应状态码 < 400 ,此区间内诊断成功
- tcpSocket : 对容器 IP 指定端口执行 TCP 检查。端口打开诊断成功,打开连接后立即关闭也算做健康。
每次探测只有三种状态,Success 成功,Failure 失败,Unknown 未知,诊断失败不会采取任何行动。
1) startupProbe 启动探针: 检测主容器启动前依赖的某个重要服务。
- 主容器启动后进行检测
- 直到 启动探针 成功之前,禁用其他探针
- 探测失败,直接杀死容器,重启开始下一次探测
- 主容器启动,启动探针执行成功,就不会重复执行
yaml
spec:
containers:
- name: web
images: myos:httpd
startupProbe: # 定义启动探针
tcpSocket: # TCP 存活探测,检测 Pod 8080 端口是否开放
port: 8080 # 可使用命名端口,httpGet也是,gRPC不支持
# host: 127.0.0.1 # 默认 Pod IP,一般不需要修改,除非 hostNetWork: true
# 容器使用了宿主机的网络命名空间,才需要改为 127.0.0.1
initialDelaySeconds: 5 # 容器启动后延迟 5s 启动探针,若定义了启动探针,
# 其他探针在其成功后才开始计时
timeoutSeconds: 4 # 超时等待时间,探测后等待容器响应的时间,
# 超过时间无回应则认为探测失败。
failureThreshold: 3 # 失败阈值,超过 3 次失败 Failure 杀死容器
successThreshold: 3 # 默认 1,成功阈值,3 次成功才标记为 Success
periodSeconds: 60 # 检测间隔,加长用来保护慢启动容器
2) readinessProbe 就绪性探针: 检测主容器运行时服务的状态是否正常,能否准备好接受请求流量,向外提供服务。
- 启用就绪性探针后,默认容器状态为 Failure,直到检测成功,被标记为就绪状态。
- 当检测失败时,端点控制器将从与 Pod 匹配的所有服务的端点列表中删除该 Pod 的 IP 地址。
- 就绪性探针在 Pod 生命周期内会一直存在。
yaml
spec:
containers:
- name: web
images: myos:httpd
readinessProbe:
httpGet: # HTTP 探测,200 <= x < 400 Success
scheme: HTTPS # 连接主机方式,默认 HTTP
path: /info.php # URL 请求路径
port: 80 # 检测 80 端口 http get 状态,
3) livenessProbe 存活探针: 许多长时间运行的应用最终会进入损坏状态,除非重新启动,分则无法被恢复,可用存活探针探测损坏状态,检测失败不可用,kubelet 会直接杀死容器执行重启策略
- 存活探针在 Pod 生命周期中一直存在
- 检测结果为 Failure ,执行重启策略
- 当 restartPolicy: Never,检测失败不会重建容器
- 被存活探针杀死并重启的容器会重新执行 启动探针 ,但不会执行 initContainer
yaml
spec:
containers:
- name: web
images: myos:httpd
livenessProbe: # 定义存活探针
exec: # 执行命令返回值检测
commands: # 命令的列表
- sh
- -c
- | # 执行脚本命令,检测最后一个命令的返回值,为 0 Success
4、ResourceQuota 全局资源配额管理
ResourceQuota设置每个命名空间内强制执行的总资源限额。
可限额对象范围。可进行限额对象有 计算资源、存储资源、资源对象。
Limit Range 资源范围限制,可以做到精细化限制命名空间内每一个 Pod 的最小、最大配额限制区间,配置复杂,暂不常用。
yaml
kind: ResourceQuota # 全局资源限额 资源对象
apiVersion: v1
metadata:
name: myquota
namespace: work # 限额生效空间
spec:
hard: # <map> 创建强制限额规则
pods: 5 # 限制 Pod 总量为 5个
cpu: 2000m # 空间内 CPU 总配额为 2 核
memory: 6Gi # 空间内内存总配额为 6Gi
scopes: # 匹配过滤所有被配额跟踪的对像
- BestEffort # Pod 节点压力驱逐类型为"尽量型"的数量限制为 5
# Guaranteed 保障型:配额 = 限额,这影响了 Pod 的 QoS 服务质量评级
# Burstable 暴发型:配额 < 限额
# 尽量型无明确资源限额,节点资源消耗过大,会被优先驱逐
5、PriorityClass 优先级类
PriorityClass是一个无命名空间资源对象,定义了从优先级类"名称"到优先级"整数值"的映射,Priority 关系到 Pod 之间的调度规则,优先级高的 Pod 可以被优先调度,系统资源紧张时能够抢占其他 Pod 的资源。
情景设计:帮助理解 scheduler 触发抢占策略并调度系统资源逻辑。
php1、2、3 定向调度到同一节点,模拟资源不足,依次运行,查看抢占情况
php1 无优先级
php2 1000 优先级,不抢占
php3 500 优先级,抢占
> ① php1 运行
> ② php2 排队,资源不足
> ③ php3 被 scheduler 触发抢占策略,发生抢占
> 注:Pod 无法被调度时,scheduler 会由于触发 Pod 上设定的抢占策略,从而尝试抢占(驱逐)较低优先级的 Pod, 以使悬决(pending) Pod 可以被调度。kubelet 执行其指令,资源被释放
> ④ php2 运行
> 原因:
> php3 优先级 < php2 无法被优先调度,即使它先 "抢占了 php1",但释放后的系统资源被 scheduler 严格分配调度给其他 Pod,它只触发抢占策略,判断有低优先级 Pod 需要被抢占,释放资源,重新调度 Pod 时,判断 php 2 优先级高,优先调度。
> scheduler 调度 Pod 原则:priority 优先级大的 Pod 优先运行,禁止私下分配资源。
yaml
kind: PriorityClass # 优先级类资源对象
apiVersion: scheduling.k8s.io/v1
metadata:
name: low-pri
value: 500 # Priority 的范围:(int32) -2,147,483,648 ~ 10^9 (十亿)
preemptionPolicy: Never # 抢占策略 /ˌpriːˈempʃn/ pre emption,
# 默认项:PreemptionLowerPriority 抢占低优先级,Neber 从不
description: "low priority" # 优先级类的描述信息
globalDefault: false # 默认 false,设置集群级别的全局默认优先级,
# 多个全局默认优先级类,取 value 最小的生效
---------------------------------------------------------------------------------
Pod 中使用方式:声明优先级类名称即可
spec:
priorityClassName: low-non