如果把 Pod 看成传统环境里的“机器”或“虚拟机”、把容器看作是运行在这个“机器”里的“用户程序”,那么很多关于 Pod 对象的设计就非常容易理解了。比如,凡是调度、网络、存储,以及安全相关的属性,基本上是 Pod 级别的。这些Pod属性的共同特征是,它们描述的是“机器”这个整体,而不是里面运行的“程序”。比如,配置这个“机器”的网卡(即:Pod 的网络定义),配置这个“机器”的磁盘(即:Pod 的存储定义),配置这个“机器”的防火墙(即:Pod 的安全定义)。更不用说,这台“机器”运行在哪个服务器之上(即:Pod 的调度)
Pod中主要字段的用法
nodeSelector
NodeSelector:是一个供用户将 Pod 与 Node 进行绑定的字段。
apiVersion: v1
kind: Pod
...
spec:
nodeSelector:
disktype: ssd
HostAliases
定义了 Pod 的 hosts 文件(比如 /etc/hosts)里的内容。
在这个 Pod 的 YAML 文件中,设置了一组 IP 和 hostname 的数据。这样,这个 Pod 启动后,/etc/hosts 文件的内容将如下所示。
apiVersion: v1
kind: Pod
...
spec:
hostAliases:
- ip: "10.10.10.1"
hostnames:
- "abc.taoge"
- "cde.taoge"
...
通过这种方法设置了host文件中的内容,当容器重启替换后,kubelet 会自动覆盖掉被修改的内容。
shareProcessNamespace=true
与容器级别,譬如Linux Namespace相关的属性,一定是pod级别的。可以理解为:Pod 的设计,就是要让它里面的容器尽可能多地共享 Linux Namespace,仅保留必要的隔离和限制能力。这样,Pod 模拟出的效果,就跟虚拟机里程序间的关系非常类似了。shareProcessNamespace=true,这个属性就是制定pod内的容器,譬如两个容器,共享一套namespace。这样创建一个sharenamespace.yaml文件,通过这个yaml文件生成pod。
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
shareProcessNamespace: true
containers:
- name: nginx
image: nginx
- name: shell
image: busybox
stdin: true
tty: true
kubectl create -f nginx.yaml
容器创建之后,查看kubectl get pods
root@k8s-m1:~# kubectl get pods nginx
NAME READY STATUS RESTARTS AGE
nginx 2/2 Running 0 117s
该pod yaml文件定义了两个容器:一个是 nginx 容器,一个是开启了 tty 和 stdin 的 shell 容器,可以看到shell这个container容器是从busybox image创建的,busybox可以理解为是一个极简的容器,包括stdin、stdout,包含了ifconfig、shell等基础组件,可以连接到shell容器进行交互。
root@k8s-m1:~# kubectl attach -it nginx -c shell
If you don't see a command prompt, try pressing enter.
/ # ps ax
PID USER TIME COMMAND
1 root 0:00 /pause
6 root 0:00 nginx: master process nginx -g daemon off;
11 101 0:00 nginx: worker process
25 root 0:00 sh
31 root 0:00 ps ax
可以看到进入shell这个容器交互,由于这个pod设置了sharenamespace属性。
同时可以看到pod内所有容器的进程。
initContainers属性
当容器设置initContainer时,如下这个yaml文件中的WAR 包容器的类型不再是一个普通容器,而是一个 Init Container 类型的容器。在 Pod 中,所有 Init Container 定义的容器,都会比 spec.containers 定义的用户容器先启动。并且,Init Container 容器会按顺序逐一启动,而直到它们都启动并且退出了,用户容器才会启动。所以,这个 Init Container 类型的 WAR 包容器启动后,我执行了一句"cp /sample.war /app",把应用的 WAR 包拷贝到 /app 目录下,然后退出。而后这个 /app 目录,就挂载了一个名叫 app-volume 的 Volume。因此当tomcat容器启动后,自然已经看到了war包容器的一系列操作之后的结果,tomcat mount的volume目录下已经有war包存在了。
这个war包容器就像是sidecar,实现volume和数据目录的操作,而tomcat这个真正的http业务的容器,不依赖于自身的任何配置文件,即可运行,也有助于将来tomcat容器的重启、重装等。
apiVersion: v1
kind: Pod
metadata:
name: javaweb-2
spec:
initContainers:
- image: taoge/sample:v2
name: war
command: ["cp", "/myweb.war", "/app"]
volumeMounts:
- mountPath: /app
name: app-volume
containers:
- image: taoge/tomcat:8.0
name: tomcat
command: ["sh","-c","/root/apache-tomcat-8.0.0-v2/bin/start.sh"]
volumeMounts:
- mountPath: /root/apache-tomcat-8.0.0-v2/webapps
name: app-volume
ports:
- containerPort: 8080
hostPort: 8001
volumes:
- name: app-volume
emptyDir: {}
暂无评论