自学k8s系列~04之Pod

Pod是什么

  • PodK8s 的最小运行单元。
  • 是所有应用的载体,包含一个或多个容器(这里的容器可以不是 Docker)。

Pod 定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
apiVersion: v1              //需要
kind: Pod //需要
metadata: //需要
name: string //需要
namaspace: string //需要
labels:
- name: string
annotations:
- name: string
spec: //需要
containers: //需要
- name: string //需要
image: string //需要
imagePullPolice: [Always | Never | IfNotPresent]
command: [string]
args: [string]
workingDir: string
volumeMounts:
- name: string
mountPath: string
readOnly: boolean
ports:
- name: string
containerPort: int
hostPort: int
protocol: string
env:
- name: string
value: string
resources:
limits:
cpu: string
memory: string
requests:
cpu: string
memory: string
livenessProbe:
exec:
command: [string]
httpGet:
path: string
port: int
host: string
scheme: string
httpHeaders:
- name: string
value: string
tcpSocket:
port: int
initialDelaySeconds: number
timeoutSeconds: number
periodSeconds: number
successThreshold: 0
failureThreshold: 0
securityContext:
privileged: false
RestartPolicy: [Always | Never | OnFailure]
nodeSelector: object
imagePullSecrets:
- name: string
hostNetwork: false
volumes:
- name: string
emptyDir: {}
hostPath:
path: string
secret:
secretName: string
items:
- key: string
path: string
configMap:
name: string
items:
- key: string
path: string

Pod 的基本操作

Pod 等于 Docker 吗?答案是不等于。Docker 运行在 Pod 中,但是 Pod 可以运行的不仅仅是 Docker, 其他容器也可以。比如: RKT 或者 Podman 都可以在 Pod 中运行。其次,Pod 中的容器也可以有多少。这一点类似于 Docker 中的容器互联。

Pod 创建

Pod 的主程序需要一直处于前台运行的状态,否则 Pod 就会将期销毁,这一点跟 Docker 很像。例如: 执行的是

1
nohup ./start.sh &

Pod 在执行完该命令后,就会将 Pod 销毁。而我们的目的是期望能够后台运行,这就违背了我们的目的。正确做法

1
./start.sh

这样该应用就会一直前台运行, Pod 就会一直存在。

  • 命令方式
1
2
# 创建 Pod 指定 namespace 名称为 sjl
kubectl create pod podName -n sjl
  • yaml 方式
1
2
3
4
5
6
7
apiVersion: v1
kind: Pod
metadata:
name: podName
namespace: sjl
spec:
image: nginx:1.19.7

Pod 状态查看

1
2
3
4
5
# 查看所有的 pod
kubectl get pods

# 查看指定 name 的 pod
kubectl get pod podName

Pod 更新

1
kubectl replace pod

Pod 删除

1
kubectl delete pod podName

查看Pod解析

1
2
# 查看指定 name 的 pod
kubectl get pod podName

Pod 显示的内容如下

1
2
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-59f854fb7c-vlkhj 1/1 Running 1 2d23h

NAME

POD 的名称。

READY

显示 Pod 的容器信息,以 / 分隔成左右两边,左边是就绪的容器,右边是 Pod 包含的总容器。一般是一个 Pod 一个容器,但是也是例外的情况,一个 Pod 包含多个容器。

STATUS

当前 Pod 的状态。

RESTARTS

Pod 的重启次数。

AGE

Pod 的运行时间。

Pod与容器

Pod与容器

在 k8s 中, Pod 是最小的单元体。 Pod 中可以运行一个或多个容器,这个容器可以是 Docker 也可以是其他容器。当然,我们最常用的还是 Docker 容器。

镜像

Pod 被高度到某一台 Node 后,会下载对应的镜像,镜像版本等信息由 image 指定,具体的镜像下载策略

k8s 中的镜像下载策略由 imagePullPolice 指定,下载策略包含以下三种:

1
imagePullPolice: [Always | Never | IfNotPresent]

Always

每次都下载最新镜像。

Never

只使用本地镜像,不下载。

IfNotPresent

当本地没有时,才下载新镜像。

Pod共享Volume

部署 Pod yaml 配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
apiVersion: v1
kind: Pod
metadata:
name: volume-pod
spec:
containers:
- name: tomcat
image: tomcat:9.0.0
ports:
- containerPort: 8080
volumeMounts:
- name: app-logs
mountPath: /usr/local/tomcat/logs
- name: busybox
image: busybox
command: ["sh", "-c", "tail -f /logs/catalina*.log"]
volumeMounts:
- name: app-logs
mountPath: /logs
volumes:
- name: app-logs
emptyDir: {}
1
//todo 实验未成功, pod 没有正常启动。

