35. K8s 网络原理——Kubernetes 通信
本章讲解知识点
- Kubernetes 的网络实现
- 容器到容器之间的通信
- 同一个 Node 上 Pod 之间的通信
- 不同 Node 上 Pod 之间的通信
<br>
1. Kubernetes 的网络实现
Kubernetes 主要实现以下目标:
- 容器到容器之间的通信
- Pod 到 Pod 之间的通信
- Pod 到 Service 的通信
- 集群内部与外部组件之间的通信
<br>
2. 容器到容器之间的通信
之前我们有讲过,对于 Docker 等大多数 Linux 容器来说,Cgroups 技术是用来制造约束的主要手段,而 Namespace 技术则是用来修改进程视图的主要方法。
那么Namespace 技术同样可以用于容器之间的网络通信,即Network Namespace 。Linux 容器能看见的“网络栈”,实际上是被隔离在它自己的 Network Namespace 当中的。
而所谓“网络栈”,就包括了:网卡(Network Interface)、回环设备(Loopback Device)、路由表(Routing Table)和 iptables 规则。对于一个进程来说,这些要素,其实就构成了它发起和响应网络请求的基本环境。
既然在 k8s 中每个 Pod 中管理着一组 Docker 容器,这些 Docker 容器共享同一个网络命名空间,Pod 中的每个 Docker 容器拥有与 Pod 相同的 IP 和 port 地址空间,并且由于他们在同一个网络命名空间,他们之间可以通过 localhost 相互访问。
举个例子,如果一个 Pod 中包含两个容器,一个是 Web 服务器,一个是 MySQL 数据库。Web 服务器可以通过 localhost:3306 的方式连接 MySQL 数据库容器的 3306 端口进行通信。
什么机制让同一个 Pod 内的多个 docker 容器相互通信?就是使用 Docker 的一种网络模型:–net=container
container 模式指定新创建的 Docker 容器和已经存在的一个容器共享一个网络命名空间,而不是和宿主机共享。新创建的 Docker 容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等
在 k8s 中每个 Pod 容器有一个pause容器有独立的网络命名空间,在 Pod 内启动 Docker 容器时候使用 –net=container 就可以让当前 Docker 容器加入到 Pause 容器的网络命名空间。当然这是 k8s 自动帮我们做的机制。
直白一点,就是在一个 Pod 内,Pod 内的容器是可以相互直接通信的。
2.1 小实验
通过实验来验证容器共享 pause 网络堆栈。
创建出测试 Pod
下载 nginx:latest 镜像
docker pull nginx:latest
创建 test 命名空间
kubectl create ns test
[root@master kubernetes]# kubectl get ns NAME STATUS AGE default Active 18h kube-node-lease Active 18h kube-public Active 18h kube-system Active 18h [root@master kubernetes]# kubectl create ns test namespace/test created
创建 nginx 的 service 和 deployment
vi nginx-service-deployment.yaml
填充以下内容:
apiVersion: v1 kind: Service metadata: labels: app: nginx-servie name: nginx-service # 命名空间,没有可以删除,默认是default namespace: test spec: ports: # 对外暴露的端口 - nodePort: 30013 port: 80 protocol: TCP targetPort: 80 selector: app: nginx-deploy # NodePort类型可以对外暴露端口 type: NodePort --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: nginx-deploy name: nginx-deploy namespace: test spec: replicas: 1 selector: matchLabels: app: nginx-pod template: metadata: labels: app: nginx-pod namespace: test spec: containers: # 镜像名称 - image: nginx:1.22.0 name: nginx ports: - containerPort: 80 resources: {}
创建应用
kubectl apply -f nginx-service-deployment.yaml
如果需要删除创建的以上资源,使用命令:
kubectl delete -f nginx-service-deployment.yaml
检查 Pod 状态
kubectl get pod -n test
[root@master mtuser]# vi nginx-service-deployment.yaml [root@master mtuser]# kubectl apply -f nginx-service-deployment.yaml service/nginx-service created deployment.apps/nginx-deploy created [root@master mtuser]# kubectl get deploy -n test NAME READY UP-TO-DATE AVAILABLE AGE nginx-deploy 1/1 1 1 22s [root@master mtuser]# kubectl get pod -n test NAME READY STATUS RESTARTS AGE nginx-deploy-d64985c8d-hf22v 1/1 Running 0 28s
Pod 的状态为 running 了。
验证容器共享 pause 网络堆栈
查看容器
docker ps | grep nginx
[root@node1 mtuser]# docker ps | grep nginx 7f082c6d8a8a 9a32d3961954 "/docker-entrypoint.…" 3 minutes ago Up 3 minutes k8s_nginx_nginx-deploy-d64985c8d-hf22v_test_6eda457a-6325-4b6e-bfaa-c54de210e137_0 15ce88cf61d0 k8s.gcr.io/pause:3.1 "/pause" 3 minutes ago Up 3 minutes k8s_POD_nginx-deploy-d64985c8d-hf22v_test_6eda457a-6325-4b6e-bfaa-c54de210e137_0
查看 pause 容器网络堆栈
docker inspect 15ce88cf61d0 | grep -i sandboxkey
[root@node1 mtuser]# docker inspect 15ce88cf61d0 | grep -i sandboxkey "SandboxKey": "/var/run/docker/netns/7b77cf0f05e0",
这个 7b77cf0f05e0
就是 pause 容器的网络命名空间。
网络堆栈被存在目录下:/var/run/docker/netns/
此时使用 ip netns
是无法查看容器的网络命名空间,需要将容器网络命名空间映射出来。
映射容器网络堆栈
ln -s /var/run/docker/netns /var/run/netns
再次查看
进入目录:/var/run/netns
[root@node1 netns]# cd /var/run/netns [root@node1 netns]# ip netns 7b77cf0f05e0 (id: 1) d3134fca8796 (id: 0) default
下载 ifconfig:
yum install net-tools
查看 nets
ip netns exec 7b77cf0f05e0 ifconfig
[root@node1 netns]# ip netns exec 7b77cf0f05e0 ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450 inet 10.244.1.10 netmask 255.255.255.0 broadcast 10.244.1.255 ether 6e:18:df:9d:1d:9f txqueuelen 0 (Ethernet) RX packets 5 bytes 446 (446.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 1 bytes 42 (42.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 loop txqueuelen 1000 (Local Loopback) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
进入 nginx 容器对比 ip 地址
docker exec -it 7f082c6d8a8a bash
下载 ifconfig
apt-get update && apt-get install net-tools iputils-ping -y
[root@node1 netns]# docker exec -it 7f082c6d8a8a bash root@nginx-deploy-d64985c8d-hf22v:/# ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450 inet 10.244.1.10 netmask 255.255.255.0 broadcast 10.244.1.255 ether 6e:18:df:9d:1d:9f txqueuelen 0 (Ethernet) RX packets 5 bytes 446 (446.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 1 bytes 42 (42.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 loop txqueuelen 1000 (Local Loopback) RX packets 0 bytes 0 (0.0 B) RX errors 0 dro
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
本专刊适合于立志转行云计算的小白,有一定的编程、操作系统、计算机网络、数据结构、算法基础。 本专刊同时也适合于面向云计算(Docker + Kubernetes)求职的从业者。 本专刊囊括了云计算、VMWare、Docker、Kubernetes、Containerd等一系列知识点的讲解,并且最后总