理论基础
Pod 是可以在 Kubernetes 中创建和管理的、最小的可部署的计算单元。
Pod (就像在鲸鱼荚或者豌豆荚中)是一组(一个或多个) 容器; 这些容器共享存储、网络、以及怎样运行这些容器的声明。 Pod 中的内容总是并置(colocated)的并且一同调度,在共享的上下文中运行。 Pod 所建模的是特定于应用的“逻辑主机”,其中包含一个或多个应用容器, 这些容器是相对紧密的耦合在一起的。 在非云环境中,在相同的物理机或虚拟机上运行的应用类似于 在同一逻辑主机上运行的云应用。
除了应用容器,Pod 还可以包含在 Pod 启动期间运行的 Init 容器。 你也可以在集群中支持临时性容器 的情况外,为调试的目的注入临时性容器。
Pod 的共享上下文包括一组 Linux 名字空间、控制组(cgroup)和可能一些其他的隔离 方面,即用来隔离 Docker 容器的技术。 在 Pod 的上下文中,每个独立的应用可能会进一步实施隔离。
就 Docker 概念的术语而言,Pod 类似于共享名字空间和文件系统卷的一组 Docker 容器。
创建Pod
使用命令行创建Pod
[root@clientvm ~]# kubectl run busybox --image=busybox -n mytest -- sleep 10000
pod/busybox created
[root@clientvm ~]# kubectl get pod -n mytest
NAME READY STATUS RESTARTS AGE
busybox 1/1 Running 0 30s
labelpod 1/1 Running 0 35m
labelpod-yaml 1/1 Running 0 22m
使用yaml创建Pod
[root@clientvm ~]# kubectl run busybox2 --image=busybox -n mytest --dry-run=client -o yaml -- sleep 10000
[root@clientvm ~]# vim busybox2.yaml
[root@clientvm ~]# kubectl apply -f busybox2.yaml
pod/busybox2 created
[root@clientvm ~]# kubectl get pod -n mytest
NAME READY STATUS RESTARTS AGE
busybox 1/1 Running 0 9m52s
busybox2 1/1 Running 0 40s
labelpod 1/1 Running 0 45m
labelpod-yaml 1/1 Running 0 31m
修改Pod
命令行修改
[root@clientvm ~]# kubectl edit pod -n mytest busybox2
##增加一个标签
labels:
run: busybox2
app: web
[root@clientvm ~]# kubectl get -n mytest pod -l app=web
NAME READY STATUS RESTARTS AGE
busybox2 1/1 Running 0 6m17s
修改yaml文件
[root@clientvm ~]# vim busybox2.yaml
......
metadata:
labels:
run: busybox2
app: web1
[root@clientvm ~]# kubectl apply -f busybox2.yaml
pod/busybox2 configured
[root@clientvm ~]#
[root@clientvm ~]#
[root@clientvm ~]# kubectl get -n mytest pod -l app=web
No resources found in mytest namespace.
[root@clientvm ~]# kubectl get -n mytest pod -l app=web1
NAME READY STATUS RESTARTS AGE
busybox2 1/1 Running 0 8m46s
通过命令行patch修改
[root@clientvm ~]# kubectl patch -n mytest pod busybox2 -p '{"metadata": {"labels": {"app": "web2"}}}'
pod/busybox2 patched
[root@clientvm ~]# kubectl get -n mytest pod -l app=web2
NAME READY STATUS RESTARTS AGE
busybox2 1/1 Running 0 11m
进入Pod中的容器
[root@clientvm ~]# kubectl exec -n mytest -it busybox2 -- /bin/sh
/ # ls
bin dev etc home proc root sys tmp usr var
/ # exit
[root@clientvm ~]#
查看容器运行的主机
[root@clientvm ~]# kubectl get -n mytest pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
busybox 1/1 Running 0 23m 10.244.1.6 worker1.example.com <none> <none>
busybox2 1/1 Running 0 14m 10.244.2.3 worker2.example.com <none> <none>
[root@clientvm ~]# ssh worker2
Last login: Fri Nov 27 14:22:32 2020 from 192.168.241.128
[root@worker2 ~]#
[root@worker2 ~]# docker ps | grep busybox2
4a3a3ae3b9f3 busybox "sleep 10000" 15 minutes ago Up 15 minutes k8s_busybox2_busybox2_mytest_9a441645-b3e2-4dc6-807b-b8235cffadbf_0
90b28e80ed25 registry.aliyuncs.com/google_containers/pause:3.2 "/pause" 15 minutes ago Up 15 minutes k8s_POD_busybox2_mytest_9a441645-b3e2-4dc6-807b-b8235cffadbf_0
运行一次性Pod
[root@clientvm ~]# kubectl run onetime --image=busybox --restart=Never -- echo hello
[root@clientvm ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
onetime 0/1 Completed 0 24s
[root@clientvm ~]# kubectl logs pod/onetime
hello
创建多容器Pod
[root@clientvm ~]# cat multi-containers.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
run: multi-container
app: web1
name: multi-container
namespace: mytest
spec:
containers:
- name: nginx
image: nginx
- name: busybox
image: busybox
args:
- sleep
- "10000"
dnsPolicy: ClusterFirst
restartPolicy: Always
[root@clientvm ~]# kubectl apply -f multi-containers.yaml
pod/multi-container created
[root@clientvm ~]# kubectl get -n mytest pod
NAME READY STATUS RESTARTS AGE
busybox 1/1 Running 0 45m
busybox2 1/1 Running 0 35m
labelpod 1/1 Running 0 80m
labelpod-yaml 1/1 Running 0 66m
multi-container 2/2 Running 0 99s
##进入多容器Pod中的某一个容器加-c选项
[root@clientvm ~]# kubectl exec -n mytest -it multi-container -c nginx -- /bin/bash
root@multi-container:/# ls
bin boot dev docker-entrypoint.d docker-entrypoint.sh etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
Init容器
Init 容器是一种特殊容器,在 Pod 内的应用容器启动之前运行。Init 容器可以包括一些应用镜像中不存在的实用工具和安装脚本。
每个 Pod 中可以包含多个容器, 应用运行在这些容器里面,同时 Pod 也可以有一个或多个先于应用容器启动的 Init 容器。
Init 容器与普通的容器非常像,除了如下两点:
- 它们总是运行到完成。
- 每个都必须在下一个启动之前成功完成。
如果 Pod 的 Init 容器失败,kubelet 会不断地重启该 Init 容器直到该容器成功为止。如果为一个 Pod 指定了多个 Init 容器,这些容器会按顺序逐个运行。 每个 Init 容器必须运行成功,下一个才能够运行。当所有的 Init 容器运行完成时, Kubernetes 才会为 Pod 初始化应用容器并像平常一样运行。
[root@clientvm ~]# cat init-container.yaml
apiVersion: v1
kind: Pod
metadata:
name: init-pod
namespace: mytest
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: busybox:1.28
command: ['sh', '-c', 'echo The app is running! && sleep 36000']
initContainers:
- name: init-container
image: busybox:1.28
command: ['sh', '-c', "echo hello"]
[root@clientvm ~]# kubectl apply -f init-container.yaml
pod/init-pod created
[root@clientvm ~]# kubectl get pod -n mytest
NAME READY STATUS RESTARTS AGE
busybox 1/1 Running 0 58m
busybox2 1/1 Running 0 48m
init-pod 1/1 Running 0 69s
[root@clientvm ~]# kubectl describe pod init-pod -n mytest
......
Normal Scheduled 118s default-scheduler Successfully assigned mytest/init-pod to worker1.example.com
Normal Pulling 117s kubelet Pulling image "busybox:1.28"
Normal Pulled 93s kubelet Successfully pulled image "busybox:1.28" in 24.34182876s
Normal Created 93s kubelet Created container init-container
Normal Started 92s kubelet Started container init-container
Normal Pulled 92s kubelet Container image "busybox:1.28" already present on machine
Normal Created 92s kubelet Created container myapp-container
Normal Started 92s kubelet Started container myapp-container
[root@clientvm ~]# kubectl logs -n mytest pod/init-pod -c init-container
hello
[root@clientvm ~]# kubectl logs -n mytest pod/init-pod -c myapp-container
The app is running!
Sidecar Pod
[root@clientvm ~]# cat sidecar-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: sidecar-container-demo
spec:
containers:
- image: busybox
imagePullPolicy: IfNotPresent
command: ["/bin/sh"]
args: ["-c", "while true; do echo echo $(date -u) 'Hi I am from Sidecar container' >> /var/log/index.html; sleep 5;done"]
name: sidecar-container
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "sleep 20"]
resources: {}
volumeMounts:
- name: var-logs
mountPath: /var/log
- image: nginx
imagePullPolicy: IfNotPresent
name: main-container
resources: {}
ports:
- containerPort: 80
volumeMounts:
- name: var-logs
mountPath: /usr/share/nginx/html
dnsPolicy: Default
volumes:
- name: var-logs
emptyDir: {}
[root@clientvm ~]# kubectl apply -f sidecar-pod.yaml -n mytest
pod/sidecar-container-demo created
[root@clientvm ~]# kubectl get pod -n mytest -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
sidecar-container-demo 2/2 Running 0 16s 10.244.2.77 worker2.example.com <none> <none>
[root@master ~]# curl 10.244.2.77
echo Tue Dec 15 04:01:21 UTC 2020 Hi I am from Sidecar container
echo Tue Dec 15 04:01:26 UTC 2020 Hi I am from Sidecar container
echo Tue Dec 15 04:01:31 UTC 2020 Hi I am from Sidecar container
echo Tue Dec 15 04:01:36 UTC 2020 Hi I am from Sidecar container
echo Tue Dec 15 04:01:41 UTC 2020 Hi I am from Sidecar container
echo Tue Dec 15 04:01:46 UTC 2020 Hi I am from Sidecar container
echo Tue Dec 15 04:01:51 UTC 2020 Hi I am from Sidecar container
echo Tue Dec 15 04:01:57 UTC 2020 Hi I am from Sidecar container
echo Tue Dec 15 04:02:02 UTC 2020 Hi I am from Sidecar container
echo Tue Dec 15 04:02:07 UTC 2020 Hi I am from Sidecar container
echo Tue Dec 15 04:02:12 UTC 2020 Hi I am from Sidecar container
静态Pod
静态 Pod 在指定的节点上由 kubelet 守护进程直接管理,不需要API 服务器监管。kubelet 监视每个静态 Pod(在它崩溃之后重新启动)。静态 Pod 永远都会绑定到一个指定节点上的 Kubelet。
启用静态Pod方法一
声明文件是标准的 Pod 定义文件,以 JSON 或者 YAML 格式存储在指定目录。路径设置在 Kubelet 配置文件. 的 staticPodPath: <目录> 字段,kubelet 会定期的扫描这个文件夹下的 YAML/JSON 文件来创建/删除静态 Pod。 在1.19版本中,默认已经启用。
如下:
[root@worker2 ~]# grep static /var/lib/kubelet/config.yaml
staticPodPath: /etc/kubernetes/manifests
启用静态Pod方法二
也可以配置这个节点上的 kubelet,使用这个参数执行 --pod-manifest-path=/YOUR/PATH
这个配置文件的位置根据OS不同和K8S版本不同略有差异
如下:
- 查找文件位置
[root@worker2 ~]# find / -name "*kubeadm.conf"
/usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf
[root@master manifests]# systemctl status kubelet.service
● kubelet.service - kubelet: The Kubernetes Node Agent
Loaded: loaded (/usr/lib/systemd/system/kubelet.service; enabled; vendor preset: disabled)
Drop-In: /usr/lib/systemd/system/kubelet.service.d
└─10-kubeadm.conf
Active: active (running) since Sun 2021-03-21 08:45:57 +08; 42min ago
[root@worker2 ~]# vim /usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf
- 重启服务
创建Pod yaml文件
[root@worker2 ~]# cd /etc/kubernetes/manifests/
[root@worker2 manifests]# vim static-pod.yaml
[root@worker2 manifests]# cat static-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: static-pod
namespace: mytest
labels:
role: myrole
spec:
containers:
- name: web
image: nginx
观察Pod创建
[root@clientvm ~]# kubectl get pod -n mytest -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
busybox 1/1 Running 0 90m 10.244.1.6 worker1.example.com <none> <none>
busybox2 1/1 Running 0 80m 10.244.2.3 worker2.example.com <none> <none>
init-pod 1/1 Running 0 33m 10.244.1.8 worker1.example.com <none> <none>
labelpod 1/1 Running 0 125m 10.244.2.2 worker2.example.com <none> <none>
labelpod-yaml 1/1 Running 0 111m 10.244.1.3 worker1.example.com <none> <none>
multi-container 2/2 Running 0 46m 10.244.2.5 worker2.example.com <none> <none>
static-pod-worker2.example.com 1/1 Running 0 71s 10.244.2.6 worker2.example.com <none> <none>