# Pod：Kubernetes中的最小调度对象
#### 介绍视频
<video controls="controls" preload="none" id="object785654211344" class="idp-external-video" src="https://res-video.hc-cdn.com/cloudbu-site/china/zh-cn/video/cce/pod1.mp4" title="Pod" poster="https://support.huaweicloud.com/basics-cce/zh-cn_image_0000002324253064.jpg" height="340.0000" width="600.0000"></video>
#### 容器组（Pod）
容器组（Pod）是Kubernetes创建或部署的最小单位。一个Pod封装一个或多个容器（Container）、存储资源（Volume）、一个独立的网络IP以及管理控制容器运行方式的策略选项。
Pod使用主要分为两种方式：
- Pod中运行一个容器。这是Kubernetes最常见的用法，您可以将Pod视为单个封装的容器，但是Kubernetes是直接管理Pod而不是容器。
- Pod中运行多个需要耦合在一起工作、需要共享资源的容器。通常这种场景下应用包含一个主容器和几个辅助容器（Sidecar Container），如[图1]所示，例如主容器为一个web服务器，从一个固定目录下对外提供文件服务，而辅助容器周期性的从外部下载文件存到这个固定目录下。
  图1Pod   
  ![](https://support.huaweicloud.com/basics-cce/zh-cn_image_0000002772910273.png) 
实际使用中很少直接创建Pod，而是使用Kubernetes中称为Controller的抽象层来管理Pod实例，例如Deployment和Job。Controller可以创建和管理多个Pod，提供副本管理、滚动升级和自愈能力。通常，Controller会使用Pod Template来创建相应的Pod。
#### 创建Pod
kubernetes中资源可以使用YAML描述（如果您对YAML格式不了解，可以参考[YAML语法](https://support.huaweicloud.com/devg-cci/cci_05_1001.html)），也可以使用JSON，如下示例描述了一个名为nginx的Pod，这个Pod中包含一个名为container-0的容器，使用nginx:alpine镜像，使用的资源为100m CPU、200Mi内存。
```
apiVersion: v1                      # Kubernetes的API Version
kind: Pod                           # Kubernetes的资源类型
metadata:
  name: nginx                       # Pod的名称
spec:                               # Pod的具体规格（specification）
  containers:
  - image: nginx:alpine             # 使用的镜像为 nginx:alpine
    name: container-0               # 容器的名称
    resources:                      # 申请容器所需的资源
      limits:
        cpu: 100m
        memory: 200Mi
      requests:
        cpu: 100m
        memory: 200Mi
  imagePullSecrets:                 # 拉取镜像使用的证书，在CCE上必须为default-secret
  - name: default-secret
```
如上面YAML的注释，YAML描述文件主要为如下部分：
- **metadata**：一些名称/标签/namespace等信息。
- **spec**：Pod实际的配置信息，包括使用什么镜像，volume等。
如果去查询Kubernetes的资源，您会看到还有一个**status**字段，status描述kubernetes资源的实际状态，创建时不需要配置。这个示例是一个最小集，其他参数定义后面会逐步介绍。
Pod定义好后就可以使用kubectl创建，如果上面YAML文件名称为nginx.yaml，则创建命令如下所示，-f表示使用文件方式创建。
```
$ kubectl create -f nginx.yaml
pod/nginx created
```
Pod创建完成后，可以使用kubectl get pods命令查询Pod的状态，如下所示。
```
$ kubectl get pods
NAME           READY   STATUS    RESTARTS   AGE
nginx          1/1     Running   0          40s
```
可以看到此处nginx这个Pod的状态为Running，表示正在运行；READY为1/1，表示这个Pod中有1个容器，其中1个容器的状态为Ready。
可以使用kubectl get命令查询具体Pod的配置信息，如下所示，-o yaml表示以YAML格式返回，还可以使用-o json，以JSON格式返回。
```
$ kubectl get pod nginx -o yaml
```
您还可以使用kubectl describe命令查看Pod的详情。
```
$ kubectl describe pod nginx
```
删除pod时，Kubernetes终止Pod中所有容器。 Kubernetes向进程发送SIGTERM信号并等待一定的秒数（默认为30）让容器正常关闭。如果它没有在这个时间内关闭，Kubernetes会发送一个SIGKILL信号终止该进程。
Pod的停止与删除有多种方法，比如按名称删除，如下所示。
```
$ kubectl delete po nginx
pod "nginx" deleted
```
同时删除多个Pod。
```
$ kubectl delete po pod1 pod2
```
删除所有Pod。
```
$ kubectl delete po --all
pod "nginx" deleted
```
根据Label删除Pod，[Label](https://support.huaweicloud.com/basics-cce/kubernetes_0011.html)详细内容将会在下一个章节介绍。
```
$ kubectl delete po -l app=nginx
pod "nginx" deleted
```
#### 使用环境变量
环境变量是容器运行环境中设定的一个变量。
环境变量为应用提供极大的灵活性，您可以在应用程序中使用环境变量，在创建容器时为环境变量赋值，容器运行时读取环境变量的值，从而做到灵活的配置，而不是每次都重新编写应用程序制作镜像。
环境变量的使用方法如下所示，配置spec.containers.env字段即可。
```
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
    containers:
    - image: nginx:alpine
      name: container-0
      resources:
        limits:
          cpu: 100m
          memory: 200Mi
        requests:
          cpu: 100m
          memory: 200Mi
      env:                            # 环境变量
      - name: env_key
        value: env_value
    imagePullSecrets:
    - name: default-secret
```
执行如下命令查看容器中的环境变量，可以看到env_key这个环境变量，其值为env_value。
```
$ kubectl exec -it nginx -- env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=nginx
TERM=xterm
env_key=env_value
```
环境变量还可以引用ConfigMap和Secret，具体使用方法请参见[在环境变量中引用ConfigMap](https://support.huaweicloud.com/basics-cce/kubernetes_0020.html#kubernetes_0020__section18458337406)和[在环境变量中引用Secret](https://support.huaweicloud.com/basics-cce/kubernetes_0021.html#kubernetes_0021__section66761159194018)。
#### 容器启动命令
启动容器就是启动主进程，但有些时候，启动主进程前，需要一些准备工作。比如MySQL类的数据库，可能需要一些数据库配置、初始化的工作，这些工作要在最终的MySQL服务器运行之前做完。这些操作，可以在制作镜像时通过在Dockerfile文件中设置ENTRYPOINT或CMD来完成，如下所示的Dockerfile中设置了**ENTRYPOINT \["top", "-b"\]**命令，其将会在容器启动时执行。
```
FROM ubuntu
ENTRYPOINT ["top", "-b"]
```
实际使用时，只需配置Pod的containers.command参数，该参数是list类型，第一个参数为执行命令，后面均为命令的参数。
```
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - image: nginx:alpine
    name: container-0
    resources:
      limits:
        cpu: 100m
        memory: 200Mi
      requests:
        cpu: 100m
        memory: 200Mi
    command:                     # 启动命令
    - top
    - "-b"
  imagePullSecrets:
   - name: default-secret
```
#### 容器的生命周期
Kubernetes提供了[容器生命周期钩子](https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/)，在容器的生命周期的特定阶段执行调用，比如容器在停止前希望执行某项操作，就可以注册相应的钩子函数。目前提供的生命周期钩子函数如下所示。
- 启动后处理（PostStart）：容器启动后触发。
- 停止前处理（PreStop）：容器停止前触发。
实际使用时，只需配置Pod的lifecycle.postStart或lifecycle.preStop参数，如下所示。
```
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - image: nginx:alpine
    name: container-0
    resources:
      limits:
        cpu: 100m
        memory: 200Mi
      requests:
        cpu: 100m
        memory: 200Mi
    lifecycle:
      postStart:                 # 启动后处理
        exec:
          command:
          - "/postStart.sh"
      preStop:                   # 停止前处理
        exec:
          command:
          - "/preStop.sh"
  imagePullSecrets:
   - name: default-secret
```
