K8s Pod 资源进阶

文章目录

K8s Pod 资源进阶

pod 资源限制

资源限制的方法:

  • Requests: 申请的资源大小; 刚创建时,申请1G内存,找到符合的节点,然后调度上去;
  • Limits: 限制运行过程中的最大使用量; 限制2G,当达到2G就没办法在继续使用了;

限制资源种类。常用有 cpu 和 memory 资源,也可以用来限制 nvidia.com/gpu 资源。限制gpu资源需要先安装对应插件,gpu 的限制方案和cpu 基本一致

Pod资源限制:

  • CPU/GPU: 可压缩资源,超载,响应慢;
  • 内存: 不可被压缩的资源,超载,触发OOM机制;杀死Pod;看 QOS

限制资源单位

  • CPU: 1 核CPU 等于 1000 毫核, 1 核心 = 1000 millicpu(1 Core = 1 m)。 k8s 不允许设置精度小于1m 的CPU 资源。 因此当 CPU 单位小于 1 时, 只能用豪核心表示

  • memory: 内存的基本单位是字节数(Bytes),也可以加上国际单位,十进制的 E、P、T、G、M、K、m,或二进制 Ei、Pi、Ti、Gi、Mi、Ki

    1 MB = 1000 KB = 1000000 Bytes

    1 Mi = 1024 KB = 1038576 bytes

资源限制实战

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: pod-resource
spec:
  containers:
  - name: memory-demo-ctr
    image: polinux/stress
    command: ["stress"]
    args: ["--vm", "1", "--vm-bytes", "250M", "--vm-hang", "1" ] # 告知容器尝试分配 150 MiB 内存 
    resources:
      requests:
        cpu: "100m" #  申请 0.1 Core cpu 资源  设置高了。没有可调度node, pod 会一直处于pending 状态
        memory: "100Mi"  # 申请 100 Mi 内存  设置高了 pending
      limits:
        cpu: "200m"      # 最多使用 0.2 Core cpu 超了会影响效率
        memory: "200Mi"  # 最多使用 200 Mi 内存  使用超过设置 会导致 status 为 OOMKilled 内存溢出(OOM) 杀死容器

Pod 服务质量Qos

QoS(Quality of Service),译作 "服务质量保证", 是作用在Pod 上的一个配置,当kubernetes 创建一个pod 时,它就会给这个Pod 分配一个QoS 等级。

当Pod 过载使用资源时,kubernetes 会根据Pod 对象的服务质量和优先级等完成判定,进而挑选对应的Pod 杀死。kubernetes 根据pod 的Requests 和 Limits 属性,把Pod 对象归类为三类 BestEffort、BurStable、Guaranteed

  • Guaranteed: Pod 对象为每个容器(包括initContainer)都设置了CPU资源需求和资源限制,切两者值相同;还同时为每个容器设置了内存需求和限制,并且两者的值相同。这类Pod 对象具有最高级别的服务质量
  • Burstable: 至少有一个容器设置 CPU 或内存资源 Requests 属性,但不满足 Guaranteed, 这类Pod具有中级服务质量
  • BestEffort: 没有为任何容器设置Requests 和 Limits属性,这类Pod对象服务质量是最低级别

当 kubernetes 集群内存资源紧缺,优先杀死BestEffort类别的容器,因为系统不为该类资源提供任何服务保证,但此类资源最大的好处就是能够尽可能的使用资源。

如果系统中没有BestEffort类别的容器,接下来就轮到BUrstable类别的容器,如果有多个Burstable类别的容器,就看谁的内存资源占用多,就优先干掉谁。比如A容器申请16内存资源,实际使用了95%,而B容器申请了26内存资源,实际使用了80%,但任然会优先干掉A容器,虽然A

容器的用量少,但与自身的Requests值相比,它的占比要大于B容器。

对于Guaranteed类别的容器拥有最高优先级,它们不会被杀死,除非其内存资源需求超限,或者OOM时没有其他更低优先级的Pod对象存在,才会千掉Guaranteed类容器。

Downward API

DownwardAPI可以让容器获取Pod的相关元数据信息,比如Pod名称,Pod的IP,Pod的资源限制等,获取后通过env、volume的方式将相关的环境信息注入到容器中,从而让容器通 过这些信息,来设定容器的运行特性。

  • 例如:Nginx进程根据节点的CPU核心数量自动设定要启动的worker 进程数。
  • 例如:JVM虛拟根据Pod的内存资源限制,来设定对应容器的堆内存大小。
  • 例如:获取Pod名称,以Pod名称注册到某个服务,当Pod结束后,调用prestop清理对应名称的注册信息。

可注入的元数据信息

