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
相关推荐
为什么这亚子29 分钟前
九、Go语言快速入门之map
运维·开发语言·后端·算法·云原生·golang·云计算
阿尔帕兹1 小时前
构建 HTTP 服务端与 Docker 镜像:从开发到测试
网络协议·http·docker
ZHOU西口2 小时前
微服务实战系列之玩转Docker(十八)
分布式·docker·云原生·架构·数据安全·etcd·rbac
牛角上的男孩3 小时前
Istio Gateway发布服务
云原生·gateway·istio
JuiceFS4 小时前
好未来:多云环境下基于 JuiceFS 建设低运维模型仓库
运维·云原生
景天科技苑5 小时前
【云原生开发】K8S多集群资源管理平台架构设计
云原生·容器·kubernetes·k8s·云原生开发·k8s管理系统
wclass-zhengge6 小时前
K8S篇(基本介绍)
云原生·容器·kubernetes
颜淡慕潇6 小时前
【K8S问题系列 |1 】Kubernetes 中 NodePort 类型的 Service 无法访问【已解决】
后端·云原生·容器·kubernetes·问题解决
川石课堂软件测试8 小时前
性能测试|docker容器下搭建JMeter+Grafana+Influxdb监控可视化平台
运维·javascript·深度学习·jmeter·docker·容器·grafana
昌sit!14 小时前
K8S node节点没有相应的pod镜像运行故障处理办法
云原生·容器·kubernetes