云原生|什么是Kubernetes最小单元POD?(2)

2023-11-24 15:11:18 浏览数 (1)

@七禾页话

学习永无止境,记录相伴相随! —— 琉璃康康

关于POD,还需要了解一个重要的概念就是它的生命周期,一个POD通常都有控制管理器,比如ReplicaSet、Deployment、DaemonSets等,单独创建一个Pod的时候是不受任何管理器管理的,不管是哪种情况,POD都要经历不同的生命周期阶段:

状态

解释

Pending(挂起)

在执行创建 Pod 过程中,命令行已经执行,Pod 已经被 Kubernetes 系统接受,但仍有一个或多个容器未被创建。可以通过 kubectl describe 查看处于 Pending 状态的原因。

Running(运行中)

Pod 已经被绑定到一个节点上,并且所有的容器都已经被创建,至少有一个是运行状态,或者是正在启动或者重启。可以通过 kubectl logs 查看 Pod 的日志。

Succeeded(成功)

所有容器执行成功并终止,并且不会再次重启。可以通过 kubectl logs 查看 Pod 的日志。

Failed(失败)

至少有一个容器没有正常退出,以失败告终。在 Linux 上每个命令都有状态值和信号值,状态值正常是 0-255 之间,正常状态值为 0。容器的创建状态只要是非 0 就是异常的。可以通过 kubectl logs 查看具体原因。

Unknown(未知)

通常是通信出问题,不知道状态是什么。通常是 Unknown。

ImagePullBackOffErr

镜像拉取失败,一般是由于镜像不存在、网络不通或者需要登录认证引起的。可以使用 kubectl describe 命令查看具体原因。

CrashLoopBackOff

容器启动失败,有可能是镜像文件本身就有问题,不能正常启动。可以通过 kubectl logs 命令查看具体原因,一般为启动命令不正确,健康检查不通过等。

OOMKilled

内存溢出,运行的容器本身出现内存溢出。一旦出现这种错误容器或者程序本身会自动 kill 掉。通常是内存 limit 设置太小。或者程序本身有问题,JVM 和容器内存限制都够用,还是内存溢出了。

Terminating

Pod 正在被删除,可以通过 kubectl describe 查看状态。

SysctlForbidden

内核启动失败,和 Linux 内核相关。在启动 Pod 的时候加了一些内核的需求,但是没有开放需求,就会造成内核启动失败。

Completed(主进程退出)

容器内部主进程退出,一般计划任务执行结束会显示该状态。

ContainerCreating

Pod 正在创建,一般为正在下载镜像,或者有配置不当的地方。可以通过 kubectl describe 查看具体原因。

Initializing(初始化)

Pod 中包含了初始化容器,这些容器正在执行初始化任务。

既然POD有状态,那么POD内的容器也有它的状态:在 Kubernetes 中,Pod 内的容器有不同的状态,这些状态反映了容器的生命周期和运行状况。以下是一些常见的容器状态及其解释,制作成表格形式:

状态

解释

Running

容器正在正常运行中。

Terminated

容器已经退出,并且可能处于成功或失败的状态。

Waiting

容器正在等待某些条件满足,例如依赖的容器尚未启动,或者容器正在等待调度资源。

Pending

Pod 已经被创建,但容器的镜像正在被拉取,或者容器正在等待被调度到节点上运行。

ImagePullBackOff

容器尝试拉取镜像失败,并且 Kubernetes 将在一段时间后进行重试。

ErrImagePull

容器无法拉取指定的镜像。通常是由于镜像不存在或者拉取时发生错误导致的。

CrashLoopBackOff

容器已经崩溃,并且 Kubernetes 将在一段时间后进行重试。通常是由于容器崩溃导致的,然后容器被重新启动。

Init:Error

Init 容器初始化失败。这是在使用 Init 容器时,Init 容器未能成功执行导致的状态。

Init:CrashLoopBackOff

Init 容器已经崩溃,并且 Kubernetes 将在一段时间后进行重试。通常是由于 Init 容器崩溃导致的,然后容器被重新启动。

如何查看POD或者容器的状态呢?依然是使用kubectl命令中的getdescribe

kubectl get pod打印中的STATUS是POD的状态,READY标识了POD中已经Ready的容器个数和容器的个数的比例,即已经Ready的容器个数/容器的个数,Ready的容器表示其可以对外提供服务了,所以Ready的容器肯定是Running的状态了,但是Running状态的容器不一定是Ready的。

代码语言:javascript复制
@@左右滑动
ubuntu@VM-16-3-ubuntu:~$ kubectl get pod 
NAME             READY   STATUS    RESTARTS   AGE
web-server-pod   1/1     Running   0          6s
ubuntu@VM-16-3-ubuntu:~$ 

通过kubectl describe pod可以详细获取POD的状态和各个容器的状态:

那么针对POD和容器的不同状态如何排错呢?如果一个POD没有Running,用kubectl describe pod来查看POD的Event进行排错;如果一个POD已经Running了,但是有容器没有Ready,就需要使用kubectl logs -n <namespace> <pod name> <container name in this pod>检查容器启动中的log来拍错。

随着时间的推移,POD的Event和容器的log是会被覆盖掉的,因此在Event和log里没有有用的信息下,可以通过kubectl delete pod -n <namespace> <pod name>删除POD以触发POD重建(使用yaml创建的前提下)来获取最初的Event和log排错。

