zoukankan      html  css  js  c++  java
  • Kubernetes Pod概述

    Pod简介

    Pod是Kubernetes创建或部署的最小/最简单的基本单位,一个Pod代表集群上正在运行的一个进程。
    一个Pod封装一个应用容器,Pod代表部署的一个单位。
    Pods提供两种共享资源:网络和存储。
    网络:每个Pod被分配一个独立的IP地址,Pod中的每个容器共享网络命名空间,包括IP地址和网络端口。
    存储:Pod可以指定一组共享存储volumes。Pod中的所有容器都可以访问共享volumes,允许这些容器共享数据。
    Pod不会自愈。如果Pod运行的Node故障,或者是调度器本身故障,这个Pod就会被删除。同样的,如果Pod所在Node缺少资源或者Pod处于维护状态,Pod也会被驱逐。Controller可以创建和管理多个Pod,提供副本管理、滚动升级和集群级别的自愈能力。例如,如果一个Node故障,Controller就能自动将该节点上的Pod调度到其他健康的Node上。

    POD生命周期

    Pod 的 status 定义在 PodStatus 对象中,其中有一个 phase 字段。

    • 挂起(Pending):Pod 已被 Kubernetes 系统接受,但有一个或者多个容器镜像尚未创建。等待时间包括调度 Pod 的时间和通过网络下载镜像的时间,这可能需要花点时间。
    • 运行中(Running):该 Pod 已经绑定到了一个节点上,Pod 中所有的容器都已被创建。至少有一个容器正在运行,或者正处于启动或重启状态。
    • 成功(Succeeded):Pod 中的所有容器都被成功终止,并且不会再重启。
    • 失败(Failed):Pod 中的所有容器都已终止了,并且至少有一个容器是因为失败终止。也就是说,容器以非0状态退出或者被系统终止。
    • 未知(Unknown):因为某些原因无法取得 Pod 的状态,通常是因为与 Pod 所在主机通信失败。

    容器存活探针,健康检查

    探针 是由 kubelet 对容器执行的定期诊断。要执行诊断,kubelet 调用由容器实现的 Handler。

    • ExecAction:在容器内执行指定命令。如果命令退出时返回码为 0 则认为诊断成功。
    • TCPSocketAction:对指定端口上的容器的 IP 地址进行 TCP 检查。如果端口打开,则诊断被认为是成功的。
    • HTTPGetAction:对指定的端口和路径上的容器的 IP 地址执行 HTTP Get 请求。如果响应的状态码大于等于200 且小于 400,则诊断被认为是成功的。

    livenessProbe:探测应用是否处于健康状态,如果不健康则删除重建改容器
    readinessProbe:探测应用是否启动完成并且处于正常服务状态,如果不正常则更新容器的状态

    apiVersion: v1
    kind: Pod
    metadata:
      labels:
        app: nginx
      name: nginx
    spec:
        containers:
        - image: nginx
          imagePullPolicy: Always
          name: http
          livenessProbe:
            httpGet:
            path: /
            port: 80
            initialDelaySeconds: 15
            timeoutSeconds: 1
          readinessProbe:
            httpGet:
            path: /ping
            port: 80
            initialDelaySeconds: 5
            timeoutSeconds: 1
    

    诊断结果状态:

    • 成功:容器通过了诊断。
    • 失败:容器未通过诊断。
    • 未知:诊断失败,因此不会采取任何行动。

    初始化容器

    Init Container在所有容器运行之前执行(run-to-completion),常用来初始化配置。

    apiVersion: v1
    kind: Pod
    metadata:
      name: init-demo
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
        volumeMounts:
        - name: workdir
          mountPath: /usr/share/nginx/html
      # These containers are run during pod initialization
      initContainers:
      - name: install
        image: busybox
        command:
        - wget
        - "-O"
        - "/work-dir/index.html"
        - http://kubernetes.io
        volumeMounts:
        - name: workdir
          mountPath: "/work-dir"
      dnsPolicy: Default
      volumes:
      - name: workdir
        emptyDir: {}
    

    重启策略

    PodSpec 中有一个 restartPolicy 字段,可能的值为 Always、OnFailure 和 Never。默认为 Always,意味着容器在探测失败时被杀死并重新启动。

    • Always:只要退出就重启
    • OnFailure:失败退出(exit code不等于0)时重启
    • Never:只要退出就不再重启

    这里的重启是指在Pod所在Node上面本地重启,并不会调度到其他Node上去。

    ImagePullPolicy

    支持三种ImagePullPolicy

    • Always:不管镜像是否存在都会进行一次拉取。
    • Never:不管镜像是否存在都不会进行拉取
    • IfNotPresent:只有镜像不存在时,才会进行镜像拉取。
      注意:
    • 默认为IfNotPresent,但:latest标签的镜像默认为Always。
    • 拉取镜像时docker会进行校验,如果镜像中的MD5码没有变,则不会拉取镜像数据。
    • 生产环境中应该尽量避免使用:latest标签,而开发环境中可以借助:latest标签自动拉取最新的镜像。

    指定Node部署

    通过nodeSelector,一个Pod可以指定它所想要运行的Node节点。
    首先给Node加上标签:

    $ kubectl label nodes <your-node-name> disktype=ssd
    

    接着,指定该Pod只想运行在带有disktype=ssd标签的Node上:

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx
      labels:
        env: test
    spec:
      containers:
      - name: nginx
        image: nginx
        imagePullPolicy: IfNotPresent
      nodeSelector:
        disktype: ssd
    

    给容器和Pod分配内存资源

    配置内存申请和限制

    memory-request-limit.yaml

    apiVersion: v1
    kind: Pod
    metadata:
      name: memory-demo
    spec:
      containers:
      - name: memory-demo-ctr
        image: vish/stress
        resources:
          limits:
            memory: "200Mi"
          requests:
            memory: "100Mi"
        args:
        - -mem-total
        - 150Mi
        - -mem-alloc-size
        - 10Mi
        - -mem-alloc-sleep
        - 1s
    

    创建一个容器的Pod,这个容器申请100M的内存,并且内存限制设置为200M,args代码段提供了容器所需的参数。-mem-total 150Mi告诉容器尝试申请150M 的内存。
    在mem-example命名空间中创建pod:

    # kubectl create -f memory-request-limit.yaml --namespace=mem-example
    

    验证Pod的容器是否正常运行:

    # kubectl get pod memory-demo --namespace=mem-example
    

    查看Pod的详细信息:

    # kubectl get pod memory-demo --output=yaml --namespace=mem-example
    -----------------
    ...
    resources:
      limits:
        memory: 200Mi
      requests:
        memory: 100Mi
    ...
    

    POD实际使用内存约为150M。
    删除Pod:

    # kubectl delete pod memory-demo --namespace=mem-example
    

    当创建POD时内存超出限制内存,则POD会被kill掉,reason: OOMKilled。
    当创建POD时内存超出节点能力范围时,Pod的状态是Pending,因为Pod不会被调度到任何节点,它会一直保持在Pending状态下,因为节点上没有足够的内存。
    如果没有内存限制,则容器使用内存资源没有上限,容器可以使用当前节点上所有可用的内存资源。

    给容器和Pod分配CPU资源

    给容器声明CPU限制

    cpu-request-limit.yaml

    apiVersion: v1
    kind: Pod
    metadata:
      name: cpu-demo
    spec:
      containers:
      - name: cpu-demo-ctr
        image: vish/stress
        resources:
          limits:
            cpu: "1"
          requests:
            cpu: "0.5"
        args:
        - -cpus
        - "2"
    

    会创建一个只有一个容器的Pod,这个容器申请0.5个CPU,并且CPU限制设置为1. cpus "2"代码告诉容器尝试使用2个CPU资源。
    在cpu-example命名空间中创建pod:

    # kubectl create -f cpu-request-limit.yaml --namespace=cpu-example
    

    验证Pod的容器是否正常运行:

    # kubectl get pod cpu-demo --namespace=cpu-example
    

    查看Pod的详细信息:

    # kubectl get pod cpu-demo --output=yaml --namespace=cpu-example
    --------------
    resources:
      limits:
        cpu: "1"
      requests:
        cpu: 500m
    

    当创建的pod申请的CPU资源超过集群node所提供的资源,那么pod会一直处于Pending状态,那是因为这个Pod并不会被调度到任何节点上,所以它会一直保持这种状态。
    如果你指定容器的CPU限额,则容器使用CPU资源没有上限,它可以使用它运行的Node上所有的CPU资源。

    通过环境变量向容器暴露 Pod 信息

    使用 Pod 字段作为环境变量的值

    dapi-envars-pod.yaml

    apiVersion: v1
    kind: Pod
    metadata:
      name: dapi-envars-fieldref
    spec:
      containers:
        - name: test-container
          image: k8s.gcr.io/busybox
          command: [ "sh", "-c"]
          args:
          - while true; do
              echo -en '
    ';
              printenv MY_NODE_NAME MY_POD_NAME MY_POD_NAMESPACE;
              printenv MY_POD_IP MY_POD_SERVICE_ACCOUNT;
              sleep 10;
            done;
          env:
            - name: MY_NODE_NAME
              valueFrom:
                fieldRef:
                  fieldPath: spec.nodeName
            - name: MY_POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: MY_POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
            - name: MY_POD_IP
              valueFrom:
                fieldRef:
                  fieldPath: status.podIP
            - name: MY_POD_SERVICE_ACCOUNT
              valueFrom:
                fieldRef:
                  fieldPath: spec.serviceAccountName
      restartPolicy: Never
    

    env 字段是 EnvVars 的数组。数组中的第一个元素指定 MY_NODE_NAME 环境变量从 Pod 的 spec.nodeName 字段中获取其值。字段是 Pod 的字段,不是 Pod 中的容器的字段。
    创建pod:

    # kubectl create -f dapi-envars-pod.yaml
    

    查看容器日志:

    # kubectl logs dapi-envars-fieldref
    -------------
    minikube
    dapi-envars-fieldref
    default
    172.17.0.48
    default
    

    配置文件的 command 和 args 字段。当容器启动时,它将 5 个环境变量的值写到标准输出中。每十秒钟重复一次。
    进入容器内查看环境变量:

    MY_POD_SERVICE_ACCOUNT=default
    ...
    MY_POD_NAMESPACE=default
    MY_POD_IP=172.17.0.4
    ...
    MY_NODE_NAME=minikube
    ...
    MY_POD_NAME=dapi-envars-fieldref
    

    使用容器字段作为环境变量的值

    dapi-envars-container.yaml

    apiVersion: v1
    kind: Pod
    metadata:
      name: dapi-envars-resourcefieldref
    spec:
      containers:
        - name: test-container
          image: k8s.gcr.io/busybox:1.24
          command: [ "sh", "-c"]
          args:
          - while true; do
              echo -en '
    ';
              printenv MY_CPU_REQUEST MY_CPU_LIMIT;
              printenv MY_MEM_REQUEST MY_MEM_LIMIT;
              sleep 10;
            done;
          resources:
            requests:
              memory: "32Mi"
              cpu: "125m"
            limits:
              memory: "64Mi"
              cpu: "250m"
          env:
            - name: MY_CPU_REQUEST
              valueFrom:
                resourceFieldRef:
                  containerName: test-container
                  resource: requests.cpu
            - name: MY_CPU_LIMIT
              valueFrom:
                resourceFieldRef:
                  containerName: test-container
                  resource: limits.cpu
            - name: MY_MEM_REQUEST
              valueFrom:
                resourceFieldRef:
                  containerName: test-container
                  resource: requests.memory
            - name: MY_MEM_LIMIT
              valueFrom:
                resourceFieldRef:
                  containerName: test-container
                  resource: limits.memory
      restartPolicy: Never
    

    env 字段是 EnvVars 的数组。数组中的第一个元素指定 MY_CPU_REQUEST 环境变量从名为 test-container 的容器的 requests.cpu 字段中获取其值。类似地,其他环境变量从容器字段中获取它们的值。
    创建pod,查看pod日志:

    # kubectl create -f dapi-envars-container.yaml
    # kubectl logs dapi-envars-resourcefieldref
    --------------
    1
    1
    33554432
    67108864
    
  • 相关阅读:
    Socket编程
    jdbc03 使用servlet实现
    el和jstl
    java03变量和基本数据类型
    java02
    ssh整合
    U1总结
    多线程
    spring07 JDBC
    cocos2dx中的三种基本的数据类型
  • 原文地址:https://www.cnblogs.com/aresxin/p/Kubernetes-Pod.html
Copyright © 2011-2022 走看看