k8s | 深入理解pod
Pod 是 k8s 中最小的可部署和可调度的单位。它是一个或多个容器的组合,共享网络和存储资源,并在同一节点上运行。
Pod本意是豌豆荚的意思,此处指的是K8S中资源调度的最小单位,豌豆荚里面的小豆子就像是Container,豌豆荚本身就像是一个Pod
生命周期
Kubernetes 以 PodStatus.Phase
抽象 Pod 的状态。可能的 Phase 包括
- Pending: API Server已经创建该Pod,但一个或多个容器还没有被创建,包括通过网络下载镜像的过程。
- Running: Pod中的所有容器都已经被创建且已经调度到 Node 上面,但至少有一个容器还在运行或者正在启动。
- Succeeded: Pod 调度到 Node 上面后均成功运行结束,并且不会重启。
- Failed: Pod中的所有容器都被终止了,但至少有一个容器退出失败(即退出码不为 0 或者被系统终止)。
- Unknonwn: 状态未知,因为一些原因Pod无法被正常获取,通常是由于 apiserver 无法与 kubelet 通信导致。
Pod 属性
NodeSelector
NodeSelector**:是一个将 Pod 与 Node 进行绑定**的字段
apiVersion: v1
kind: Pod
……
spec:
nodeSelector:
disktype: ssd
这个配置意味着在 携带了“disktype: ssd”标签(Label)的节点运行,否则会失败
HostAlias
HostAliases**:**定义了 Pod 的 hosts 文件(比如 /etc/hosts)里的内容,
简单说就是 将 ip 和别名进行一个 绑定
apiVersion: v1
kind: Pod
...
spec:
hostAliases:
- ip: "10.1.2.4"
hostnames:
- "test1.remote"
- "test2.remote"
...
对应的/etc/hosts 文件的内容将如下
cat /etc/hosts
# Kubernetes-managed hosts file.
127.0.0.1 localhost
...
10.244.135.10 hostaliases-pod
10.1.2.4 test1.remote
10.1.2.4 test2.remote
shareProcessNamespace
凡是跟容器的 Linux Namespace 相关的属性,也一定是 Pod 级别的,包括以下
- Network:将该 Pod 的网络命名空间与主机共享。这意味着 Pod 中的容器可以直接访问主机的网络栈和接口
- IPC(Inter-Process Communication): Pod 中的容器可以与主机上的进程进行 IPC 通信。
- PID:意味着 Pod 中的容器可以看到主机上的进程并与其进行交互
- Namespace
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
hostNetwork: true
hostIPC: true
hostPID: true
containers:
- name: nginx
image: nginx
- name: shell
image: busybox
stdin: true
tty: true
在这个 Pod 中,定义了共享宿主机的 Network、IPC 和 PID Namespace。
这就意味着,这个 Pod 里的所有容器,会直接使用宿主机的网络、直接与宿主机进行 IPC 通信、看到宿主机里正在运行的所有进程。
NodeName
当Pod 的这个字段被赋值,Kubernetes 项目就会被认为这个 Pod 已经经过了调度,调度的结果就是赋值的节点名字。
所以,这个字段一般由调度器负责设置
container 属性
和 Docker 的 container 类似
- Image(镜像)
- Command(启动命令)
- workingDir(容器的工作目录)
- Ports(容器要开发的端口)
- volumeMounts(容器要挂载的 Volume)
ImagePullPolicy
定义了镜像拉取的策略
- Always:不管镜像是否存在都会去拉取,不同则覆盖
- Never:只是用本地镜像,不会去仓库拉取镜像,如果本地镜像不存在则Pod运行失败。
- IfNotPresent:只有本地镜像不存在时,才会去仓库拉取镜像。ImagePullPolicy的默认值。
注意
:latest
标签的镜像默认为Always
- 生产环境中应该尽量避免使用
:latest
标签,而开发环境中可以借助:latest
标签自动拉取最新的镜像。
LifeCycle
定义的是 Container Lifecycle Hooks, 作用就是容器发生变化触发的一系列 “钩子”
apiVersion: v1
kind: Pod
metadata:
name: lifecycle-demo
spec:
containers:
- name: lifecycle-demo-container
image: nginx
lifecycle:
# 指在容器启动后,立刻执行一个指定的操作
postStart:
exec:
# 在 /usr/share/message 里写入了一句“Hello from the postStart handler”
command: ["/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"]
# 容器被杀死之前 执行的操作
preStop:
exec:
# 调用 nginx 的退出指令
command: ["/usr/sbin/nginx","-s","quit"]
Volume 数据卷
Volume 是一种抽象概念,用于表示容器中的存储设备。Volume 可以包含多个容器,以便它们可以在容器之间共享数据
Projected Volume
Kubernetes 中,有几种特殊的 Volume,它们不是为了存放容器里的数据,也不是用来进行容器和宿主机之间的数据交换。这些特殊 Volume 的作用,是为容器提供预先定义好的数据。所以,从容器的角度来看,这些 Volume 里的信息就是仿佛是被 Kubernetes“投射”(Project)进入容器当中的。这正是 Projected Volume 的含义
secret
把 Pod 想要访问的加密数据,存放到 Etcd 中,通过在 Pod 的容器里挂载 Volume 访问到这些 Secret 里保存的信息
apiVersion: v1
kind: Pod
metadata:
name: test-projected-volume
spec:
containers:
- name: test-secret-volume
image: busybox
args:
- sleep
- "86400"
volumeMounts:
- name: mysql-cred
mountPath: "/projected-volume"
readOnly: true
volumes:
- name: mysql-cred
projected:
sources:
- secret:
name: user
- secret:
name: passward
BusyBox镜像:BusyBox是一个开源项目,提供了一个类似于UNIX操作系统的命令行界面,它包含了许多常用的工具程序,如文件操作、文本处理、网络配置、系统监测等。它被设计成在嵌入式系统中使用,因为它占用的空间很小,可以在资源受限的设备上运行。
这里用到的数据库的用户名、密码,就是以 Secret 对象的方式交给 Kubernetes 保存的
$ kubectl create secret generic user --from-file=./username.txt
$ kubectl create secret generic passward --from-file=./password.txt
查看
kubectl get secrets
直接通过编写 YAML 文件的方式来创建这个 Secret 对象
apiVersion: v1
kind: Secret
metadata:
name: mytestsecret
type: Opaque
data:
user: YWRtaW4=
passward: YWRtaW4xMjM0
Download API
Downward API:是让 Pod 里的容器能够直接获取到这个 Pod API 对象本身的信息。
apiVersion: v1
kind: Pod
metadata:
name: test-downwardapi-volume
labels:
zone: us-est-coast
cluster: test-cluster1
rack: rack-22
spec:
containers:
- name: client-container
image: k8s.gcr.io/busybox
command: ["sh", "-c"]
args:
- while true; do
if [[ -e /etc/podinfo/labels ]]; then
echo -en '\n\n'; cat /etc/podinfo/labels; fi;
sleep 5;
done;
volumeMounts:
- name: podinfo
mountPath: /etc/podinfo
readOnly: false
volumes:
- name: podinfo
projected:
sources:
- downwardAPI:
items:
- path: "labels"
fieldRef:
fieldPath: metadata.labels
在这个 Pod 的 YAML 文件中,定义了一个简单的容器,声明了一个 projected 类型的 Volume。只不过这次 Volume 的数据来源,变成了 Downward API。而这个 Downward API Volume,则声明了要暴露 Pod 的 metadata.labels 信息给容器。
评论区