Pod的配置管理

ConfigMap

kubernetes 提供了一种统一的配置管理方案——ConfigMap

ConfigMap 的常用方式:

  • 生成为容器内的环境变量。
  • 设置容器的启动命令启动参数(需要设置为环境变量)。
  • Volume 的形式挂载为容器内的文件或目录。

ConfigMap的保存形式

  • key: value
  • vlue 可以是一个完整的配置文件

ConfigMap的创建

1
2
3
4
5
6
apiVersion: v1
kind: ConfigMap
metadata:
name: pod-configmap
data:
key: zhangsan

执行命令

1
kubectl apply -f ./pod_configmap.yaml

查看ConfigMap

  • 查看 ConfigMap
1
kubectl get configmap

展示内容

1
2
3
NAME               DATA   AGE
kube-root-ca.crt 1 175d
pod-configmap 1 7m54s
  • 查看 ConfigMap 详情信息
1
kubectl describe configmap pod-configmap

展示内容

1
2
3
4
5
6
7
8
9
10
11
Name:         pod-configmap
Namespace: default
Labels: <none>
Annotations: <none>

Data
====
key:
----
张三
Events: <none>

在Pod中使用ConfigMap

  • ConfigMap
1
2
3
4
5
6
7
apiVersion: v1
kind: ConfigMap
metadata:
name: cm-appvars
data:
apploglevel: INFO
appdatadir: /var/data
  • Pod
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
apiVersion: v1
kind: Pod
metadata:
name: pod-configmap-apply
spec:
containers:
- name: pod-configmap-apply
image: busybox
command: ["/bin/sh", "-c", "env|grep APP"] #启动时执行该命令
env:
- name: APPLOGLEVEL #定义环境变量的名称
valueFrom:
configMapKeyRef:
name: cm-appvars #环境变量的值取自 cm-appvars
key: apploglevel #取的 key 为 apploglevel
- name: APPDATADIR #定义 APPDATADIR 环境变量
valueFrom:
configMapKeyRef:
name: cm-appvars #环境变量的值取自 cm-appvars
key: appdatadir #取的 key 为 appdatadir
restartPolicy: Never
  • 创建 ConfigMap 和 Pod
1
2
3
4
# 创建 ConfigMap
kubectl apply -f ./pod_configmap.yaml
# 创建 Pod
kubectl apply -f ./pod_configmap_apply.yaml
  • 查看日志
1
2
3
4
5
6
7
8
9
10
11
# 查看 Pod
kubectl get pods

NAME READY STATUS RESTARTS AGE
pod-configmap-apply 0/1 Completed 0 7m32s

# 查看 Pod 名为 pod-configmap-apply 的日志
kubectl logs pod-configmap-apply

APPDATADIR=/var/data
APPLOGLEVEL=INFO

使用 envFrom 创建环境变量

  • 使用 envFrom 创建 Pod
1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: v1
kind: Pod
metadata:
name: pod-configmap-apply-envfrom
spec:
containers:
- name: cm-test
image: busybox
command: ["/bin/sh", "-c", "env"]
envFrom:
- configMapRef:
name: cm-appvars
restartPolicy: Never
  • 启动 Pod
1
kubectl apply -f ./pod_configmap_apply_envfrom.yaml
  • 查看 Pod 日志
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
kubectl logs pod-configmap-apply-envfrom

# 在显示的内容中可以看到,我们在 ConfigMap 中设置的两个变量 apploglevel 和 appdatadir 已经加入进来了
apploglevel=INFO
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.96.0.1:443
HOSTNAME=pod-configmap-apply-envfrom
SHLVL=1
HOME=/root
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
appdatadir=/var/data
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_SERVICE_HOST=10.96.0.1
PWD=/

通过Volume使用ConfigMap

  • ConfigMap 配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
apiVersion: v1
kind: ConfigMap
metadata:
name: pod-configmap-volume
data:
# 在 applicationContextXml 放的是整个 xml 文件的配置
applicationContextXml: |
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"
default-autowire="byName">
<!--
注意上面的default-autowire="byName",如果没有这个声明不会被注入
-->

<description>Spring-database配置</description>

