K8S Pod

Pod是Kubernetes创建或部署的最小单位。一个Pod封装一个或多个容器(container)、存储资源(volume)、一个独立的网络IP以及管理控制容器运行方式的策略选项。

Pod使用主要分为两种方式:

  • Pod中运行一个容器。这是Kubernetes最常见的用法,Kubernetes是直接管理Pod而不是容器。
  • Pod中运行多个需要耦合在一起工作、需要共享资源的容器。通常这种场景下应用包含一个主容器和几个辅助容器(SideCar Container),例如主容器为一个web服务器,从一个固定目录下对外提供文件服务,而辅助容器周期性的从外部下载文件存到这个固定目录下。

实际很少直接创建Pod,而是使用Kubernetes中称为Controller的抽象层来管理Pod实例,例如Deployment和Job。Controller可以创建和管理多个Pod,提供副本管理、滚动升级和自愈能力。通常,Controller 会使用Pod Template来创建相应的Pod。

创建Pod

如下示例描述了一个名为nginx的Pod,这个Pod中包含一个名为container-0的容器,使用nginx:alpine镜像,使用的资源为100m core CPU、200Mi内存。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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

YAML描述文件主要为如下部分:

  1. metadata:一些名称/标签/namespace等信息。
  2. spec:Pod实际的配置信息,包括使用什么镜像,volume等。

Pod定义好后就可以使用kubectl创建,如果上面YAML文件名称为nginx.yaml,则创建命令如下所示,-f表示使用文件方式创建。

1
2
3
4
5
6
7
8
$ 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

使用kubectl get命令查询具体Pod的配置信息,如下所示,-o yaml表示以YAML格式返回,还可以使用-o json,以JSON格式返回。

1
$ kubectl get pod nginx -o yaml

您还可以使用kubectl describe命令查看Pod的详情。

1
$ kubectl describe pod nginx

删除pod时,Kubernetes终止Pod中所有容器。 Kubernetes向进程发送SIGTERM信号并等待一定的秒数(默认为30)让容器正常关闭。如果它没有在这个时间内关闭,Kubernetes会发送一个SIGKILL信号杀死该进程。 Pod的停止与删除有多种方法,比如按名称删除,如下所示。

1
2
$ kubectl delete po nginx
pod "nginx" deleted

同时删除多个Pod。

1
$ kubectl delete po pod1 pod2

删除所有Pod。

1
2
$ kubectl delete po --all
pod "nginx" deleted

根据Label删除Pod,Label详细内容将会在下一个章节介绍。

1
2
$ kubectl delete po -l app=nginx
pod "nginx" deleted

使用环境变量

环境变量是容器运行环境中设定的一个变量。 环境变量的使用方法如下所示,配置spec.containers.env字段即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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

执行如下命令查看容器中的环境变量,可以看到env_key这个环境变量,其值为env_value。

1
2
3
4
5
$ 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

容器启动命令

启动容器就是启动主进程,但有些时候,启动主进程前,需要一些准备工作。比如MySQL类的数据库,可能需要一些数据库配置、初始化的工作,这些工作要在最终的MySQL服务器运行之前做完。这些操作,可以在制作镜像时通过在Dockerfile文件中设置ENTRYPOINT或CMD来完成,如下所示的Dockerfile中设置了ENTRYPOINT [“top”, “-b”]命令,其将会在容器启动时执行。
实际使用时,只需配置Pod的containers.command参数,该参数是list类型,第一个参数为执行命令,后面均为命令的参数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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"

容器的生命周期

Kubernetes提供了容器生命周期钩子,在容器的生命周期的特定阶段执行调用,比如容器在停止前希望执行某项操作,就可以注册相应的钩子函数。目前提供的生命周期钩子函数如下所示。

启动后处理(PostStart):容器启动后触发。
停止前处理(PreStop):容器停止前触发。
实际使用时,只需配置Pod的lifecycle.postStart或lifecycle.preStop参数,如下所示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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"

Label

Label的具体形式是key-value的标记对,可以在创建资源的时候设置,也可以在后期添加和修改。

  • 添加Label
    Label的形式为key-value形式,使用非常简单,如下,为Pod设置了app=nginx和env=prod两个Label。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels: # 为Pod设置两个Label
app: nginx
env: prod
spec:
containers:
- image: nginx:alpine
name: container-0
resources:
limits:
cpu: 100m
memory: 200Mi
requests:
cpu: 100m
memory: 200Mi
imagePullSecrets:
- name: default-secret

Pod有了Label后,在查询Pod的时候带上–show-labels就可以看到Pod的Label。

1
2
3
$ kubectl get pod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx 1/1 Running 0 50s app=nginx,env=prod
  • 修改Label
1
2
$ kubectl label pod nginx env=debug --overwrite
pod/nginx labeled