欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Kubernetes资源对象:pod

程序员文章站 2024-03-11 10:10:37
...

pod是一组紧密关联的容器集合,它们共享 IPC、Network 和 UTS namespace,是 Kubernetes 调度的基本单位。Pod 的设计理念是支持多个容器在一个 Pod *享网络和文件系统,可以通过进程间通信和文件共享这种简单高效的方式组合完成服务。

以下就是pod  yaml

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx
    ports:
    - containerPort: 80

根据yaml结构,pod对象的结构主要核心是pod.spec.containers, 每一个container 主要是由image(镜像),name(容器名),ports(端口组)组成,

根据yaml 的特殊符合  - ,代表着这个是数组中的一个,可以明确 pod 可以有多个容器,每个容器能开放多个端口;

pod.metadata.labels 对应结构类型为map,也就是说pod可以有多个label ,提供给其他资源筛选。

pod的资源使用限制

应用调度到哪些节点,节点资源是否占满,资源使用率是否低,这些都是需要考虑的东西,故需要添加对pod的资源使用限制,保证pod以合理的资源配额运行在节点上。

pod.spec.containers[].resources

  resources:
   requests:
     memory: "32Mi"
     cpu: "125m"
   limits:
     memory: "64Mi"
     cpu: "250m"

spec.containers[].resources.limits.cpu:CPU 上限,可以短暂超过,容器也不会被停止

spec.containers[].resources.limits.memory:内存上限,不可以超过;如果超过,容器可能会被终止或调度到其他资源充足的机器上

spec.containers[].resources.requests.cpu:CPU 请求,也是调度 CPU 资源的依据,可以超过

spec.containers[].resources.requests.memory:内存请求,也是调度内存资源的依据,可以超过;但如果超过,容器可能会在 Node 内存不足时清理

关于pod的亲和性调度

服务往往因自身特性,可能会分为计算密集型(cpu),io密集型,网络密集型等,故可能需要划分节点,明确节点是否网络性能优先或io性能优先,故在服务调度的时候,需要考虑节点亲和;

若多个计算密集型资源服务调度到同一个节点,就可能会出现cpu紧缺,memory空余,导致资源浪费,故服务与服务之间的不亲和调度是在生产环境上必不可少的;

往往一个应用会有多个服务组成,某些服务之间调用十分频繁,那么这两个服务部署在同一个节点,性能提升将会十分明显。

pod.spec.affinity 下有着三种亲和性类型: nodeAffinity(节点亲和),podAffinity(pod亲和),podAntiAffinity(pod反亲和)

nodeAffinity demo


    nodeAffinity:

      requiredDuringSchedulingIgnoredDuringExecution:

        nodeSelectorTerms:

        - matchExpressions:

          - key: kubernetes.io/e2e-az-name

            operator: In

            values:

            - e2e-az1

            - e2e-az2

      preferredDuringSchedulingIgnoredDuringExecution:

      - weight: 1

        preference:

          matchExpressions:

          - key: another-node-label-key

            operator: In

            values:

            - another-node-label-value

requiredDuringSchedulingIgnoredDuringExecution :代表必须要满足条件

preferredDuringSchedulingIgnoredDuringExecution :代表优先条件,若条件不满足,在调度的时候也可以不考虑

preferredDuringSchedulingIgnoredDuringExecution.[].weight : 代表优先条件的权重,在条件冲突的时候,权重越高,优先支持

matchExpressions[].key : 代表node label 对应 key

matchExpressions[].operator : 代表 筛选label value 值的方式,有In, NotIn, Exists, DoesNotExist等方式

matchExpressions[].value : 代表 node label 对应 value

podAffinity / podAntiAffinity demo

    podAffinity:

      requiredDuringSchedulingIgnoredDuringExecution:

      - labelSelector:

          matchExpressions:

          - key: security

            operator: In

            values:

            - S1

        topologyKey: failure-domain.beta.kubernetes.io/zone

    podAntiAffinity:

      preferredDuringSchedulingIgnoredDuringExecution:

      - weight: 100

        podAffinityTerm:

          labelSelector:

            matchExpressions:

            - key: security

              operator: In

              values:

              - S2

          topologyKey: kubernetes.io/hostname