如何访问POD中的应用程序呢?kubectl提供了port-forward命令,从而实现对集群内部正在运行中的POD的访问。

代码语言:javascript复制
@@左右滑动
ubuntu@VM-16-3-ubuntu:~$ kubectl port-forward pod/web-server-pod 8080:80
Forwarding from 127.0.0.1:8080 -> 80
Forwarding from [::1]:8080 -> 80
Handling connection for 8080     ---->运行curl所打印的log

@@再开一个session,通过curl可以访问POD内部的Nginx服务:
ubuntu@VM-16-3-ubuntu:~$ curl localhost:8080
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
ubuntu@VM-16-3-ubuntu:~$ 

某些POD中的容器也开放了shell的访问权限,因此可以通过kubectl exec的命令进入POD中的某个容器,格式是kubectl exec -it -n <namespace> <pod name> -c <container name> -- <shell in container>,如果POD只有一个容器可以不用制定容器名;如果是多个容器,在不指定容器名的时候,访问的就是Annotation中kubectl.kubernetes.io/default-container的容器或者POD中的第一个容器:

代码语言:javascript复制
@@左右滑动
ubuntu@VM-16-3-ubuntu:~$ kubectl get pod
NAME             READY   STATUS    RESTARTS   AGE
web-server-pod   1/1     Running   0          36m
ubuntu@VM-16-3-ubuntu:~$ kubectl exec -it web-server-pod web-server-pod -- bash
root@web-server-pod:/# hostname
web-server-pod
root@web-server-pod:/# exit
exit
ubuntu@VM-16-3-ubuntu:~$ 
ubuntu@VM-16-3-ubuntu:~$ kubectl get pod -n harbor harbor-registry-5ff45f8998-5gh99 
NAME                               READY   STATUS    RESTARTS   AGE
harbor-registry-5ff45f8998-5gh99   2/2     Running   0          7d1h
ubuntu@VM-16-3-ubuntu:~$ kubectl exec -it -n harbor harbor-registry-5ff45f8998-5gh99 -- bash
Defaulted container "registry" out of: registry, registryctl
harbor [ / ]$ hostname
harbor-registry-5ff45f8998-5gh99
harbor [ / ]$ exit
exit
ubuntu@VM-16-3-ubuntu:~$ 
ubuntu@VM-16-3-ubuntu:~$ kubectl exec -it -n harbor harbor-registry-5ff45f8998-5gh99 -c registryctl -- bash
harbor [ / ]$ hostname
harbor-registry-5ff45f8998-5gh99
harbor [ / ]$ exit
exit
ubuntu@VM-16-3-ubuntu:~$ 

小知识点,如何定义Annotation中kubectl.kubernetes.io/default-container?首先需要知道POD下路由的容器名,然后通过kubectl annotate命令定义,例子如下:

代码语言:javascript复制
@@左右滑动
ubuntu@VM-16-3-ubuntu:~$ kubectl annotate pods -n harbor harbor-registry-5ff45f8998-5gh99  kubectl.kubernetes.io/default-container=registryctl
pod/harbor-registry-5ff45f8998-5gh99 annotate
ubuntu@VM-16-3-ubuntu:~$ kubectl describe pod -n harbor harbor-registry-5ff45f8998-5gh99 | grep -i default-container
                  kubectl.kubernetes.io/default-container: registryctl
ubuntu@VM-16-3-ubuntu:~$ kubectl exec -it -n harbor harbor-registry-5ff45f8998-5gh99  -- bash
harbor [ / ]$ cd ~
harbor [ ~ ]$ ls
ca-bundle.crt.original  harbor_registryctl  install_cert.sh  start.sh
harbor [ ~ ]$ exit
exit
ubuntu@VM-16-3-ubuntu:~$ 

上述例子中的nginx POD配置非常上,但是POD的功能确实非常多的,用于资源管理、配置、安全定义等等,同时POD相关的还有许多功能,列举如下:

以下是与 Pod 相关的关键功能。

功能

描述

Resource Requests and Limits

Pod CPU/Memory 分配

Labels

附加到 Pod 的键值对,用于对资源进行分类

Selectors

基于标签对资源进行分组

Liveness, Readiness, and Startup Probes

容器健康检查

ConfigMaps

用于配置管理

Secrets

用于管理一些如证书、用户密码等安全信息

Volumes

永久性的数据存储

Init Containers

在主容器之前运行的启动容器

Ephemeral Containers

用于调试或故障排除目的添加到 Pod 的临时容器

Service Account

限制对 Kubernetes 对象和资源的访问

SecurityContext

主机权限和特权

Affinity and Anti-Affinity Rules

在节点之间控制 Pod 的亲和反亲和规则

Pod Preemption & Priority

设置 Pod 调度的优先级

Pod Disruption Budget

在集群维护期间需要运行的最小Pod副本数,常用于集群维护和升级时

Container Life Cycle Hooks

根据 Pod 生命周期阶段更改执行自定义脚本

这些功能涵盖了与 Kubernetes Pod 相关的一些关键方面,包括资源管理、标签和选择器、健康检查、配置管理、安全性等。

以上,有想法欢迎留言来聊!


『分享』你的每个『赞』和『在看』,我都喜欢!

0 人点赞