基本介绍

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

Pod特征

  • 包含多个共享 IPC、Network 和 UTC namespace 的容器,可直接通过 localhost 通信
  • 所有 Pod 内容器都可以访问共享的 Volume,可以访问共享数据
  • 无容错性:直接创建的 Pod 一旦被调度后就跟 Node 绑定,即使 Node 挂掉也不会被重新调度(而是被自动删除),因此推荐使用 Deployment、Daemonset 等控制器来容错
  • 优雅终止:Pod 删除的时候先给其内的进程发送 SIGTERM,等待一段时间(grace period)后才强制停止依然还在运行的进程
  • 特权容器(通过 SecurityContext 配置)具有改变系统配置的权限

Pod 状态

k8s以 PodStatus.Phase 抽象 Pod 的状态(但并不直接反映所有容器的状态)。可能的 Phase 包括

  • Pending: API Server已经创建该Pod,但一个或多个容器还没有被创建,包括通过网络下载镜像的过程
  • Running: Pod中的所有容器都已经被创建且已经调度到 Node 上面,但至少有一个容器还在运行或者正在启动。
  • Succeeded: Pod 调度到 Node 上面后均成功运行结束,并且不会重启。
  • Failed: Pod中的所有容器都被终止了,但至少有一个容器退出失败(即退出码不为 0 或者被系统终止)。
  • Unknonwn: 状态未知,因为一些原因Pod无法被正常获取,通常是由于 apiserver 无法与 kubelet 通信导致。

可以用 kubectl 命令查询 Pod Phase,如下:

[root@node162 ~]# kubectl get po test -o jsonpath="{.status.phase}"
Running
[root@node162 ~]# 

PodrestartPolicy

PodSpec 中的 restartPolicy 可以用来设置是否对退出的 Pod 重启,如下:

  • Always:当容器失效时,由Kubelet自动重启该容器。RestartPolicy的默认值。
  • OnFailure:当容器终止运行且退出码不为0时由Kubelet重启。
  • Never:无论何种情况下,Kubelet都不会重启该容器。

设置 Pod 的 hostname

通过 spec.hostname 参数实现,如果未设置默认使用 metadata.name 参数的值作为 Pod 的 hostname。

apiVersion: v1
kind: Pod
metadata:
  name: test
  labels:
    name: test
spec:
  hostname: test   ###设置pod 名称为test
  containers:
  - image: nginx
    command: ["init"]
    name: nginx:latest

Pod健康检查

为了确保容器在部署后确实处在正常运行状态,Kubernetes 提供了两种探针(Probe)来探测容器的状态:

  • LivenessProbe:探测应用是否处于健康状态,如果不健康则删除并重新创建容器。
  • ReadinessProbe:探测应用是否启动完成并且处于正常服务状态,如果不正常则不会接收来自 Kubernetes Service 的流量,即将该Pod从Service的endpoint中移除。
    k8s支持三种方式来执行探针:
  • exec:在容器中执行一个命令,如果 命令退出码 返回 0 则表示探测成功,否则表示失败
  • tcpSocket:对指定的容器 IP 及端口执行一个 TCP 检查,如果端口是开放的则表示探测成功,否则表示失败
  • httpGet:对指定的容器 IP、端口及路径执行一个 HTTP Get 请求,如果返回的 状态码[200,400) 之间则表示探测成功,否则表示失败
apiVersion: v1
kind: Pod
metadata:
  labels:
    app: nginx
  name: nginx
spec:
    containers:
    - image: nginx
      imagePullPolicy: Always
      name: http
      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
    - name: goproxy
      image: gcr.io/google_containers/goproxy:0.1
      ports:
      - containerPort: 8080
      readinessProbe:
        tcpSocket:
          port: 8080
        initialDelaySeconds: 5
        periodSeconds: 10
      livenessProbe:
        tcpSocket:
          port: 8080
        initialDelaySeconds: 15
        periodSeconds: 20
        

容器生命周期钩子

容器生命周期钩子(Container Lifecycle Hooks)监听容器生命周期的特定事件,并在事件发生时执行已注册的回调函数。支持两种钩子:

  • postStart: 容器创建后立即执行,注意由于是异步执行,它无法保证一定在 ENTRYPOINT 之前运行。如果失败,容器会被杀死,并根据 RestartPolicy 决定是否重启
  • preStop:容器终止前执行,常用于资源清理。如果失败,容器同样也会被杀死
    而钩子的回调函数支持两种方式:
  • exec:在容器内执行命令,如果命令的退出状态码是 0 表示执行成功,否则表示失败
  • httpGet:向指定 URL 发起 GET 请求,如果返回的 HTTP 状态码在 [200, 400) 之间表示请求成功,否则表示失败
    postStart 和 preStop 钩子示例:
apiVersion: v1
kind: Pod
metadata:
  name: lifecycle-demo
spec:
  containers:
  - name: lifecycle-demo-container
    image: nginx
    lifecycle:
      postStart:
        httpGet:
          path: /
          port: 80
      preStop:
        exec:
          command: ["/usr/sbin/nginx","-s","quit"]

Pod自定义 hosts

默认情况下,容器的 /etc/hosts 是 kubelet 自动生成的,并且仅包含 localhost 和 podName 等。不建议在容器内直接修改 /etc/hosts 文件,因为在 Pod 启动或重启时会被覆盖。

默认的 /etc/hosts 文件格式如下,其中 eci-runc-block-deployment-fio 是 podName:

[root@eci-runc-block-deployment-fio /]# cat /etc/hosts
# Kubernetes-managed hosts file.
127.0.0.1	localhost
::1	localhost ip6-localhost ip6-loopback
fe00::0	ip6-localnet
fe00::0	ip6-mcastprefix
fe00::1	ip6-allnodes
fe00::2	ip6-allrouters
172.10.0.44	eci-runc-block-deployment-fio

可以通过 pod.Spec.HostAliases 来增加 hosts 内容,如

    spec:
      hostAliases:
      - ip: "10.224.1.100"
        hostnames:
        - "vip.test.com"

Pod 时区

很多容器都是默认的 UTC 时区,与集群的 Node 所在时区有可能不一致,可以通过 HostPath 存储插件给容器配置与 Node 一样的时区,如下:

apiVersion: v1
kind: Pod
metadata:
  name: time
spec:
  containers:
  - image: nginx:latest
    volumeMounts:
    - mountPath: /etc/localtime
      name: time
      readOnly: true
  volumes:
  - hostPath:
      path: /etc/localtime
      type: ""
    name: time
Logo

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

更多推荐