35. K8s 网络原理——Kubernetes 通信

本章讲解知识点

  • Kubernetes 的网络实现
  • 容器到容器之间的通信
  • 同一个 Node 上 Pod 之间的通信
  • 不同 Node 上 Pod 之间的通信

<br>

1. Kubernetes 的网络实现

Kubernetes 主要实现以下目标:

  1. 容器到容器之间的通信
  2. Pod 到 Pod 之间的通信
  3. Pod 到 Service 的通信
  4. 集群内部与外部组件之间的通信

<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等一系列知识点的讲解,并且最后总

全部评论

相关推荐

程序员小白条:投太少了,多投点吧,二本就海投,然后简历上加点奖项或者四六级之类的,别管有没有用,另外最好搞下个人博客,定期输出一些文章和学习总结,也可以去github参与一下开源项目提一些PR,总会有中小公司看的上的
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务