目录

(一)pod基本概念

1:什么是pod?

2:pod的生命周期

(二)pod创建过程

1:pod如何创建

2:pod创建过程

3:pod相位状态(status字段)

(三)pod排错三兄弟

1:kubectl get 

2:kubectl describe 

3:kubectl logs 

(四)pod资源对象文件

1:什么是资源对象?

2:什么是资源对象文件?

3:资源对象文件详解

(五)静态pod

1:什么是静态pod?

(六)pod调度策略

1:调度策略概述

2:标签管理

(七)pod资源配额

1:资源配额概述

2:最小资源配额

3:最大资源配额

4:全局资源配额

5:资源配额范围

(八)pod污点策略

1:污点与容忍

2:优先级与抢占

(九)pod安全

1:特权容器

2: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创建过程

在这里插入图片描述

步骤如下:(异步操作)

  1.  API Server 接收用户创建pod的指令,并将pod对象的相关信息存入etcd数据库中,完成后向客户端发送反馈信息。
  2. Scheduler(集群调度器)通过“watch”监控机制检查API Server的相关变动且该Pod对象目前并未调度至任何节点。
  3. Scheduler通过调度计算,分配给合适的node(最闲的),然后将最新分配结果存储在etcd中。
  4. Kubelet通过“watch”监控机制检查API Server的变动,以及etcd中的变化(scheduler分配绑定的创建pod的node节点)。
  5. 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: #宽限时间设置,默认是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访问权限,可以突破隔离限制,直接对宿主机资源进行配置。

如何创建特权容器?

  1. 修改主机名
  2. 修改/etc/hosts
  3. 共享主机进程
  4. 共享主机网络
  5. 获取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

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