k8s(三)pod管理
通过本文章,可以对pod的基本概念、创建、排错、调度等方面有基本的认识。
目录
(一)pod基本概念
1:什么是pod?
- pod是k8s中最小的管理单元
- pod由一个或多个容器组成
- pod是一个服务的多个进程的聚合单位
- 同一个pod共享网络IP、权限、主机名、存储设备
2:pod的生命周期
- pod对象从创建开始至结束的时间范围称为生命周期
- 在这段时间中,pod处于多种不同的状态
- 创建主容器为必须操作,其他为可选(包括运行初始化容器、启动后钩子、存活性探测、就绪性探测、终止前钩子等)
- post start|pre stop:钩子程序,一段触发式脚本。前者为开始的,后者为结束的。
- liveness probe :生命探针,监控容器在运行时是否发生故障。
- readiness probe:就绪性探针,判断容器运行状态是否符合预期,是否准备好为请求提供服务。
- startup probe:启动探针,指示容器中的应用是否已经启动。
(二)pod创建过程
1:pod如何创建
- 前提条件:创建容器必须有对应的镜像
- 使用run子命令创建
- 使用资源文件
2:pod创建过程
步骤如下:(异步操作)
- API Server 接收用户创建pod的指令,并将pod对象的相关信息存入etcd数据库中,完成后向客户端发送反馈信息。
- Scheduler(集群调度器)通过“watch”监控机制检查API Server的相关变动且该Pod对象目前并未调度至任何节点。
- Scheduler通过调度计算,分配给合适的node(最闲的),然后将最新分配结果存储在etcd中。
- Kubelet通过“watch”监控机制检查API Server的变动,以及etcd中的变化(scheduler分配绑定的创建pod的node节点)。
- Kubelet调用docker API 创建pod,并将更新后的pod状态返还给API Server ,同时存入etcd中。
3:pod相位状态(status字段)
- pending:等待被调度,排队。pod已经被k8s系统接受,但有一个或多个容器尚未创建亦未运行。此阶段包括pod等待被调度的时间和通过网络下载镜像的时间。
- running:Pod 已经绑定到了某个节点,Pod 中所有的容器都已被创建。至少有一个容器仍在运行,或者正处于启动或重启状态。
- succeed:容器被要求执行一项任务,任务完成后,容器成功运行可以被终止。
- failed:Pod 中的所有容器都已终止,并且至少有一个容器是因为失败终止。
- unknown:因为某些原因无法取得 Pod 的状态。这种情况通常是因为与 Pod 所在主机通信失败。
(三)pod排错三兄弟
1:kubectl get
2:kubectl describe
3:kubectl logs
#k8s系统的管理和排错一直都是工作中的重点,利用以上三种方式可以有效解决绝大部分问题。
#排错小技巧。在书写资源对象文件时,可用cat -A 找出文件中不可见的特殊中文字符。
(四)pod资源对象文件
1:什么是资源对象?
- k8s对象是目标性记录
- k8s使用这些对象去表示整个集群的状态
2:什么是资源对象文件?
- 用于描述资源对象基本信息,以及描述该对象的期望状态特征的文件。
- 使用yaml语法表示
3:资源对象文件详解
命名规范:(大写驼峰式命名法)
- 大驼峰(所有单词首字母大写),小驼峰(除单词首字母不大写,其余单词首字母均大写)
- 所有键值对的key使用小驼峰,所有键值对的value使用大驼峰
关于缩进
- 由键值对和数组组成
- key的所有下级value要有缩进
- 数组:下面 “-” 后面跟的代表数组的元素
文件详解
#资源的特征描述
--- #yaml文件开始的标志
kind:pod #当前创建资源的类型
apiVersion:v1 #当前资源对象的版本
metadata: #元数据,属性信息
name:mypod #属性信息,资源的名称
spec:
terminationGracePeriodSeconds: 0 #宽限时间设置,默认是30s
restartPolicy: Always #服务故障策略。
containers: #容器资源特征描述
- name:nginx #容器的名称
image:myos:nginx #启动容器使用的镜像
imagePullPolicy: IfNotPresent #镜像下载策略。
ports: #声明容器使用的网络端口
- protocol:TCP #声明容器使用的协议
containerPort:80 #声明容器使用的端口号
command:["/bin/bash"] #自定义命令,还可以添加嵌入式脚本
args: #命令的参数
- -c #从字符串中读取命令
- | #固定yaml语法,以下多行字符串保留原格式
while true;do
sleep 5
echo “hello world”
done#服务故障策略:默认Always:无限重启;Never:不管什么原因停止,绝不重启;OnFailure:基于条件判断结果,判断程序的状态码,如果是0就不重启,非0则重启。
#镜像下载策略:默认IfNotPresent:优先使用本机缓存,如果没有就去仓库找;always:只使用仓库里的镜像;never:只使用本机缓存的镜像;)
#在书写kind和apiversion时,可以通过kubectl api-resource查询;spec根据实际需求找
(五)静态pod
1:什么是静态pod?
-
由kubelet守护进程直接管理的pod,不需要API服务器监管,kubelet监视每个静态pod
-
用户直接通过kubelet创建的容器叫静态pod,只能创建在用户指定的节点上,不能迁移
-
静态pod的spec不能引用其他API对象
-
静态pod配置路径:/var/lib/kubelet/config.yaml
-
搭建k8s集群时,master集群的四大核心组件就是静态pod创建的
(六)pod调度策略
1:调度策略概述
什么是调度分配?
- kube-scheduler是默认调度器,也是集群的核心组件
- 调度是将pod分配到合适的计算节点上,然后在对应节点上的kubelet运行这些pod
调度器如何工作?
- 调度器通过“watch”检测机制发现集群中未被分配到计算节点的pod,调度器依据调度算法将pod分配到合适的节点上运行。
调度策略流程概述
- 筛选。首先筛选出满足pod所有的资源请求的节点,包括计算资源、内存、存储、网络等,若没有节点满足pod的需求,pod将一直处于pending状态,直到调度器能找到合适的节点运行它。
- 打分。调度器会根据打分规则,为每一个可调度节点进行打分,选出其中得分最高的节点来运行pod,如果存在多个得分最高的节点,则随机选取一个。
- 绑定。在确定了某个节点运行pod以后,调度器将这个调度决定通知给api-server。
pod定向调度
#基于节点名称的调度
- 在创建pod的过程中,可以配置相关的调度规则,让pod运行在指定的节点上。
- nodeName标签,让pod运行在指定节点上,在pod资源对象文件中spec下声明目标主机名。
- 如果标签指定的节点无法运行pod,它不会迁移到其他节点,将会一直等待下去
2:标签管理
标签基本概念
- 标签是附加到k8s对象上的键值对。
- 使用节点名称定向调度不够灵活,使用标签可以更加灵活的完成调度任务。
- 标签可以在创建时附加到对象,也可以在创建之后随时添加和修改。标签可以用于组织和选择对象的子集。
管理标签命令
#语法格式:kubectl label 资源类型 [资源名称] [选项/参数]
- 查看标签:kubectl get 资源类型 [资源名称] --show-labels
- 设置标签:kubectl label 资源类型 [资源名称] <label-key>=<label-value>
- 删除标签:kubectl label 资源类型 [资源名称] <label-key>-
- 例1:查询资源对象标签(#使用--show-labels查询标签)
- kubectl get pods --show-labels
- kubectl get nodes --show-labels
- kubectl get namespaces --show-labels
- 例2:使用标签过滤资源对象(-l 筛选标签)
- kubectl get nodes -l kubernetes.io/hostname=master
- 例3:为资源对象添加标签
- kubectl label pod myhttpd app=apache
- 例4:删除标签(直接在key值后面加-)
- kubectl label pod myhttpd app-
资源文件中配置标签
---
kind: Pod
apiVersion: v1
metadata: #在此处定义标签
name:myhttpd
labels: #声明标签
app:apache #标签键值对,可以有多个
spec:
........
基于标签的调度
#使用系统标签调度
#在spec下用nodeSelector定义标签的调度
#kubernetes.io/hostname:node-0002 ,这是node-0002上独有的标签
[root@master ~]# kubectl get nodes node-0002 --show-labels
NAME STATUS ROLES AGE VERSION LABELS
node-0002 Ready <none> 3h38m v1.22.5 kubernetes.io/hostname=node-0002 ... ...
[root@master ~]# vim myhttpd.yaml
---
kind: Pod
apiVersion: v1
metadata:
name: myhttpd
labels:
app: apache
spec:
terminationGracePeriodSeconds: 0
restartPolicy: Always
nodeSelector: # 基于节点标签进行调度
kubernetes.io/hostname: node-0002 # 这是node-0002上独有标签
containers:
(七)pod资源配额
1:资源配额概述
- 当多个应用共享固定节点数目的集群时,某些应用可能会过度的使用资源,从而影响到其他服务。因此需要设定一些规则,用来保证应用能获得其运行所需的合理的资源。
- cpu资源类型。cpu资源的约束和请求以毫核(m)为单位。在k8s中,1m是最小的调度单位,1核cpu可以看作1000m
- 内存资源类型。内存的约束和请求以字节为单位。可以使用以下单位来表示:E P T G M k ,1k=1000 。 也可以使用以下单位来表示:Ei Pi Ti Gi Mi Ki ,1Ki=1024 。
- 配额是分配的资源,实际使用中可以超过该值,一般用于核心的重点程序。
- 限额。资源的最大使用量就是对应所分配的量;限制容器的最大使用量。
#在spec下,对应containers下,用“resources”定义配额,用“requests”定义最小资源配额,用“limits”限制最大资源配额,内存需求用“memory”表示,cpu需求用“cpu”表示。
2:最小资源配额
---
kind: Pod
apiVersion: v1
metadata:
name: minpod
spec:
terminationGracePeriodSeconds: 0
restartPolicy: Always
nodeSelector:
kubernetes.io/hostname: node-0003
containers:
- name: linux
image: myos:v2009
resources: #定义资源的配额
requests: #定义最小资源配额
cpu: “800m” #计算资源需求
memory: “1200Mi” #内存资源
3:最大资源配额
---
kind:Pod
apiVersion: v1
metadata:
name: maxpod
spec:
terminationGracePeriodSeconds: 0
restartPolicy: Always
nodeSelector:
kubernetes.io/hostname: node-0003
containers:
- name: linux
image: myos:v2009
resources: #定义资源的配额
limits: #定义最大资源限额
cpu: “800m” #计算资源最大配额
memory: “2000Mi” #内存资源最大配额
4:全局资源配额
基本概述
- 如果有大量的容器需要设置资源配额,为每个pod设置资源配额策略不方便管理。所以可以以名称空间(namespace)为单位,限制其资源的使用与创建,该名称空间中创建的容器都会受到规则的限制。
- 对内存、cpu、存储资源进行配额:LimitRange
- 对pod进行配额:ResourceQuota
默认配额策略
#如果在创建pod时明确了资源配额,那么该规则就会覆盖掉全局资源配额。
#创建名称空间
[root@master ~]# kubectl create namespace myns
#设置默认配额
[root@master ~]# vim mynslimit.yaml
---
kind: Pod
apiVersion: v1
metadata:
name: mylimit
namespace: myns
spec:
limits: #全局限制规则
- type: Container #资源类型
default: #如果没有配置资源配额,以下配置生效
cpu: 300m #cpu限额
memory: 500Mi #内存限额
defaultRequest:
cpu: 8m #最小保留资源,cpu
memory: 8Mi #最小保留资源,内存
#创建名称空间限制规则
[root@master ~]# kubectl -n myns apply -f mynslimit.yaml
5:资源配额范围
多容器资源配额
---
kind: Pod
apiVersion: v1
metadata:
name: maxpod
spec:
terminationGracePeriodSeconds: 0
restartPolicy: Always
containers:
- name: c1
image: myos:v2009
resources:
limits:
cpu: "800m"
memory: "1000Mi"
- name: c2
image: myos:v2009
resources:
limits:
cpu: "800m"
memory: "1000Mi"
基于pod的资源配额
---
kind:LimitRange
apiVersion: v1
metadata:
name: mylimit
namespace: myns
spec:
limits: #全局限制规则
- type: Container #资源类型
default: #如果没有配置资源配额,以下配置生效
cpu: "300m" #cpu限额
memory: "500Mi" #内存限额
defaultRequest:
cpu: "8m" #最小保留资源,cpu
memory: "8Mi" #最小保留资源,内存
max:
cpu: "800m"
memory: "1000Mi"
min:
cpu: "2m"
memory: "8Mi"
- type: Pod #资源类型
max: #最大资源类型
cpu: "1200m" #cpu限额
memory: "1200Mi" #内存限额
min: #最小资源限额
cpu: "2m" #cpu限额
memory: "8Mi" #内存限额
全局quota配额
#基于总数量配额
---
kind: ResourceQuota
apiVersion: v1
metadata:
name: myquota
namespace: myns
spec:
hard:
requests.cpu: "1000m"
requests.memory: "2000Mi"
limits.cpu: "5000m"
limits.memory: "8Mi"
pods: "3"
(八)pod污点策略
1:污点与容忍
污点概述
- 污点是是节点与pod产生排次的一类规则。
- 污点策略通过嵌合在键值对上的污点标签进行声明(污点标签必须绑定在键值对上)。
- pod调度可以理解为白名单,而pod污点可以理解为黑名单
污点标签
- 尽量不调度:PreferNoSchedule #只对新建的pod有效,在优选环节,打最低分
- 不会被调度:NoSchedule #只对新建的pod有效,优选环节都到不了,第一阶段就会被过滤掉
- 驱逐节点:NoExecute #不仅对新建的pod有效,历史数据都会删除。
管理污点标签
key=value:[污点标签] #污点标签必须绑定在键值对上
kubectl describe nodes [节点名字] #查看污点标签
kubectl taint node [节点名字] key=value:污点标签 #设置污点标签
kubectl taint node [节点名字] key=value:污点标签- #删除污点标签
调度顺序
- 优先使用没有污点的节点
- 最后使用PreferNoSchedule节点
- 不会使用NoSchedule节点
容忍策略
#容忍与污点相反。需要在有污点的节点上运行pod,这种无视污点标签的调度方式叫作容忍
#如何定义容忍策略
---
......
spec: #在pod.spec下定义
tolerations: #定义容忍策略
- operator: "Equal" #匹配方式(Equal、Exists)
key: "k1" #设置键值对的key,为空代表任意键值对
value: "v1" #设置values的值
effect: "NoSchedule" #设置容忍的标签,为空代表所有污点标签#Equal:精准匹配。需要键值对的key和value与标签都匹配。
#Exists:模糊匹配其中任意一项
2:优先级与抢占
优先级概述
- 优先级表示一个pod相较于其他pod的重要性。
- 优先级可以保证重要的pod被调度运行。
PriorityClass
- PriorityClass是一个全局资源对象。 用整数数值在value字段中指定,值越大优先级越高。
- PriorityClass中另外两个可选字段。globalDefault:用于设置默认优先级状态,如果没有任何优先级设置,pod的优先级为0 ;description:用来配置描述性信息,告诉用户优先级的用途。
优先级策略
- 非抢占优先:在调度阶段优先进行调度分配,一旦容器调度完成就不可以抢占,资源不足时,只能等待。(preemptionPolicy:Never)
- 抢占优先:强制调度一个pod,如果资源不足无法被调度,调度程序会抢占(删除)较低优先级的pod资源,来保证高优先级pod的运行。(preemptionPolicy:PreemptLowerPriority)
如何使用优先级和抢占
- 配置优先级类PriorityClass或抢占类PriorityClass
- 创建pod时为其设置对应的优先级。
#配置优先级类PriorityClass(定义优先级) ->[在yaml文件中单独定义]
[root@master ~]# vim mypriority.yaml
---
kind: PriorityClass #资源对象类型
apiVersion: scheduling.k8s.io/v1 #资源对象版本
metadata:
name: high-non #优先级名称,可以在pod中引用
globalDefault: false #是否定义默认优先级(唯一)
preemptionPolicy: Never #抢占策略。非抢占优先
value: 1000 #优先级
description: non-preemptive #描述信息#抢占策略还可以定义为抢占优先->[preemptionPolicy:PreemptLowerPriority]
#创建pod时为其设置对应的优先级。直接调用优先级名字即可->[priorityClassName]
[root@master ~]# vim php.yaml
---
kind: Pod
apiVersion: v1
metadata:
name: php
spec:
nodeSelector:
kubernetes.io/hostname: node-0002
priorityClassName: high-non # 优先级名称
containers:
- name: php
image: myos:phpfpm
resources:
requests:
cpu: "1500m"
(九)pod安全
1:特权容器
什么是特权容器?
- 首先,容器是通过名称空间实现的隔离。但是在执行一些应用服务时,需要使用或修改敏感的系统信息,这时容器需要突破隔离限制,拥有更高的权限。这一类容器称为特权容器。
- 运行特权容器会存在一定的安全风险。在这种模式下,运行容器对宿主机拥有root访问权限,可以突破隔离限制,直接对宿主机资源进行配置。
如何创建特权容器?
- 修改主机名
- 修改/etc/hosts
- 共享主机进程
- 共享主机网络
- 获取root权限
#更改容器主机名和/etc/hosts文件
[root@master ~]# vim root.yaml
---
kind: Pod
apiVersion: v1
metadata:
name: root
spec:
terminationGracePeriodSeconds: 0
restartPolicy: Always
hostname: myhost # 特权,修改主机名
hostAliases: # 修改 /etc/hosts
- ip: 192.168.1.30 # IP 地址
hostnames: # 名称键值对
- registry # 主机名
.....[root@master ~]# kubectl apply -f root.yaml
[root@master ~]# kubectl delete pod root
#共享主机及网络,获得root特权
[root@master ~]# vim root.yaml
---
kind: Pod
apiVersion: v1
metadata:
name: root
spec:
terminationGracePeriodSeconds: 0
restartPolicy: Always
hostPID: true # 特权,共享系统进程
hostNetwork: true # 特权,共享主机网络
containers:
- name: linux
image: myos:v2009
imagePullPolicy: IfNotPresent
securityContext: # 安全上下文值
privileged: true # root特权容器 ->获取真机的文件系统权限,最高权限
......
2:pod安全策略
安全性概述
- pod安全策略是集群级别的资源,可以控制pod运行的行为,以及具有的访问能力。
- k8s服务器版本不应该低于v1.22。
- 确保PodSecurity特权门控被启用。
pod安全策略
- PodSecurity提供一种内置的pod安全性准入控制器。pod安全性限制实在pod被创建时,在名字空间层面实施的。
- pod安全性标准定义了三种不同的策略。这些策略是渐进式的,安全级别从高度宽松至高度受限。
pod安全策略(LEVEL)
- privileged:不受限制的策略,提供最大可能范围的权限许可。此策略允许特权提升
- baseline:弱限制性策略,禁止已知的策略提升权限,允许使用默认的pod配置
- restricted:非常严格的限制性策略,遵循当前的保护pod的最佳实践。
pod准入控制标签(MODE)
- k8s定义了一组标签,可以通过设置这些标签来定义某个名字空间上pod安全性标准级别。所选择的标签定义了检测到潜在违例时,所要采取的动作。
- enforce:策略违例会导致pod被拒绝。强制性行为,最高级别
- audit:策略违例会触发审计日志,并做记录,但是pod仍可被接受
- warn:策略违例会触发用户可见的警告信息,但是pod仍可被接受
#格式:pod-security.kubernetes.io/<MODE>:<LEVEL>
(kubernetes.io-->系统定义好的标签)
生产环境设置严格的准入控制
- [root@master ~]# kubectl create namespace mypr
- [root@master ~]# kubectl label namespaces myprod pod-security.kubernetes.io/enforce=restricted
测试环境测试警告提示
- [root@master ~]# kubectl create namespace mytest
- [root@master ~]# kubectl label namespaces mytest pod-security.kubernetes.io/warn=baseline
更多推荐
所有评论(0)