topologyKey: 代表筛选出node labels 的key中 有topologyKey value 的node

 容器健康检查

容器运行起来,并不代表其能够提供正常服务,比如tomcat容器,往往需要一定时候启动,才能提供服务,故需要一种方式判定服务到底能否提供正常;

在容器一直运行,但处于无法提供服务的状态下,虽然健康检查可以使pod not ready,并使其不提供给其他服务调用,但其他实例负载就会变大,如何打破这种僵局,需要一种健康检查,判断无法提供服务,则重启容器的策略。

livenessProbe: 是根据规则检查pod状态,若检测结果为异常,则重启pod

readinessProbe: 是根据规则来不停止检测pod状态,若检测结果为异常,则将pod状态置为not rady,直到检测结果正常,将pod状态置为 ready

pod.spec.containers[].livenessProbe ,

pod.spec.containers[].readinessProbe

     livenessProbe:

        httpGet:

          path: /

          port: 80

          httpHeaders:

          - name: X-Custom-Header

            value: Awesome

        initialDelaySeconds: 15

        timeoutSeconds: 1
    readinessProbe:

        exec:

          command:

          - cat

          - /usr/share/nginx/html/index.html

        initialDelaySeconds: 5

        timeoutSeconds: 1

pod.spec.containers[].livenessProbe.httpGet: 代表使用http get 请求进行验证

pod.spec.containers[].livenessProbe.initialDelaySeconds: 代表容器正式启动后,多久后开始验证

pod.spec.containers[].livenessProbe.timeoutSeconds: 代表通过验证方式超时时间,超时代表着失败

pod.spec.containers[].readinessProbe.exec: 进入到容器内使用命令进行验证

  • 在容器刚运行阶段,readiness 判定健康状态的初始值为 false,当readinessprobe 验证通过,才变为 true ,也就是pod 进入ready 状态
  • liveness 判定健康状态的初始值为 true ,当 livenessprobe验证失败,才变为fasle,则容器进行重启。

容器存储挂载

PV 与 PVC

PersistentVolume (PV) 和 PersistentVolumeClaim (PVC) 提供了方便的持久化卷:PV 提供网络存储资源,而 PVC 请求存储资源。

设置pv(持久化存储)包括置底层文件系统或者云数据卷、创建持久性数据卷最后创建 PVC 来将 Pod 跟数据卷关联起来。

PV 和 PVC 可以将 pod 和数据卷解耦,pod 不需要知道确切的文件系统或者支持它的持久化引擎。

PersistentVolume(PV)是集群之中的一块网络存储。跟 Node 一样,也是集群的资源。PV 跟 Volume (卷) 类似,不过会有独立于 Pod 的生命周期。比如一个 NFS 的 PV 可以定义为

apiVersion: v1

kind: PersistentVolume

metadata:

  name: pv0003

spec:

  capacity:

    storage: 5Gi

  accessModes:

    - ReadWriteOnce

  persistentVolumeReclaimPolicy: Recycle

  nfs:

    path: /da/project/pvname

    server: 172.17.0.2

PV 的访问模式(accessModes)有三种:

  • ReadWriteOnce(RWO):是最基本的方式,可读可写,但只支持被单个 Pod 挂载。
  • ReadOnlyMany(ROX):可以以只读的方式被多个 Pod 挂载。
  • ReadWriteMany(RWX):这种存储可以以读写的方式被多个 Pod 共享。不是每一种存储都支持这三种方式,像共享方式,目前支持的还比较少,比较常用的是 NFS。在 PVC 绑定 PV 时通常根据两个条件来绑定,一个是存储的大小,另一个就是访问模式。

PV 的状态变化

  1. Available: 可用状态
  2. Bound: 已经分配给pvc
  3. Released: pvc解绑但未执行回收策略
  4. Failed: 发生错误

