一、凡是调度、网络、存储,以及安全相关的属性,基本上是 Pod 级别的。
1、这些属性的共同特征是,它们描述的是“机器”这个整体,而不是里面运行的“程序”。
1、比如,配置这个“机器”的网卡(即:Pod 的网络定义),
2、配置这个“机器”的磁盘(即:Pod 的存储定义),
3、配置这个“机器”的防火墙(即:Pod 的安全定义)。
4、更不用说,这台“机器”运行在哪个服务器之上(即:Pod 的调度)。
2、NodeSelector:是一个供用户将 Pod 与 Node 进行绑定的字段
apiVersion: v1 kind: Pod ... spec: nodeSelector: disktype: ssd
这样的一个配置,意味着这个 Pod 永远只能运行在携带了“disktype: ssd”标签(Label)的节点上;否则,它将调度失败。
3、NodeName:一旦Pod的这个字段被赋值,Kubernetes 项目就会被认为这个 Pod 已经经过了调度
调度的结果就是赋值的节点名字。所以,这个字段一般由调度器负责设置,但用户也可以设置它来“骗过”调度器,
当然这个做法一般是在测试或者调试的时候才会用到。
4、HostAliases:定义了Pod的hosts文件(比如 /etc/hosts)里的内容
apiVersion: v1 kind: Pod ... spec: hostAliases: - ip: "10.1.2.3" hostnames: - "foo.remote" - "bar.remote" ...
在这个 Pod 的 YAML 文件中,我设置了一组 IP 和 hostname 的数据。这样,这个 Pod 启动后,/etc/hosts 文件的内容将如下所示:
cat /etc/hosts # Kubernetes-managed hosts file. 127.0.0.1 localhost ... 10.244.135.10 hostaliases-pod 10.1.2.3 foo.remote 10.1.2.3 bar.remote
二、凡是跟容器的 Linux Namespace 相关的属性,也一定是 Pod 级别的
这个原因也很容易理解:Pod 的设计,就是要让它里面的容器尽可能多地共享 Linux Namespace,仅保留必要的隔离和限制能力。
这样,Pod 模拟出的效果,就跟虚拟机里程序间的关系非常类似了。
1、shareProcessNamespace=true这个 Pod 里的容器要共享 PID Namespace。
举个例子,在下面这个 Pod 的 YAML 文件中,我定义了 shareProcessNamespace=true:
apiVersion: v1 kind: Pod metadata: name: nginx spec: shareProcessNamespace: true containers: - name: nginx image: nginx - name: shell image: busybox stdin: true tty: true
这就意味着这个 Pod 里的容器要共享 PID Namespace。
2、tty和stdin等同于设置了 docker run 里的 -it(-i 即 stdin,-t 即 tty)参数。
如果你还是不太理解它们俩的作用的话,可以直接认为 tty 就是 Linux 给用户提供的一个常驻小程序,用于接收用户的标准输入,返回操作系统的标准输出。
当然,为了能够在 tty 中输入信息,你还需要同时开启 stdin(标准输入流)。
于是,这个 Pod 被创建后,你就可以使用 shell 容器的 tty 跟这个容器进行交互了。我们一起实践一下
$ kubectl create -f nginx.yaml
接下来,我们使用 kubectl attach 命令,连接到 shell 容器的 tty 上:
$ kubectl attach -it nginx -c shell
这样,我们就可以在 shell 容器里执行 ps 指令,查看所有正在运行的进程:
$ kubectl attach -it nginx -c shell / # ps ax PID USER TIME COMMAND 1 root 0:00 /pause 8 root 0:00 nginx: master process nginx -g daemon off; 14 101 0:00 nginx: worker process 15 root 0:00 sh 21 root 0:00 ps ax
三、凡是 Pod 中的容器要共享宿主机的 Namespace,也一定是 Pod 级别的定义
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
1、hostNetwork: true这个 Pod 里的所有容器,会直接使用宿主机的网络、直接与宿主机进行 IPC 通信
在这个 Pod 中,我定义了共享宿主机的 Network、IPC 和 PID Namespace。这就意味着,这个 Pod 里的所有容器,
会直接使用宿主机的网络、直接与宿主机进行 IPC 通信、看到宿主机里正在运行的所有进程。
2、Containers
1、Containers的分类
2、Container 的主要字段
3、ImagePullPolicy镜像拉取的策略
它定义了镜像拉取的策略。而它之所以是一个 Container 级别的属性,是因为容器镜像本来就是 Container 定义中的一部分。
1、Always
2、Never 或者 IfNotPresent
4、Lifecycle在容器状态发生变化时触发一系列“钩子
apiVersion: v1 kind: Pod metadata: name: lifecycle-demo spec: containers: - name: lifecycle-demo-container image: nginx lifecycle: postStart: exec: command: ["/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"] preStop: exec: command: ["/usr/sbin/nginx","-s","quit"]
1、postStart
2、preStop
3、优雅退出
四、Pod 对象在 Kubernetes 中的生命周期。
Pod 生命周期的变化,主要体现在 Pod API 对象的Status 部分,这是它除了 Metadata 和 Spec 之外的第三个重要字段。其中,pod.status.phase,
就是 Pod 的当前状态,它有如下几种可能的情况:
1、Status 部分
1、Pending
2、Running
3、Succeeded
4、Failed
5、Unknown
2、造成当前 Status 的具体原因是什么。
更进一步地,Pod 对象的 Status 字段,还可以再细分出一组 Conditions。这些细分状态的值包括:PodScheduled、Ready、Initialized,以及 Unschedulable。它们主要用于描述造成当前 Status 的具体原因是什么。
1、Unschedulable
2、Ready
Pod 的这些状态信息,是我们判断应用运行情况的重要标准,尤其是 Pod 进入了非“Running”状态后,你一定要能迅速做出反应,根据它所代表的异常情况开始跟踪和定位,而不是去手忙脚乱地查阅文档。
3、在学习完这篇文章后,我希望你能仔细阅读
$GOPATH/src/k8s.io/kubernetes/vendor/k8s.io/api/core/v1/types.go 里,type Pod struct ,尤其是 PodSpec 部分的内容。
争取做到下次看到一个 Pod 的 YAML 文件时,不再需要查阅文档,就能做到把常用字段及其作用信手拈来。