使用 pod.spec.containers.env. valueFrom. fieldRef 可以注入的字段有:

  • metadata.name:Pod对象的名称
  • metadata.namespace:Pod对象隶属的名称空间
  • metadata.uid: Pod对象的UID
  • metadata.labels['']:获取Labe1指定KEY对应的值
  • metadata.annotations["']:获取Annotat ions对应KEY的值
  • status.podIP:Pod对象的IP地址
  • status.hostIP:节点IP
  • status.nodeName:节点名称
  • spec.serviceAccountName:Pod对象使用的ServiceAccount资源名称

使用 pod.spec.containers.env.valueFrom.resourceFieldRef 可以注入的字段有:

  • requests.cpu
  • requests.memory
  • limits.cpu
  • limits.memory

环境变量方式注入元数据

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: pod-down-api
  labels:
    app: nginx-app
    role: backend
    zone: beijing
spec:
  containers:
  - name: pod-down-api
    image: nginx
    command: ["/bin/bash" ,  "-c", "env"]
    resources:
      requests:
        cpu: "200m"
        memory: "32Mi"
      limits:
        cpu: "200m"
        memory: "64Mi"

    env:
    - name: APP1_POD_NAME
      valueFrom:
        fieldRef:
          fieldPath: metadata.name

    - name: APP1_POD_NAMESPACE
      valueFrom:
        fieldRef:
          fieldPath: metadata.namespace

    - name: APP1_POD_LABELS
      valueFrom:
        fieldRef:
          fieldPath: metadata.labels['app']

    - name: APP1_CPU_REQUESTS
      valueFrom:
        resourceFieldRef:
          resource: requests.cpu

    - name: APP1_MEM_LIMITS
      valueFrom:
        resourceFieldRef:
          resource: limits.memory
          divisor: 1Mi       # 默认显示为字节,通过 divisor 调整显示单位为兆

存储卷方式注入元数据

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: pod-down-api-volumes
  labels:
    app: nginx-app
    role: backend
    zone: beijing
spec:
  containers:
  - name: pod-down-api
    image: nginx
    resources:
      requests:
        cpu: "200m"
        memory: "32Mi"
      limits:
        cpu: "200m"
        memory: "64Mi"
    volumeMounts:   # 将环境变量挂载到/etc/podinfo 目录中,没注入一条元数据都会产生一个文件
    - name: podinfo
      mountPath: /etc/info

  volumes:
  - name: podinfo
    downwardAPI:
      items:
      - path: pod_name
        fieldRef:
          fieldPath: metadata.name
          
      - path: pod_namespace
        fieldRef:
          fieldPath: metadata.namespace

      - path: pod_labels
        fieldRef:
          fieldPath: metadata.labels

      - path: req_cpu
        resourceFieldRef:
          containerName: pod-down-api
          resource: requests.cpu

      - path: limit_mem
        resourceFieldRef:
          containerName: pod-down-api
          resource: limits.memory

为注册服务注入Pod 名称

yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: pod-mysql-register
spec:
  replicas: 10
  selector:
    matchLabels:
      app: tools
  template:
    metadata:
      labels:
        app: tools
    spec:
      containers:
      - name: register
        image: tools:latest  # 找一个能够有mysql client的镜像即可
        imagePullPolicy: IfNotPresent
        command:
        - "/bin/bash"
        - "-c"
        - |
          mysql -h 172.0.1.1 -uroot -p1234 -e "create database ${POD_NAME//-/_}"
          sleep 99999999
    
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
    
        lifecycle:
          preStop:  # pod 终止前执行
            exec:
              command:
              - "/bin/bash"
              - "-c"
              - mysql -h 172.0.1.1 -uroot -p1234 -e "drop database ${POD_NAME//-/_}"

为 JVM 注入堆内存限制

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: pod-tomcat-downward
spec:
  containers:
  - name: tomcat
    image: tomcat:9.0.63
    ports:
    - containerPort: 8080
    env:
    - name: JAVA_OPTS   # JVM 内存设置环境变量
      value: -server -Xms${JVM_XMS} -Xmx${JVM_XMX} -XX:+UseConcMarkSweepGC
    - name: JVM_XMS   # 读取 resources 配置
      valueFrom:
        resourceFieldRef:
          resource: requests.memory
    - name: JVM_XMX
      valueFrom:
        resourceFieldRef:
          resource: limits.memory
    resources:
      requests:
        memory: 100Mi
      limits:
        memory: 100Mi
相关推荐
似水流年 光阴已逝1 小时前
Kubernetes Pod 基本原理:全面详解
云原生·容器·kubernetes·pod
PKNLP1 小时前
07.docker介绍与常用命令
运维·docker·容器
阿里云云原生2 小时前
评估工程正成为下一轮 Agent 演进的重点
云原生
人工智能训练3 小时前
在ubuntu系统中如何将docker安装在指定目录
linux·运维·服务器·人工智能·ubuntu·docker·ai编程
爱宇阳3 小时前
Java Spring Boot 项目 Docker 容器化部署教程
java·spring boot·docker
掘根3 小时前
【Docker】网络
网络·docker·容器
爱宇阳5 小时前
从容器化到自动化:Vue3 项目 Docker 部署与 GitLab CI/CD 集成 Harbor 全流程
docker·自动化·gitlab
高旭博5 小时前
10. kubernetes资源——statefulset有状态负载
云原生·容器·kubernetes
_Walli_5 小时前
k8s集群搭建(七)-------- 微服务间的调用
微服务·容器·kubernetes
马达加斯加D5 小时前
k8s --- resource: Pod, ReplicaSet and Deployment
云原生·容器·kubernetes