前言
Kubernetes 技术背后的基石 -- 容器化的底层知识
一、LXC
LXC(Linux Containers)是一种基于 Linux 的内核级虚拟化技术。它将应用软件打包成一个软件容器,内含应用软件本身代码以及所需要的操作系统核心、相关依赖库,创造出应用程序独立的沙箱运行时环境。google 是 lxc 最大的支持者,k8s 未开源前在 google 内部使用的就是 lxc。
### 创建ubuntu容器
# lxc-create -n <container> -t ubuntu
### 在容器中运行程序
# lxc-execute -n <container> [-f config_file] [ -s KEY=VAL ] command
在容器中运行的程序可以被环境隔离,访问的硬件资源也被受限使用,这里面涉及两个核心技术namespaces、cgroups。
1.1 Linux Namespaces
namespace提供一种隔离机制,让不同的namespace下的进程看到的全局资源不同,每一个namespace有一个自己独立的全局资源实例。
1.2 Linux cgroups
cgroups(control groups)是Linux内核的一个功能,用来限制、控制与分离一个进程组的资源(如CPU、内存、磁盘输入输出等)。这个项目最早由Google发起,并且被加入到2.6.24及之后的内核中去。
1.3 容器技术发展历史
二、Docker
2.1 发展历史
2010 年,几个搞 IT 的年轻人在美国旧金山成立了一家名叫 dotCloud 的公司向用户提供PaaS服务。底层技术上,dotCloud 平台使用了LXC 容器技术,为了方便创建和管理这些容器,开发了一套内部工具,之后被命名为“Docker”,Docker就是这样诞生的。
作为一家小型创业企业,在激烈的竞争之下也是步履维艰。正当他们快要坚持不下去的时候,脑子里蹦出了“开源”的想法,于是2013年3月Docker项目被开源。随后越来越多的工程师发现了Docker的优点,纷纷加入 Docker 开源社区,Docker得以快速的发展,甚至像Google、微软、Amazon、 VMware 这样的巨头们都对它青睐有加,表示将全力支持。Docker 火了之后,dotCloud公司干脆把公司名字也改成了 Docker Inc.。之后,又由于商业化的考虑 2017 年 Docker 改名为 moby。
2.2 LXC vs Docker
- 镜像
Docker中支持 Dockerfile,将应用的所有依赖项,构建工具和包都以源码的形式写在 Dockerfile 中,然后 Docker 可以根据 Dockerfile 构建镜像。该镜像在任何机器上面运行的效果都一样。 - 版本控制
Docker对容器提供了类 git 的版本控制功能,支持版本回滚等功能。Docker也实现了增量上传和下载的功能,节约了上传和下载时的带宽资源。 - 组件复用
一个镜像可以作为基础镜像来创建更多特定的镜像,镜像之间支持多层重用。 - Docker 文件系统
对于Docker来说,联合文件系统可以说是其镜像和容器的基础。联文件系统可以使得Docker把镜像做成分层结构,从而使得镜像的每一层都可以被共享节省大量的存储空间。联合文件系统更多的是一种概念或者标准,真正实现才是关键,当前 Docker 中常见的联合文件系统有三种:AUDFS、DeviceMapper、OverlayFS。
2.3 Docker 网络
2.3.1 主机内网络模式
当使用docker run创建Docker容器时,可以用–net选项指定容器的网络模式,docker有 host、container、none、bridge 等4种网络模式。
- host 模式
如果启动容器的时候使用 host 模式,那么这个容器将不会获得一个独立的 Network Namespace,而是和宿主机共用一个 Network Namespace。容器将不会虚拟出自己的网卡,配置自己的 IP 等,而是使用宿主机的 IP 和端口。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。使用 host 模式的容器可以直接使用宿主机的 IP 地址与外界通信,容器内部的服务端口也可以使用宿主机的端口,不需要进行 NAT,host 最大的优势就是网络性能比较好,但是 docker host上已经使用的端口就不能再用了,网络的隔离性不好。 - bridge 模式
当 Docker 进程启动时,会在主机上创建一个名为 docker0 的虚拟网桥,此主机上启动的 Docker 容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。从 docker0 子网中分配一个IP给容器使用,并设置 docker0 的IP地址为容器的默认网关。在主机上创建一对虚拟网卡 veth pair 设备,Docker将 veth pair 设备的一端放在新创建的容器中,并命名为 eth0(容器的网卡),另一端放在主机中,以 vethxxx 这样类似的名字命名,并将这个网络设备加入到docker0网桥中。可以通过brctl show
命令查看。bridge 模式是 docker 的默认网络模式,不写--net
参数,就是 bridge 模式。使用docker run -p
时,docker 实际是在 iptables 做了 DNAT 规则,实现端口转发功能。可以使用iptables -t nat -vnL
查看。 - container 模式
这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信。 - none 模式
使用none模式,Docker容器拥有自己的 Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个 Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。这种网络模式下容器只有 lo 回环网络,没有其他网卡。none 模式可以在容器创建时通过--network=none
来指定。这种类型的网络没有办法联网,封闭的网络能很好的保证容器的安全性。
2.3.2 跨主机网络模式
上述四种模式都是针对宿主机与其中的容器进行通信的,并不涉及跨宿主机的网络通信,起初开发 docker 时也没有过多考虑这方面,如果希望跨主机通信,一般有几种方法:
- bridge 端口映射,直接把容器的服务端口映射到主机上,主机直接通过映射出来的端口通信。
- host 模式,但有端口冲突。
- SDN方案:原生overlay、第三方方案:flannel、calico、weaved等等。
- macvlan。
1. macvlan
macvlan 是一种网卡虚拟化技术,将一张物理网卡虚拟化出多个网卡,每个都用独立的mac地址和ip地址。
优点:
- 性能好,macvlan 不需要创建 linux bridge,数据包直接通过物理网卡出去。
缺点:
- vlan 子接口和需要提前划出来,ip 地址使用需要自己手动去配置。
- vlan 数量有限,不适合大型公有云应用。
- Macvlan 的缺点是需要将主机网卡(NIC)设置为混杂模式(Promiscuous Mode),这在大部分公有云平台上是不允许的。
2. Flannel
Flannel 是一种基于 overlay 网络的跨主机容器网络解决方案,将 TCP 数据包封装在另一种网络包里面进行路由转发和通信,其中数据包转发需要注册中心。
10.1.15.2 想访问 10.1.20.2,数据包从容器中发出后,宿主机从注册中心查找到 10.1.20.2 在 174.24.8.112 上,用 udp 协议重新封装数据包发给174.24.8.112。
3. Calico
在主机1上设置docker内部流量到docker0的规则
iptables -t nat -I PREROUTING -s 10.0.128.0/24 -d 10.0.129.0/24 -j DNAT --to 10.0.128.1
主机1上添加路由,发送到主机2中docker容器(10.0.129.0/24)的数据包先发送到主机2上
route add -net 10.0.129.0/24 gw 192.168.91.129
在主机2上设置docker内部流量到docker0的规则
iptables -t nat -I PREROUTING -s 10.0.129.0/24 -d 10.0.128.0/24 -j DNAT --to 10.0.129.1
同理主机2上也添加类型的路由
route add -net 10.0.128.0/24 gw 192.168.91.128
解决跨主机通信,总体来看要考虑几方面:
- 是否支持公有云、私有云多租户隔离。
- 是否简单易实施。
- 转发性能。
2.4 Docker三剑客
由于docker仅是dotCloud公司paas产品中的一部分,并不具备完整的paas平台功能,因此docker社区后续又开发了Compose、Machine、Swarm等工具(docker三剑客)完善paas平台建设,于此同时google也开源了与之类似的k8s进行paas平台建设,在竞争中最终k8s胜出。
发表评论 取消回复