Kubernetes技术分析之网络
来源:互联网 发布:js数组的排序函数 编辑:程序博客网 时间:2024/05/21 19:33
概述
Docker的流行激活了一直不温不火的PaaS,随着而来的是各类Micro-PaaS的出现,Kubernetes是其中最具代表性的一员,它是Google多年大规模容器管理技术的开源版本。本系列文章将逐一分析Kubernetes,本文说明 Kubernetes网络模型的特点和实现方式。
Kubernetes网络
Kubernetes采用扁平化的网络模型,每个Pod都有一个全局唯一的IP(IP-per-pod),Pod之间可以跨主机通信,相比于Docker原生的NAT方式来说,这样使得容器在网络层面更像虚拟机或者物理机,复杂度整体降低,更加容易实现服务发现,迁移,负载均衡等功能。
为了实现这个目标,Kubernetes中需要解决4个问题:
容器间通信
Pod是容器的集合,Pod包含的容器都运行在同一个Host上,并且拥有同样的网络空间。现在创建一个Pod,包含2个Container:
web-pod.yaml:
apiVersion: v1kind: Podmetadata:name: webpodlabels:name: webpodspec:containers:- name: webpod80 image: jonlangemak/docker:web_container_80 ports: - containerPort: 80 hostPort: 80- name: webpod8080 image: jonlangemak/docker:web_container_8080 ports: - containerPort: 8080 hostPort: 8080
Pod运行成功后,在其所在的Node上查询容器:
$ docker psCONTAINER ID IMAGE PORTS 63dc7e032ab6 jonlangemak/docker:web_container_8080 4ac1a5156a04 jonlangemak/docker:web_container_80 b77896498f8f gcr.io/google_containers/pause:0.8.0 0.0.0.0:80->80/tcp, 0.0.0.0:8080->8080/tcp
可以看到运行了3个容器,其中2个这是Pod定义好的,第3个运行的容器镜像 是gcr.io/google_containers/pause,它是Netowrk Container,它不做任何事情,只是用来接管Pod的网络。
通过docker inspect查看着几个容器的信息,可以看出Pod中定义的容器的网络设置都集中配置在了Netowrk Container上,然后再加入Netowrk Container的网络中。这样的好处是避免服务容器之间产生依赖,用一个简单的容器来统一管理网络。
Pod间通信
Pod间通信是使用一个内部IP,这个IP即使Netowrk Container的IP。
以web-pod为例:
$ kubectl describe pod webpodName: webpodNamespace: defaultIP: 10.1.14.51...$ docker inspect b77896498f8f |grep IPAddress "IPAddress": "10.1.14.51",
对应用来说,这个IP是应用能看到,并且是可以对外宣称的(服务注册,服务发现);而NAT方式,应用能看到的IP是不能对外宣称的(必须要使用主机IP+port方式),端口本身就是稀缺资源,并且ip+port的方式,无疑增加了复杂度,这就是IP-per-pod的优势所在。
那么第一个问题就是,如何保证Pod的IP是全局唯一的。其实做法也很简单,因为Pod的IP是docker bridge分配的,不同Node之间docker bridge配置成不同的网段。
- node1: docker -d --bip=10.1.79.1/24 ...
- node2: docker -d --bip=10.1.14.1/24 ...
- node3: docker -d --bip=10.1.58.1/24 ...
同一个Node上的Pod原生能通信,但是不同Node之间的Pod如何通信的,这就需要对Docker进行增强,现有的方案有Flannel,OpenVSwitch,Weave等。本文Kubernetes环境是采用Flannel。
Flannel
由CoreOS团队针对Kubernetes设计的一个覆盖网络工具,Flannel 通过在集群中创建一个覆盖网络为主机设定一个子网。通过隧道协议(支持udp,vxlan)封装容器之间的通信报文,实现跨主机通信。
Pod到Service通信
Pod本身是变化的,比如当Pod发生迁移,那么Pod的IP是变化的, 那么Service的就是在Pod之间起到中转和代理的作用,Service会生成一个虚拟IP, 这个虚拟IP负载均衡到后端的Pod的IP。现在为上面的web-pod创建service:
web-service.yaml:
apiVersion: v1kind: Servicemetadata:name: webservicelabels:name: webservicespec:ports:- name: web-80 port: 80 containerPort: 80- name: web-8080 port: 8080 containerPort: 8080selector:name: webpod
然后查询Service的VIP和后端Pod的IP:
$ kubectl describe service webserviceName: webserviceNamespace: defaultLabels: name=webserviceSelector: name=webpodType: ClusterIPIP: 10.254.85.33Port: web-80 80/TCPEndpoints: 10.1.14.51:80Port: web-8080 8080/TCPEndpoints: 10.1.14.51:8080Session Affinity: NoneNo events.
那么访问web-pod则可以通过10.254.85.33。这主要是Kube-Proxy在其作用,在每台Node上都会部署一个Kube-Proxy,Kube-Proxy对于每个Service会启用端口监听,并配合iptables定向到该端口,现在在一台Node上查询:
$ iptables-save...-A KUBE-PORTALS-HOST -d 10.254.85.33/32 -p tcp -m comment --comment "default/webservice:web-80" -m tcp --dport 80 -j DNAT --to-destination 192.168.3.146:56610-A KUBE-PORTALS-HOST -d 10.254.85.33/32 -p tcp -m comment --comment "default/webservice:web-8080" -m tcp --dport 8080 -j DNAT --to-destination 192.168.3.146:50871
对于Web-Service,Kube-Proxy创建2条iptables规则:
1.目的IP为10.254.85.33,目的端口为80的报文DNAT到192.168.3.146:56610
2.目的IP为10.254.85.33,目的端口为8080的报文DNAT到192.168.3.146: 50871
$ lsof -i:56610COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAMEkube-prox 2537 root 16u IPv6 26353463 0t0 TCP *:56610 (LISTEN)$ lsof -i:50871COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAMEkube-prox 2537 root 17u IPv6 26353485 0t0 TCP *:50871 (LISTEN)
可以看到Kube-Proxy监听在56610和50871,对于访问的报文将转发到后端Pod。对于Pod的变化,Kube-Proxy会及时刷新。
还需要注意的是,当前Kube-Proxy只是3层"(TCP/UDP over IP) 转发,当后端有多个Pod的时候,Kube-Proxy默认采用随机方式进行选择,也可以设置成基于CLientIP的会话保持。
外网到内网的通信
目前为止,以上部分都是在讨论Kubernetes内部网络的通信,但是外网如何访问到Kubernetes上的应用,因为内网的IP是无法直接访问的(需要KubeProxy和Flannel的工作),这时候就需要一个外部路由模块来连接外网和内网。
参考
- https://github.com/GoogleCloud ... ng.md
- http://www.dasblinkenlichten.c ... king/
- https://github.com/GoogleCloud ... oxies
- Kubernetes技术分析之网络
- Kubernetes技术分析之网络
- Kubernetes技术分析之入门
- Kubernetes技术分析之DNS
- Kubernetes技术分析之存储
- Kubernetes技术分析之监控
- Kubernetes技术分析之监控
- Kubernetes技术分析之资源管理
- Kubernetes技术分析之灰度升级
- kubernetes之Scheduler分析
- kubernetes 网络框架源码分析
- kubernetes源码分析之RBAC
- kubernetes之pod状态分析
- 理解Kubernetes网络之Flannel网络
- 容器编排之Kubernetes网络隔离NetworkPolicy
- Kubernetes对象(网络)之Ingress
- kubernetes 网络
- kubernetes源码阅读之整体架构分析
- [组合数学 思路题] BZOJ 4402 Claris的剑
- Windows下创建线程的方法_beginThread和CreateThread区别
- Docker中的网络详解以及与OpenStack网络对比
- 阻塞与非阻塞
- oradebug
- Kubernetes技术分析之网络
- [CS]C#操作word
- SpringMVC异常处理综述
- nginx、fastCGI、php-fpm关系梳理
- Actual Practise : Row_Number() over(partition by colnum1 order by colnum2 ) as No - 7
- Facebook申请应用
- Hibernate注解方式多种映射
- 日志库选择
- 【笔试/面试】—— 二叉树的最远距离