美文网首页思科ACI程序员工具癖
Kubernetes初探:网络技术原理

Kubernetes初探:网络技术原理

作者: 点融黑帮 | 来源:发表于2016-12-22 16:59 被阅读2094次

    1、什么是Kubernetes?

    Kubernetes(k8s) 源于古希腊语,意寓为舵手,管理者。Kubernetes 是Google开源的容器集群管理系统,其提供应用部署、维护、扩展机制等功能,利用Kubernetes能方便地管理跨机器运行容器化的应用。

    其主要功能如下:

    以集群的方式运行、管理跨机器的容器;

    解决Docker 跨机器容器之间的通讯问题;

    Kubernetes 的自我修复机制使得容器集群总是运行在用户期望的状态。

    实际上使用Kubernetes 只需要一个部署文件,使用一条命令就可以部署一个完整集群(以官网部署k8s 的dashboard 为例):

    kubectl create -fhttps://rawgit.com/kubernetes/dashboard/master/src/deploy/kubernetes-dashboard.yaml

    现在先介绍一些核心的概念:

    Pods:是连接在一起的容器组合并共享文件卷。它们是最小的部署单元,由 Kubernetes 统一创建、调度、管理;

    Replication controllers:管理 Pods 的生命周期, 它们确保指定数量的Pods 会一直运行;

    Labels:被用来管理和选取基于键值对为基础的对象组;

    Services:提供独立、可靠名称和地址的 Pods 集合,它就像一个基础版本的负载均衡器;

    Node:相对master是工作主机,也叫Minon,物理机、虚拟机均可。

    Namespace:不同的namespace 形成逻辑上不同的项目或用户组。

    Volume:Pod 中被多个容器访问的共享目录。

    下图是典型的Kubernetes 的架构图:

    在开始了解Kubernetes 的网络原理之前,我们先来看下docker 的网络模型。

    2、Docker的网络模型

    docker network ls 这个命令用于列出所有当前主机上的网络:

    在默认情况下会看到三个网络,它们是DockerDeamon 进程创建的。标准的Docker 支持一下4种网络模式:

    Bridge模式:使用—net=bridge指定。容器使用独立网络Namespace,并连接到docker0虚拟网卡(默认模式);

    None模式:使用—net=none指定。容器没有任何网卡,适合不需要与外部通过网络通信的容器;

    Host模式:使用—net=host指定。容器与主机共享网络Namespace,拥有与主机相同的网络设备;

    Container模式:使用—net=container:NAME_or_ID指定。

    在Kubernetes 的管理模式下,通常只使用bridge 模式。在bridge 模式下,DockerDaemon 第一次启动时创建一个虚拟的网桥,缺省名字是docker0,然后按照RPC1918的模型,在私有网络空间中给这个网桥分配一个子网。Docker 创建出来的每一个容器,都会创建一个虚拟的Veth 设备对,其中一端关联到网桥上,另一端用Linux 的网络命名空间技术,映射到容器内的eth0设备,然后在网桥的地址段内分配一个IP地址。

    Docker的缺省桥接网络模型:

    虚拟化技术中最为复杂的就是虚拟化网络技术,也是门槛很高的技术领域,Docker 很明智的早期并没有提供跨主机的解决方案。

    3、什么是kubernetes网络模型?

    Kubernetes 网络设计的一个基本原则是:每个Pod 都有一个全局唯一的IP,  而且假定所有的Pod 都在一个可以直接连通的,扁平的网络空间中,Pod 之间可以跨主机通信,按照这种网络原则抽象出来的一个Pod 对应一个IP的设计模型也被称作IP-per-Pod 模型。

    相比于Docker 原生的NAT方式来说,这样使得容器在网络层面更像虚拟机或者物理机,复杂度整体降低,更加容易实现服务发现,迁移,负载均衡等功能。

    容器间的通信

    创建的dashboard 容器信息:

    在yaml 文件中你可以发现我们设置的replicas 的数量是1,但是却发现了两个容器在运行,第二个image名为gcr.io/google_containers/pause:2.0,那么第二个容器从何而来?

    执行下图中的命令可以发现:

    第二个容器和第一个容器共享网络命名空间。第一个容器是Netowrk Container,它不做任何事情,只是用来接管Pod 的网络。这样做的好处在于避免容器间的相互依赖,使用一个简单的容器来统一管理网络。

    Pod 间的通信

    Pod 间的通信使用的是一个内部IP,这个IP就是Network Container 的IP。

    以dashboard 为例:

    同一个Node 上的Pod 通过Veth 连接在同一个docker0 网桥上,地址段相同,原生能通信。但是不同Node 之间的Pod 如何通信的,本质是在网路上再架设一层overlay network 使容器的网络运行在这层overlay 网络上。现有的方案有Flannel,OpenVSwitch,Weave 等。本文Kubernetes 环境是采用Flannel。

    Flannel 使用Linux 通用TUN/ TAP 设备, 并使用UDP 封装IP 数据包创建一个覆盖网络。它使用etcd 维护子网的分配和overlay 网络和实际IP 的映射。

    下图是Flannel 的原理图:

    Pod 到Service 通信

    查看dashboard 的Service 的VIP(Virtual IP) 和后端Pod 的IP:

    那么dashboard 就可以通过10.254.104.235来进行访问,执行iptables-save:

    然后执行lsof –i:30250:

    可以看到Kube-Proxy 进程监听在30250端口上,这个进程可以看做是Service 的透明代理兼负载均衡器,对于Service 的访问请求将被这个进程转发到后端Pod。

    对于Pod 的变化会及时刷新。那么Service 就是在Pod 间起到中转和代理的作用。

    下图中可以很好的反映整个流程:

    当一个客户端访问这个Service 时,这些iptable 规则就开始起作用,客户端的流量被重定向到Kube-Proxy 为这个Service 打开的端口上,Kube-Proxy 随机选择一个后端Pod 来进行服务。

    外部到内部的通信

    Kubernetes 支持两种对外服务的Service 的Type 定义:NodePort 和LoadBalancer。

    NodePort:在每个Node 上打开一个端口并且每个Node 的端口都是一样的,通过:NodePort 的方式,Kubernetes 集群外部的程序可以访问Service;

    LoadBalancer:通过外部的负载均衡器来访问。

    参考:

    https://github.com/kubernetes/kubernetes/blob/a6fdc50265c9e2831db66b92b23b41e0266387ce/docs/user-guide/services.md#virtual-ips-and-service-proxies

    https://github.com/kubernetes/kubernetes/blob/v1.0.1/docs/design/networking.md

    http://www.dasblinkenlichten.com/kubernetes-101-networking/

    本文作者:陈玉(点融黑帮),点融infra团队运维开发工程师, 爱点融, 爱自然, 爱生活。

    相关文章

      网友评论

        本文标题:Kubernetes初探:网络技术原理

        本文链接:https://www.haomeiwen.com/subject/szkhvttx.html