PV 的回收策略(persistentVolumeReclaimPolicy,即 PVC 释放卷的时候 PV 该如何操作)也有三种

  • Retain,不清理, 保留 Volume(需要手动清理)
  • Recycle,删除数据,即 rm -rf /thevolume/*(只有 NFS 和 HostPath 支持)
  • Delete,删除存储资源,比如删除 AWS EBS 卷(只有 AWS EBS, GCE PD, Azure Disk 和 Cinder 支持)

PVC是存储资源的请求,而 PersistentVolumeClaim (PVC) 是对 PV 的请求。

PVC 跟 Pod 类似:Pod 消费 Node 资源,而 PVC 消费 PV 资源;Pod 能够请求 CPU 和内存资源,而 PVC 请求特定大小和访问模式的数据卷。

kind: PersistentVolumeClaim

apiVersion: v1

metadata:

  name: myclaim

spec:

  accessModes:

    - ReadWriteOnce

  resources:

    requests:

      storage: 8Gi

  selector:

    matchLabels:

      release: "stable"

    matchExpressions:

      - {key: environment, operator: In, values: [dev]}

PVC 如何去寻找匹配pv,这通常通过pvc.spec.selector 查询到pv 列表,然后通过pvc.spec.accessModes 与 pvc.spec.resources 来判定pv.spec.accessModes 与 pv.spec.capaticy 是否满足条件,若满足则进行绑定操作,pv的状态变为bound

PVC 应用于pod 存储

kind: Pod

apiVersion: v1

metadata:

  name: mypod

spec:

  containers:

    - name: myfrontend

      image: dockerfile/nginx

      volumeMounts:

      - mountPath: "/var/www/html"

        name: mypd

  volumes:

    - name: mypd

      persistentVolumeClaim:

        claimName: myclaim

 

 

 

 

Configmap

在执行应用程式或是生产环境等等, 会有许多的情况需要做变更, 而我们不希望因应每一种需求就要准备一个镜像档, 这时就可以透过 ConfigMap 来帮我们做一个配置档或是命令参数的映射, 更加弹性化使用我们的服务或是应用程式。

ConfigMap 用于保存配置数据的键值对,可以用来保存单个属性,也可以用来保存配置文件

创建configmap

使用命令:kubectl create configmap special-config --from-file=config/

apiVersion: v1

kind: ConfigMap

metadata:

  name: special-config

  namespace: default

data:

  special.how: very

  special.type: charm

configmap应用于pod 存储

apiVersion: v1

kind: Pod

metadata:

  name: vol-test-pod

spec:

  containers:

    - name: test-container

      image: gcr.io/google_containers/busybox

      command: ["/bin/sh", "-c", "cat /etc/config/special.how"]

      volumeMounts:

      - name: config-volume

        mountPath: /etc/config

  volumes:

    - name: config-volume

      configMap:

        name: special-config

  restartPolicy: Never

将config内的文件挂载到/etc/config目录下,

secret

Secret 解决了密码、token、**等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者 Pod Spec 中。Secret 可以以 Volume 或者环境变量的方式使用。

Secret 有三种类型:

  • Opaque:base64 编码格式的 Secret,用来存储密码、**等;但数据也通过 base64 --decode 解码得到原始数据,所以加密性很弱。
  • kubernetes.io/dockerconfigjson:用来存储私有 docker registry 的认证信息。
  • kubernetes.io/service-account-token: 用于被 serviceaccount 引用。serviceaccout 创建时 Kubernetes 会默认创建对应的 secret。Pod 如果使用了 serviceaccount,对应的 secret 会自动挂载到 Pod 的 /var /run/secrets/kubernetes.io/serviceaccount目录中。

secret yaml

apiVersion: v1

kind: Secret

metadata:

  name: mysecret

type: Opaque

data:

  password: MWYyZDFlMmU2N2Rm

  username: YWRtaW4=

 

 

 

 

secret应用pod存储

apiVersion: v1

kind: Pod

metadata:

  labels:

    name: db

  name: db

spec:

  volumes:

  - name: secrets

    secret:

      secretName: mysecret

  containers:

  - image: gcr.io/my_project_id/pg:v1

    name: db

    volumeMounts:

    - name: secrets

      mountPath: "/etc/secrets"

      readOnly: true

    ports:

    - name: cp

      containerPort: 5432

      hostPort: 5432