集群中的所有资源可以提供如下方式查看:
kubectl api-resources
命名空间,集群内一个虚拟的概念,类似于资源池的概念,一个池子里可以有各种资源类型,绝大多数的资源都必须属于某一个 namespace。集群初始化安装好之后,会默认有如下几个 namespace:
[root@k8s-master ~]# kubectl get namespaces
NAME STATUS AGE
default Active 22h
kube-node-lease Active 22h
kube-public Active 22h
kube-system Active 22h
kubernetes-dashboard Active 21h
$ kubectl -h
$ kubectl get -h
$ kubectl create -h
$ kubectl create namespace -h
kubectl 如何管理集群资源
kubectl get po -v=7
为什么引入 pod
apiVersion: v1
kind: Pod
metadata:
name: myblog
namespace: demo
labels:
component: myblog
spec:
containers:
- name: myblog
image: 192.168.51.209:5000/myblog
env:
- name: MYSQL_HOST # 指定root用户的用户名
value: "127.0.0.1"
- name: MYSQL_PASSWD
value: "123456"
ports:
- containerPort: 8002
- name: mysql
image: 192.168.51.209:5000/mysql:5.7-utf8
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
value: "123456"
- name: MYSQL_DATABASE
value: "myblog"
apiVersion | 含义 |
---|---|
alpha | 进入 K8s 功能的早期候选版本,可能包含 Bug,最终不一定进入 K8s |
beta | 已经过测试的版本,最终会进入 K8s,但功能、对象定义可能会发生变更。 |
stable | 可安全使用的稳定版本 |
v1 | stable 版本之后的首个版本,包含了更多的核心对象 |
apps/v1 | 使用最广泛的版本,像 Deployment、ReplicaSets 都已进入该版本 |
资源类型与 apiVersion 对照表
快速获得资源和版本
$ kubectl explain pod
$ kubectl explain Pod.apiVersion
创建 namespace, namespace 是逻辑上的资源池
kubectl create namespace demo
使用指定文件创建 Pod
kubectl create -f demo-pod.yaml
查看 pod,可以简写 po
所有的操作都需要指定 namespace,如果是在 default 命名空间下,则可以省略
[root@k8s-master myblog]# kubectl -n demo get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
myblog 2/2 Running 0 2m12s 10.244.1.6 k8s-slave1 <none> <none>
进入容器,执行初始化, 不必到对应的主机执行 docker exec
[root@k8s-master myblog]# kubectl -n demo exec -ti myblog -c myblog bash
[root@myblog myblog]# env
[root@myblog myblog]# python3 manage.py migrate
[root@k8s-master myblog]# kubectl -n demo exec -ti myblog -c mysql bash
root@myblog:/# mysql -p123456
登录 k8s-slave1
节点
##其中包含 MySQL 和 myblog 程序以及 Infra 容器
##为了实现 Pod 内部的容器可以通过 localhost 通信,每个 Pod 都会启动 Infra 容器,然后 Pod 内部的其他容器的网络空间会共享该 Infra 容器的网络空间(Docker 网络的 container 模式),Infra 容器只需要 hang 住网络空间,不需要额外的功能,因此资源消耗极低。
登录 master 节点,查看 pod 内部的容器 ip 均相同,为 pod ip
[root@k8s-master myblog]# kubectl -n demo exec -ti myblog -c myblog bash
[root@myblog myblog]# ifconfig
pod 容器命名: k8s_<container_name>_<pod_name>_<namespace>_<random_string>
查看 pod 调度节点及 pod_ip
$ kubectl -n demo get pods -o wide
查看完整的 YAML
$ kubectl -n demo get po myblog -o yaml
查看 pod 的明细信息及事件
$ kubectl -n demo describe pod myblog
Troubleshooting and Debugging
进入 Pod 内的容器
$ kubectl -n <namespace> exec <pod_name> -c <container_name> -ti /bin/sh
查看 Pod 内容器日志,显示标准或者错误输出日志
$ kubectl -n <namespace> logs -f <pod_name> -c <container_name>
kubectl apply -f demo-pod.yaml
删除 Pod 服务
#根据文件删除
$ kubectl delete -f demo-pod.yaml
#根据 pod_name 删除
$ kubectl -n <namespace> delete pod <pod_name>
若删除了 Pod,由于 MySQL 的数据都在容器内部,会造成数据丢失,因此需要数据进行持久化。
apiVersion: v1
kind: Pod
metadata:
name: myblog
namespace: demo
labels:
component: myblog
spec:
volumes:
- name: mysql-data
hostPath:
path: /data/mysql/data
nodeSelector: # 使用节点选择器将Pod调度到指定label的节点
component: mysql
containers:
- name: myblog
image: 192.168.51.209:5000/myblog
env:
- name: MYSQL_HOST # 指定root用户的用户名
value: "127.0.0.1"
- name: MYSQL_PASSWD
value: "123456"
ports:
- containerPort: 8002
- name: mysql
image: 192.168.51.209:5000/mysql:5.7-utf8
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
value: "123456"
- name: MYSQL_DATABASE
value: "myblog"
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql
若存在旧的同名服务,先删除掉,后创建
kubectl -n demo delete pod myblog
[root@k8s-master one-pod]# kubectl create -f pod-with-volume.yaml
pod/myblog created
此时:此时 pod 状态 Pending
[root@k8s-master one-pod]# kubectl -n demo get pods
NAME READY STATUS RESTARTS AGE
myblog 0/2 Pending 0 43s
查看原因,提示调度失败,因为节点不满足 node selector
[root@k8s-master myblog]# kubectl -n demo describe pod myblog
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling <unknown> default-scheduler 0/3 nodes are available: 3 node(s) didn't match node selector.
Warning FailedScheduling <unknown> default-scheduler 0/3 nodes are available: 3 node(s) didn't match node selector.
为节点打标签
[root@k8s-master myblog]# kubectl label node k8s-slave1 component=mysql
node/k8s-slave1 labeled
再次查看,已经运行成功
[root@k8s-master myblog]# kubectl -n demo get po
NAME READY STATUS RESTARTS AGE
myblog 2/2 Running 0 4m51s
到 k8s-slave1 节点,查看/opt/mysql/data
[root@k8s-slave1 ~]# ll /data/mysql/data/
total 188484
-rw-r-----. 1 polkitd input 56 Apr 18 06:15 auto.cnf
-rw-------. 1 polkitd input 1676 Apr 18 06:15 ca-key.pem
-rw-r--r--. 1 polkitd input 1112 Apr 18 06:15 ca.pem
-rw-r--r--. 1 polkitd input 1112 Apr 18 06:15 client-cert.pem
-rw-------. 1 polkitd input 1680 Apr 18 06:15 client-key.pem
-rw-r-----. 1 polkitd input 1346 Apr 18 06:16 ib_buffer_pool
-rw-r-----. 1 polkitd input 79691776 Apr 18 06:16 ibdata1
-rw-r-----. 1 polkitd input 50331648 Apr 18 06:16 ib_logfile0
-rw-r-----. 1 polkitd input 50331648 Apr 18 06:15 ib_logfile1
-rw-r-----. 1 polkitd input 12582912 Apr 18 06:16 ibtmp1
drwxr-x---. 2 polkitd input 20 Apr 18 06:16 myblog
drwxr-x---. 2 polkitd input 4096 Apr 18 06:15 mysql
drwxr-x---. 2 polkitd input 8192 Apr 18 06:15 performance_schema
-rw-------. 1 polkitd input 1676 Apr 18 06:15 private_key.pem
-rw-r--r--. 1 polkitd input 452 Apr 18 06:15 public_key.pem
-rw-r--r--. 1 polkitd input 1112 Apr 18 06:15 server-cert.pem
-rw-------. 1 polkitd input 1680 Apr 18 06:15 server-key.pem
drwxr-x---. 2 polkitd input 8192 Apr 18 06:15 sys
执行 migrate,创建数据库表,然后删掉 pod,再次创建后验证数据是否存在
kubectl -n demo exec -ti myblog python3 manage.py migrate
测试一下服务是否正常
[root@k8s-master ~]# kubectl -n demo get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
myblog 2/2 Running 0 7m6s 10.244.1.7 k8s-slave1 <none> <none>
删除 pod 再创建
[root@k8s-master myblog]# kubectl delete -f pod-with-volume.yaml
pod "myblog" deleted
[root@k8s-master myblog]#
[root@k8s-master myblog]# kubectl create -f pod-with-volume.yaml
pod/myblog created
查看 pod ip 并访问服务*
[root@k8s-master myblog]# kubectl -n demo get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
myblog 2/2 Running 0 34s 10.244.1.8 k8s-slave1 <none> <none>
测试一次啊:
[root@k8s-master myblog]# curl 10.244.1.8:8002/myblog/index
检测容器服务是否健康的手段,若不健康,会根据设置的重启策略(restartPolicy)进行操作,两种检测机制可以分别单独设置,若不设置,默认认为 Pod 是健康的。
两种机制:
三种类型:
示例:
apiVersion: v1
kind: Pod
metadata:
name: myblog
namespace: demo
labels:
component: myblog
spec:
volumes:
- name: mysql-data
hostPath:
path: /data/mysql/data
nodeSelector: # 使用节点选择器将Pod调度到指定label的节点
component: mysql
containers:
- name: myblog
image: 192.168.51.209:5000/myblog
env:
- name: MYSQL_HOST # 指定root用户的用户名
value: "127.0.0.1"
- name: MYSQL_PASSWD
value: "123456"
ports:
- containerPort: 8002
livenessProbe:
httpGet:
path: /blog/index/
port: 8002
scheme: HTTP
initialDelaySeconds: 10 # 容器启动后第一次执行探测是需要等待多少秒
periodSeconds: 15 # 执行探测的频率
timeoutSeconds: 2 # 探测超时时间
readinessProbe:
httpGet:
path: /blog/index/
port: 8002
scheme: HTTP
initialDelaySeconds: 10
timeoutSeconds: 2
periodSeconds: 15
- name: mysql
image: 192.168.51.209:5000/mysql:5.7-utf8
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
value: "123456"
- name: MYSQL_DATABASE
value: "myblog"
readinessProbe:
tcpSocket:
port: 3306
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
tcpSocket:
port: 3306
initialDelaySeconds: 15
periodSeconds: 20
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql
重启策略:
Pod 的重启策略(RestartPolicy)应用于 Pod 内的所有容器,并且仅在 Pod 所处的 Node 上由 kubelet 进行判断和重启操作。当某个容器异常退出或者健康检查失败时,kubelet 将根据 RestartPolicy 的设置来进行相应的操作。
Pod 的重启策略包括 Always、OnFailure 和 Never,默认值为 Always。
spec:
containers:
- name: myblog
image: 192.168.51.209:5000/demo/myblog
imagePullPolicy: IfNotPresent
设置镜像的拉取策略,默认为 IfNotPresent
为了保证充分利用集群资源,且确保重要容器在运行周期内能够分配到足够的资源稳定运行,因此平台需要具备
Pod 的资源限制的能力。 对于一个 pod 来说,资源最基础的 2 个的指标就是:CPU 和内存。
Kubernetes 提供了个采用 requests 和 limits 两种类型参数对资源进行预分配和使用限制。
apiVersion: v1
kind: Pod
metadata:
name: myblog
namespace: demo
labels:
component: myblog
spec:
volumes:
- name: mysql-data
hostPath:
path: /data/mysql/data
nodeSelector: # 使用节点选择器将Pod调度到指定label的节点
component: mysql
containers:
- name: myblog
image: 192.168.51.209:5000/myblog
env:
- name: MYSQL_HOST # 指定root用户的用户名
value: "127.0.0.1"
- name: MYSQL_PASSWD
value: "123456"
ports:
- containerPort: 8002
resources:
requests:
memory: 100Mi
cpu: 50m
limits:
memory: 500Mi
cpu: 100m
livenessProbe:
httpGet:
path: /blog/index/
port: 8002
scheme: HTTP
initialDelaySeconds: 10 # 容器启动后第一次执行探测是需要等待多少秒
periodSeconds: 15 # 执行探测的频率
timeoutSeconds: 2 # 探测超时时间
readinessProbe:
httpGet:
path: /blog/index/
port: 8002
scheme: HTTP
initialDelaySeconds: 10
timeoutSeconds: 2
periodSeconds: 15
- name: mysql
image: 192.168.51.209:5000/mysql:5.7-utf8
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
value: "123456"
- name: MYSQL_DATABASE
value: "myblog"
resources:
requests:
memory: 100Mi
cpu: 50m
limits:
memory: 500Mi
cpu: 100m
readinessProbe:
tcpSocket:
port: 3306
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
tcpSocket:
port: 3306
initialDelaySeconds: 15
periodSeconds: 20
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql
requests:
limits:
对于 CPU,我们知道计算机里 CPU 的资源是按 “时间片”
的方式来进行分配的,系统里的每一个操作都需要 CPU 的处理,所以,哪个任务要是申请的 CPU 时间片越多,那么它得到的 CPU 资源就越多。
然后还需要了解下 CGroup 里面对于 CPU 资源的单位换算:
1 CPU = 1000 millicpu(1 Core = 1000m) 这里的 m
就是毫、毫核的意思,Kubernetes 集群中的每一个节点可以通过操作系统的命令来确认本节点的 CPU 内核数量,然后将这个数量乘以 1000,得到的就是节点总 CPU 总毫数。比如一个节点有四核,那么该节点的 CPU 总毫量为 4000m。
docker run
命令和 CPU 限制相关的所有选项如下:
选项 | 描述 |
---|---|
--cpuset-cpus="" | 允许使用的 CPU 集,值可以为 0-3,0,1 |
-c ,--cpu-shares=0 | CPU 共享权值(相对权重) |
cpu-period=0 | 限制 CPU CFS 的周期,范围从 100ms~1s,即[1000, 1000000] |
--cpu-quota=0 | 限制 CPU CFS 配额,必须不小于1ms,即 >= 1000,绝对限制 |
docker run -it --cpu-period=50000 --cpu-quota=25000 ubuntu:16.04 /bin/bash 将 CFS 调度的周期设为 50000,将容器在每个周期内的 CPU 配额设置为 25000,表示该容器每 50ms 可以得到 50% 的 CPU 运行时间。
注意:若内存使用超出限制,会引发系统的 OOM 机制,因 CPU 是可压缩资源,不会引发 Pod 退出或重建
apiVersion: v1
kind: Pod
metadata:
name: myblog
namespace: demo
labels:
component: myblog
spec:
volumes:
- name: mysql-data
hostPath:
path: /data/mysql/data
nodeSelector: # 使用节点选择器将Pod调度到指定label的节点
component: mysql
containers:
- name: myblog
image: 192.168.51.209:5000/myblog
env:
- name: MYSQL_HOST # 指定root用户的用户名
value: "127.0.0.1"
- name: MYSQL_PASSWD
value: "123456"
ports:
- containerPort: 8002
resources:
requests:
memory: 100Mi
cpu: 50m
limits:
memory: 500Mi
cpu: 100m
livenessProbe:
httpGet:
path: /blog/index/
port: 8002
scheme: HTTP
initialDelaySeconds: 10 # 容器启动后第一次执行探测是需要等待多少秒
periodSeconds: 15 # 执行探测的频率
timeoutSeconds: 2 # 探测超时时间
readinessProbe:
httpGet:
path: /blog/index/
port: 8002
scheme: HTTP
initialDelaySeconds: 10
timeoutSeconds: 2
periodSeconds: 15
- name: mysql
image: 192.168.51.209:5000/mysql:5.7-utf8
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
value: "123456"
- name: MYSQL_DATABASE
value: "myblog"
resources:
requests:
memory: 100Mi
cpu: 50m
limits:
memory: 500Mi
cpu: 100m
readinessProbe:
tcpSocket:
port: 3306
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
tcpSocket:
port: 3306
initialDelaySeconds: 15
periodSeconds: 20
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql
为什么要优化
解决问题一,需要拆分 YAML
mysql.yaml 文件内容
apiVersion: v1
kind: Pod
metadata:
name: mysql
namespace: demo
labels:
component: mysql
spec:
hostNetwork: true # 声明pod的网络模式为host模式,效果通docker run --net=host
volumes:
- name: mysql-data
hostPath:
path: /data/mysql/data
nodeSelector: # 使用节点选择器将Pod调度到指定label的节点
component: mysql
containers:
- name: mysql
image: 192.168.51.209:5000/mysql:5.7-utf8
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
value: "123456"
- name: MYSQL_DATABASE
value: "myblog"
resources:
requests:
memory: 100Mi
cpu: 50m
limits:
memory: 500Mi
cpu: 100m
readinessProbe:
tcpSocket:
port: 3306
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
tcpSocket:
port: 3306
initialDelaySeconds: 15
periodSeconds: 20
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql
myblog.yaml 文件内容
apiVersion: v1
kind: Pod
metadata:
name: myblog
namespace: demo
labels:
component: myblog
spec:
containers:
- name: myblog
image: 192.168.51.209:5000/myblog
imagePullPolicy: IfNotPresent
env:
- name: MYSQL_HOST # 指定root用户的用户名
value: "192.168.51.209"
- name: MYSQL_PASSWD
value: "123456"
ports:
- containerPort: 8002
resources:
requests:
memory: 100Mi
cpu: 50m
limits:
memory: 500Mi
cpu: 100m
livenessProbe:
httpGet:
path: /blog/index/
port: 8002
scheme: HTTP
initialDelaySeconds: 10 # 容器启动后第一次执行探测是需要等待多少秒
periodSeconds: 15 # 执行探测的频率
timeoutSeconds: 2 # 探测超时时间
readinessProbe:
httpGet:
path: /blog/index/
port: 8002
scheme: HTTP
initialDelaySeconds: 10
timeoutSeconds: 2
periodSeconds: 15
创建测试
kubectl -n demo delete po myblog
kubectl create -f mysql.yaml
kubectl create -f myblog.yaml
[root@k8s-master two-pod]# kubectl -n demo get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
myblog 1/1 Running 0 26s 10.244.1.9 k8s-slave1 <none> <none>
mysql 1/1 Running 0 33s 192.168.51.210 k8s-slave1 <none> <none>
[root@k8s-master two-pod]# curl 10.244.1.9:8002/blog/index/
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<h3>我的博客列表:</h3>
<a href="/blog/article/1"> nihao </a>
<br/>
</br>
</br>
<a href=" /blog/article/edit/0 ">写博客</a>
</body>
</html>
解决问题二,环境变量中敏感信息带来的安全隐患
为什么要统一管理环境变量
k8s 提供两类资源,configMap 和 Secret,可以用来实现业务配置的统一管理, 允许将配置文件与镜像文件分离,以使容器化的应用程序具有可移植性 。
myblog/two-pod/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: myblog
namespace: demo
data:
MYSQL_HOST: "192.168.51.209"
MYSQL_PORT: "3306"
Secret,管理敏感类的信息,默认会 base64 编码存储,有三种类型
apiVersion: v1
kind: Secret
metadata:
name: myblog
namespace: demo
type: Opaque
data:
MYSQL_USER: cm9vdA== #注意加-n参数, echo -n root|base64
MYSQL_PASSWD: MTIzNDU2
创建并查看:
[root@k8s-master two-pod]# kubectl create -f secret.yaml
secret/myblog created
[root@k8s-master two-pod]# kubectl -n demo get secret
NAME TYPE DATA AGE
default-token-cv8ks kubernetes.io/service-account-token 3 103m
myblog Opaque 2 28s
如果不习惯这种方式,可以通过如下方式:
[root@k8s-master two-pod]# cat secret.txt
MYSQL_USER=root
MYSQL_PASSWD=123456
kubectl -n demo create secret generic myblog --from-env-file=secret.txt
修改后的 MySQL 的 YAML 文件:
apiVersion: v1
kind: Pod
metadata:
name: mysql
namespace: demo
labels:
component: mysql
spec:
hostNetwork: true # 声明pod的网络模式为host模式,效果通docker run --net=host
volumes:
- name: mysql-data
hostPath:
path: /data/mysql/data
nodeSelector: # 使用节点选择器将Pod调度到指定label的节点
component: mysql
containers:
- name: mysql
image: 192.168.51.209:5000/mysql:5.7-utf8
ports:
- containerPort: 3306
env:
- name: MYSQL_USER
valueFrom:
secretKeyRef:
name: myblog
key: MYSQL_USER
- name: MYSQL_PASSWD
valueFrom:
secretKeyRef:
name: myblog
key: MYSQL_PASSWD
- name: MYSQL_DATABASE
value: "myblog"
resources:
requests:
memory: 100Mi
cpu: 50m
limits:
memory: 500Mi
cpu: 100m
readinessProbe:
tcpSocket:
port: 3306
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
tcpSocket:
port: 3306
initialDelaySeconds: 15
periodSeconds: 20
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql
修改后的 myblog 的 YAML
apiVersion: v1
kind: Pod
metadata:
name: myblog
namespace: demo
labels:
component: myblog
spec:
containers:
- name: myblog
image: 192.168.51.209:5000/myblog
imagePullPolicy: IfNotPresent
env:
- name: MYSQL_HOST
valueFrom:
configMapKeyRef:
name: myblog
key: MYSQL_HOST
- name: MYSQL_PORT
valueFrom:
configMapKeyRef:
name: myblog
key: MYSQL_PORT
- name: MYSQL_USER
valueFrom:
secretKeyRef:
name: myblog
key: MYSQL_USER
- name: MYSQL_PASSWD
valueFrom:
secretKeyRef:
name: myblog
key: MYSQL_PASSWD
ports:
- containerPort: 8002
resources:
requests:
memory: 100Mi
cpu: 50m
limits:
memory: 500Mi
cpu: 100m
livenessProbe:
httpGet:
path: /blog/index/
port: 8002
scheme: HTTP
initialDelaySeconds: 10 # 容器启动后第一次执行探测是需要等待多少秒
periodSeconds: 15 # 执行探测的频率
timeoutSeconds: 2 # 探测超时时间
readinessProbe:
httpGet:
path: /blog/index/
port: 8002
scheme: HTTP
initialDelaySeconds: 10
timeoutSeconds: 2
periodSeconds: 15
在部署不同的环境时,pod 的 YAML 无须再变化,只需要在每套环境中维护一套 ConfigMap 和 Secret 即可。但是注意 configmap 和 secret 不能跨 namespace 使用,且更新后,pod 内的 env 不会自动更新,重建后方可更新。
configmap 文件
apiVersion: v1
kind: ConfigMap
metadata:
name: myblog
namespace: demo
data:
MYSQL_HOST: "192.168.51.209"
MYSQL_PORT: "3306"
kubectl -n kube-system get po,deployment,ds
kubectl -n demo get pod mysql -o yaml
|
Running | Pod 内容器均已创建,且至少有一个容器处于运行状态、正在启动状态或正在重启状态 |
| Succeeded | Pod 内所有容器均已成功执行退出,且不再重启 |
| Failed | Pod 内所有容器均已退出,但至少有一个容器退出为失败状态 |
| CrashLoopBackOff | Pod 内有容器启动失败,比如配置文件丢失导致主进程启动失败 |
| Unknown | 由于某种原因无法获取该 Pod 的状态,可能由于网络通信不畅导致 |
生命周期示意图:
启动和关闭示意:
apiVersion: v1
kind: Pod
metadata:
name: demo-start-stop
namespace: demo
labels:
component: demo-start-stop
spec:
initContainers:
- name: init
image: busybox
command: ['sh', '-c', 'echo $(date +%s): INIT >> /loap/timing']
volumeMounts:
- mountPath: /loap
name: timing
containers:
- name: main
image: busybox
command: ['sh', '-c', 'echo $(date +%s): START >> /loap/timing;
sleep 10; echo $(date +%s): END >> /loap/timing;']
volumeMounts:
- mountPath: /loap
name: timing
livenessProbe:
exec:
command: ['sh', '-c', 'echo $(date +%s): LIVENESS >> /loap/timing']
readinessProbe:
exec:
command: ['sh', '-c', 'echo $(date +%s): READINESS >> /loap/timing']
lifecycle:
postStart:
exec:
command: ['sh', '-c', 'echo $(date +%s): POST-START >> /loap/timing']
preStop:
exec:
command: ['sh', '-c', 'echo $(date +%s): PRE-STOP >> /loap/timing']
volumes:
- name: timing
hostPath:
path: /tmp/loap
创建 pod 测试:
[root@k8s-master myblog]# kubectl create -f demo-pod-start.yaml
查看 demo 状态
kubectl -n demo get po -o wide -w
查看调度节点的/tmp/loap/timing
cat /tmp/loap/timing