天天看点

Kubernetes Pod 资源共享实现机制

1.Pod基本概念

Pod是Kubernetes创建和管理的最小单元,一个Pod由一个容器或多个容器组成,这些容器共享存储、网络。

Pod特点

  • 一个Pod可以理解为是一个应用实例,提供服务
  • Pod中容器始终部署在一个Node上 
  • Pod中容器共享网络、存储资源
  • Kubernetes直接管理Pod,而不是容器
Kubernetes Pod 资源共享实现机制

Pod就是豌豆荚,里面的豆子可以理解为容器,一个pod可以理解为一个应用提供具体的某个服务。

Pod主要用法:

  • 运行单个容器:最常见的用法,在这种情况下,可以将Pod看做是单个容器的抽象封装
  • 运行多个容器:封装多个紧密耦合且需要共享资源的应用程序(这就是引入Pod的意义了)

如果有这些需求,你可以运行多个容器:

  • 两个应用之间发生文件交互
  • 两个应用需要通过127.0.0.1或者socket通信
  • 两个应用需要发生频繁的调用

2.Pod资源共享实现机制

Kubernetes Pod 资源共享实现机制

 容器之间是通过namespace之间去隔离的,之间的网络是隔离的,文件系统是隔离的,难道在pod当中两个容器也不能相互通信了吗?仿佛又回到了docker各个容器之间都是隔离的。

docker是通过namespace实现docker容器间资源隔离的,那么Pod要解决网络和文件系统的问题其实就要打破namespace的隔离。

怎么解决两个容器之间通信的问题呢?也即是容器之间看到的网络协议栈是一样的,在创建pod的时候会先创建infra container这个容器,启动好之后然后再将实际创建的pod加入到infra container容器当中,这个容器实现的主要目的是维护了pod的网络,没有跑任何的业务逻辑,只是启动了一个容器罢了。其他容器的创建都让其连接至该容器的网络命名空间当中。这样一来其他容器看到的网络视图就是infra container的网络视图了。一个pod当中所有的容器看到的网络设备,网卡,ip,mac地址都看到的是同一个了,因为在一个网络命名空间。这样就解决了网络共享的问题。实际上pod的ip就是infra container的ip。(加入infra container命名空间实现网络共享,同一个网络协议栈),

两个容器的文件系统也是隔离的,k8s引入了数据卷volume,通过pod当中的不同容器去挂载这个卷来实现共享某些数据。

2.1 Pod网络共享验证

1)创建一个Pod(包含busybox和nginx两个容器)

[root@k8s-master ~]# cat pod-network.yml 
apiVersion: v1
kind: Pod
metadata:
  labels:
    app: test
  name: pod-network-test 
  namespace: default
spec:
  containers:
  - image: busybox
    name: busybox
    command: ["/bin/sh","-c","sleep 3600"]
  - image: nginx
    name: nginx


[root@k8s-master ~]# kubectl apply -f pod-network.yml
[root@k8s-master ~]# kubectl get pod
NAME               READY   STATUS    RESTARTS   AGE
pod-network-test   2/2     Running   0          117s
[root@k8s-master ~]# kubectl describe pod pod-network-test  //如果启动不了使用该命令查看Pod具体信息      

2)进入busybox容器查看网络端口信息 

如果pod当中包含有多个容器需要使用-c指定进入哪个容器

[root@k8s-master ~]# kubectl exec -it  pod-network-test -c busybox -- sh
/ # netstat -tpln
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      -
tcp        0      0 :::80                   :::*                    LISTEN      

注:busybox是一个纯净的容器,里面怎么多出了一个80端口?实际上这就是nginx的监听端口。其实看到的就是infra container的网络协议栈。即nginx和busybox看到的网络协议栈是一样的。

可以看到网络是共享的,如果网络不是共享的通过127.0.0.1就访问自己的协议栈了,就不会获取到index.html页面

/ # wget 127.0.0.1:80
Connecting to 127.0.0.1:80 (127.0.0.1:80)
saving to 'index.html'
index.html           100% |******************************************************************|   612  0:00:00 ETA
'index.html' saved
/ # cat index.html | grep nginx
<title>Welcome to nginx!</title>      

2.2 Pod数据共享验证

1)创建一个Pod(包含busybox和nginx两个容器并设置volume)

[root@k8s-master ~]# cat pod-volume.yml 
apiVersion: v1
kind: Pod
metadata:
  labels:
    app: test
  name: pod-volume-test 
  namespace: default
spec:
  containers:
  - image: busybox
    name: busybox
    command: ["/bin/sh","-c","sleep 3600"]
    volumeMounts:
    - name: data
      mountPath: /data
  - image: nginx
    name: nginx
    volumeMounts:
    - name: data
      mountPath: /data
  volumes:
  - name: data
  emptyDir: {}


[root@k8s-master ~]# kubectl apply -f pod-volume.yml
[root@k8s-master ~]# kubectl get pod
NAME               READY   STATUS    RESTARTS   AGE
pod-network-test   2/2     Running   0          23m
pod-volume-test    2/2     Running   0          42s
[root@k8s-master ~]# kubectl exec -it pod-volume-test -c nginx -- bash
root@pod-volume-test:/# cd /data
root@pod-volume-test:/data# echo "volume test" > a.txt
root@pod-volume-test:/data# exit
exit      

2)进入busybox容器检查

[root@k8s-master ~]# kubectl exec -it pod-volume-test -c busybox -- sh
/ # cat /data/a.txt 
volume test
/ #      

 注:可以看busybox看到Nginx修改的文件到文件共享了,通过数据卷实现的文件的共享

3.Pod管理命令

创建Pod:

kubectl apply -f pod.yaml
或者使用命令 kubectl run nginx --image=nginx      

查看Pod:

kubectl get pods
kubectl describe pod <Pod名称>      

查看日志:

如果pod里面包含多个容器,需要指定容器名字来查看指定容器的日志

kubectl logs <Pod名称> [-c CONTAINER]
kubectl logs <Pod名称> [-c CONTAINER] -f      

进入容器终端:

kubectl exec <Pod名称> [-c CONTAINER] -- bash      

删除Pod:

kubectl delete <Pod名称>      

注:如果需要采集nginx日志,那么可能就需要共享存储这个机制,跑一个独立的采集日志的容器采集共享存储里面的日志。这就会用到一个pod运行多个容器。一个业务容器,一个业务日志采集容器

补充:kubectl命令自动补全

例:输入kubectl cr(tab键自动联想命令create)

[root@k8s-master ~]# yum install -y bash-completion
[root@k8s-master ~]# bash
[root@k8s-master ~]# source <(kubectl completion bash)
[root@k8s-master ~]# kubectl create 
clusterrole          configmap            deployment           namespace            priorityclass        role                 secret               serviceaccount       
clusterrolebinding   cronjob              job                  poddisruptionbudget  quota                rolebinding          service      

作者:杰宏唯一

继续阅读