linux怎么查看本机内存大小
230
2022-10-13
k8s之网络
Kubernetes 作为编排引擎管理着分布在不同节点上的容器和 Pod。Pod、Service、外部组件之间需要一种可靠的方式找到彼此并进行通信,Kubernetes 网络则负责提供这个保障。本章包括如下内容:
Kubernetes 网络模型 各种网络方案 Network Policy
Kubernetes 网络模型
Kubernetes 采用的是基于扁平地址空间的网络模型,集群中的每个 Pod 都有自己的 IP 地址,Pod 之间不需要配置 NAT 就能直接通信。另外,同一个 Pod 中的容器共享 Pod 的 IP,能够通过 localhost 通信。
这种网络模型对应用开发者和管理员相当友好,应用可以非常方便地从传统网络迁移到 Kubernetes。每个 Pod 可被看作是一个个独立的系统,而 Pod 中的容器则可被看做同一系统中的不同进程。
下面讨论在这个网络模型下集群中的各种实体如何通信。知识点前面都已经涉及,这里可当做复习和总结。
Pod 内容器之间的通信
当 Pod 被调度到某个节点,Pod 中的所有容器都在这个节点上运行,这些容器共享相同的本地文件系统、IPC 和网络命名空间。
不同 Pod 之间不存在端口冲突的问题,因为每个 Pod 都有自己的 IP 地址。当某个容器使用 localhost 时,意味着使用的是容器所属 Pod 的地址空间。
比如 Pod A 有两个容器 container-A1 和 container-A2,container-A1 在端口 1234 上监听,当 container-A2 连接到 localhost:1234,实际上就是在访问 container-A1。这不会与同一个节点上的 Pod B 冲突,即使 Pod B 中的容器 container-B1 也在监听 1234 端口。
Pod 之间的通信
Pod 的 IP 是集群可见的,即集群中的任何其他 Pod 和节点都可以通过 IP 直接与 Pod 通信,这种通信不需要借助任何的网络地址转换、隧道或代理技术。Pod 内部和外部使用的是同一个 IP,这也意味着标准的命名服务和发现机制,比如 DNS 可以直接使用。
Pod 与 Service 的通信
Pod 间可以直接通过 IP 地址通信,但前提是 Pod 得知道对方的 IP。在 Kubernetes 集群中, Pod 可能会频繁的销毁和创建,也就是说 Pod 的 IP 不是固定的。为了解决这个问题,Service 提供了访问 Pod 的抽象层。无论后端的 Pod 如何变化,Service 都作为稳定的前端对外提供服务。同时,Service 还提供了高可用和负载均衡功能,Service 负责将请求转发给正确的 Pod。
外部访问
无论是 Pod 的 IP 还是 Service 的 Cluster IP,它们只能在 Kubernetes 集群中可见,对集群之外的世界,这些 IP 都是私有的。
Kubernetes 提供了两种方式让外界能够与 Pod 通信:
NodePort Service 通过 Cluster 节点的静态端口对外提供服务。外部可以通过
k8s网络方案
网络模型有了,如何实现呢?
为了保证网络方案的标准化、扩展性和灵活性,Kubernetes 采用了 Container Networking Interface(CNI)规范。
CNI 是由 CoreOS 提出的容器网络规范,它使用了插件(Plugin)模型创建容器的网络栈。
CNI 的优点是支持多种容器 runtime,不仅仅是 Docker。CNI 的插件模型支持不同组织和公司开发的第三方插件,这对运维人员来说很有吸引力,可以灵活选择适合的网络方案。
目前已有多种支持 Kubernetes 的网络方案,比如 Flannel、Calico、Canal、Weave Net 等。因为它们都实现了 CNI 规范,用户无论选择哪种方案,得到的网络模型都一样,即每个 Pod 都有独立的 IP,可以直接通信。区别在于不同方案的底层实现不同,有的采用基于 VxLAN 的 Overlay 实现,有的则是 Underlay,性能上有区别。再有就是是否支持 Network Policy。
Network Policy
Network Policy 是 Kubernetes 的一种资源。Network Policy 通过 Label 选择 Pod,并指定其他 Pod 或外界如何与这些 Pod 通信。
默认情况下,所有 Pod 是非隔离的,即任何来源的网络流量都能够访问 Pod,没有任何限制。当为 Pod 定义了 Network Policy,只有 Policy 允许的流量才能访问 Pod。
不过,不是所有的 Kubernetes 网络方案都支持 Network Policy。比如 Flannel 就不支持,Calico 是支持的。我们接下来将用 Canal 来演示 Network Policy。Canal 这个开源项目很有意思,它用 Flannel 实现 Kubernetes 集群网络,同时又用 Calico 实现 Network Policy。
部署 Canal
部署 Canal 与部署其他 Kubernetes 网络方案非常类似,都是在执行了 kubeadm init 初始化 Kubernetes 集群之后通过 kubectl apply 安装相应的网络方案。也就是说,没有太好的办法直接切换使用不同的网络方案,基本上只能重新创建集群。
要销毁当前集群,最简单的方法是在每个节点上执行 kubeadm reset。然后初始化集群。
kubeadm init --apiserver-advertise-address 192.168.56.105 --pod-network-cidr=10.244.0.0/16
然后按照文档 安装 Canal。文档列出了各种网络方案的安装方法:
执行如下命令部署 Canal
kubectl apply -f Canal 相关组件:
Canal 作为 DaemonSet 部署到每个节点,地属于 kube-system 这个 namespace。
Canal 准备就绪,下节我们将实践 Network Policy。
实践 Network Policy
为了演示 Network Policy,我们先部署一个 应用,其配置文件 为:
apiVersion: apps/v1beta1 kind: Deployment metadata: name: httpd spec: replicas: 3 template: metadata: labels: run: httpd spec: containers: - name: httpd image: httpd:latest imagePullPolicy: IfNotPresent ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: httpd-svc spec: type: NodePort selector: run: httpd ports: - protocol: TCP nodePort: 30000 port: 8080 targetPort: 80
有三个副本,通过 NodePort 类型的 Service 对外提供服务。部署应用:
[root@k8s-master ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
1/1 Running 0 63s 10.244.2.3 k8s-node2
当前没有定义任何 Network Policy,验证应用可以被访问:
启动一个 busybox Pod,可以访问 Service,也可以 Ping 到副本 Pod。
[root@k8s-master ~]# kubectl run busybox --rm -it --image=busybox /bin/sh kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead. If you don't see a command prompt, try pressing enter. / # wget httpd-svc:8080 Connecting to (10.108.126.45:8080) saving to 'index.html' index.html 100% |**********************************************************************************************************| 45 0:00:00 ETA 'index.html' saved / # ping 10.244.2.3 PING 10.244.2.3 (10.244.2.3): 56 data bytes 64 bytes from 10.244.2.3: seq=0 ttl=62 time=1.316 ms 64 bytes from 10.244.2.3: seq=1 ttl=62 time=0.862 ms 64 bytes from 10.244.2.3: seq=2 ttl=62 time=1.204 ms ^C --- 10.244.2.3 ping statistics --- 3 packets transmitted, 3 packets received, 0% packet loss round-trip min/avg/max = 0.862/1.127/1.316 ms / # exit
集群节点可以访问 Service, 也可以 Ping 到副本 Pod。
[root@k8s-node1 ~]# curl 10.108.126.45:8080
It works! [root@k8s-node1 ~]# ping -c 3 10.244.2.3 PING 10.244.2.3 (10.244.2.3) 56(84) bytes of data. 64 bytes from 10.244.2.3: icmp_seq=1 ttl=63 time=0.732 ms 64 bytes from 10.244.2.3: icmp_seq=2 ttl=63 time=0.824 ms ^C --- 10.244.2.3 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1000ms rtt min/avg/max/mdev = 0.732/0.778/0.824/0.046 ms集群外(192.168.56.1)可以访问 Service。
现在创建如下 Network Policy:
kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: access-httpd spec: podSelector: matchLabels: run: httpd ingress: - from: - podSelector: matchLabels: access: "true" ports: - protocol: TCP port: 80
① 定义将此 Network Policy 中的访问规则应用于 label 为 run: 的 Pod,即 应用的三个副本 Pod。
② ingress 中定义只有 label 为 access: "true" 的 Pod 才能访问应用。
③ 只能访问 80 端口。
通过 kubectl apply 创建 Network Policy。
[root@k8s-master ~]# kubectl apply -f policy.yml networkpolicy.networking.k8s.io/access-created [root@k8s-master ~]# kubectl get networkpolicies. NAME POD-SELECTOR AGE access- run= 32s
验证 Network Policy 的有效性:
busybox Pod 已经不能访问 Service。
[root@k8s-master ~]# kubectl run busybox --rm -it --image=busybox /bin/sh kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead. If you don't see a command prompt, try pressing enter. / # wget --timeout=5 Connecting to (10.108.126.45:8080) wget: download timed out / # exit
如果 Pod 添加了 label access: "true" 就能访问到应用,但 Ping 已经被禁止。
[root@k8s-master ~]# kubectl run busybox --rm -it --labels="access=true" --image=busybox /bin/sh kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead. If you don't see a command prompt, try pressing enter. / # wget httpd-svc:8080 Connecting to (10.108.126.45:8080) saving to 'index.html' index.html 100% |**********************************************************************************************************| 45 0:00:00 ETA 'index.html' saved / # ping 10.244.2.3 PING 10.244.2.3 (10.244.2.3): 56 data bytes ^C --- 10.244.2.3 ping statistics --- 68 packets transmitted, 0 packets received, 100% packet loss / # exit
集群节点已经不能访问 Service, 也 Ping 不到副本 Pod。
[root@k8s-node1 ~]# curl 10.108.126.45:8080 ^C [root@k8s-node1 ~]# ping -c 3 10.244.2.3 PING 10.244.2.3 (10.244.2.3) 56(84) bytes of data. ^C --- 10.244.2.3 ping statistics --- 3 packets transmitted, 0 received, 100% packet loss, time 1999ms
集群外(192.168.56.1)已经不能访问 Service。
[root@k8s-node1 ~]# curl 192.168.77.10:30000 --connect-timeout 5 curl: (28) Connection timed out after 5001 milliseconds
如果希望让集群节点和集群外(192.168.56.1)也能够访问到应用,可以对 Network Policy 做如下修改:
应用新的 Network Policy:
现在,集群节点和集群外(192.168.56.1)已经能够访问了:
除了通过 ingress 限制进入的流量,也可以用 egress 限制外出的流量。大家可以参考官网相关文档和示例,这里就不赘述了。
小结Kubernetes 采用的是扁平化的网络模型,每个 Pod 都有自己的 IP,并且可以直接通信。 CNI 规范使得 Kubernetes 可以灵活选择多种 Plugin 实现集群网络。 Network Policy 则赋予了 Kubernetes 强大的网络访问控制机制。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~