<bean id="aliyunIntranetStorage" class="com.olymtech.aliyun.client.oss.AliyunStorageImpl">
<property name="accessID" value="${oss.accessID}"/>
<property name="accessKey" value="${oss.accessKey}"/>
<property name="ossEndpoint" value="${oss.ossIntranetEndpoint}"/>
<property name="bucketName" value="${oss.bucketName}"/>
</bean>
<bean id="aliyunStorage" class="com.olymtech.aliyun.client.oss.AliyunStorageImpl">
<property name="accessID" value="${oss.accessID}"/>
<property name="accessKey" value="${oss.accessKey}"/>
<property name="ossEndpoint" value="${oss.ossEndpoint}"/>
<property name="bucketName" value="${oss.bucketName}"/>
</bean>

<bean id="ediAliyunIntranetStorage" class="com.olymtech.aliyun.client.oss.AliyunStorageImpl">
<property name="accessID" value="${oss-edi.accessID}"/>
<property name="accessKey" value="${oss-edi.accessKey}"/>
<property name="ossEndpoint" value="${oss-edi.ossIntranetEndpoint}"/>
<property name="bucketName" value="${oss-edi.bucketName}"/>
</bean>
<bean id="ediAliyunStorage" class="com.olymtech.aliyun.client.oss.AliyunStorageImpl">
<property name="accessID" value="${oss-edi.accessID}"/>
<property name="accessKey" value="${oss-edi.accessKey}"/>
<property name="ossEndpoint" value="${oss-edi.ossEndpoint}"/>
<property name="bucketName" value="${oss-edi.bucketName}"/>
</bean>
</beans>

  • Pod 配置
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: pod-configmap-volume-apply # 指定Pod名称
spec:
containers:
- name: pod-configmap-volume-apply # 容器名称
image: tomcat #指定容器镜像
ports:
- containerPort: 8080
volumeMounts: #配置挂载
- name: applicationcontextxml #x
mountPath: /configfiles
volumes:
- name: applicationcontextxml
configMap:
name: pod-configmap-volume
items:
- key: applicationContextXml
path: applicationContext.xml
  • 验证结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 部署 ConfigMap
kubectl apply -f ./pod_configmap_volume.yaml
# 部署 Pod
kubectl apply -f ./pod_configmap_volume_apply.yaml
# 查看日志
kubectl get pods

NAME READY STATUS RESTARTS AGE
pod-configmap-volume-apply 1/1 Running 0 4m49s

# 如果 READY 是 0/1 多执行几次 kubectl get pos, pod 还没启动成功

# 进入 pod 查看目录
kubectl exec -it pod-configmap-volume-apply -- bash

# 前面是进入 pod 的默认目录,而配置挂载在 / 目录下
root@pod-configmap-volume-apply:/usr/local/tomcat# ls /
bin boot configfiles dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
#可以看到,有一个 configfiles 目录

#进入 configfiles 查看是否存在 applicationContext.xml
root@pod-configmap-volume-apply:/usr/local/tomcat# cd /configfiles/

root@pod-configmap-volume-apply:/configfiles# ls
applicationContext.xml
# 可以看到,出现了 applicationContext.xml

root@pod-configmap-volume-apply:/configfiles# cat applicationContext.xml
# 查看 applicationContext.xml 的内容

Pod的生命周期和重启策略

Pod的生命周期

Pod 的生命周期被定义为各种状态, Pod 的状态有五种分别是:PendingRunningSuccessedFailedUnknown

状态 描述
Pending 等待,Pod 已经创建,但是Pod内的容器或者镜像还没创建。
Running 运行中,Pod 内所有容器均已创建,正在运行中。
Successed 执行成功,该状态表示 Pod 已经执行成功并退出,且不会重启容器。
Failed 执行失败,该状态表示 Pod 已经退出,但是至少有一个容器为失败状态。
Unknown 未知,无法获取到 Pod 的正确状态,这种情况一般是网络故障。

Pod的重启策略

Pod 的重启策略应用于 Pod 内的所有容器,并且仅在 Pod 所处的 Node 上由 kubelet 进行判断和重启操作。当某个容器异常退出或者健康检查失败时,kubelet 将根据 RestartPolicy 配置的重启策略进行相应的处理。

Pod 的重启策略主要有三种,分别是: AlwaysOnFailureNever

配置值 描述
Always 当容器失效时,由 kubelet 自动重启该容器。默认值
OnFailure 当容器终止运行,且退出状态码不为 0 时, kubelet 自动重启该容器。
Never 无论处于何种状态,kubelet 都不会重启该容器。
1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: v1
kind: Pod
metadata:
name: pod-configmap-apply-envfrom
spec:
containers:
- name: cm-test
image: busybox
command: ["/bin/sh", "-c", "env"]
envFrom:
- configMapRef:
name: cm-appvars
restartPolicy: Never #手动配置该 Pod 的重启策略为 Never

Pod 的健康检查,扩缩容,滚动更新以及回滚后面再专门的记录。