为什么要学习容器?
软件开发人员
相信微服务架构(Microservice Architectur)会逐渐成为开发应用系统的主流。而容器则是这种架构的基石。市场将需要更多能够开发出基于容器的应用程序的软件开发人员。
IT 实施和运维工程师
容器为应用提供了更好的打包和部署方式。越来越多的应用将以容器的方式在开发、测试和生产环境中运行。掌握容器相关技术将成为实施和运维工程师的核心竞争力。
画一下Docker的架构图
默认Docker的镜像是集中放置在Docker Hub上的,docker在创建容器时,Docker会先检查本地是否有镜像,如果没有会到docker hub上去下载指定的镜像到本地,并且下载下来的镜像在容器使用结束后不会删除,镜像是不可修改的,只能重构。下面是docker的整体架构
Docker 的核心组件包括:
-
Docker 客户端 - Client
-
Docker 服务器 - Docker daemon
-
Docker 镜像 - Image
- Docker 容器 - Container
-
Registry:也叫Docker Hub,Docker的镜像仓库。
docker pull
命令可以从 Registry 下载镜像。
Docker 采用的是 Client/Server 架构。客户端向服务器发送请求,服务器负责构建、运行和分发容器。客户端和服务器可以运行在同一个 Host 上,客户端也可以通过 socket 或 REST API 与远程的服务器通信。
docker容器的四种网络模式:
none 网络模式:
就是什么都没有的网络。在这个网络下的容器除了 lo,没有其他任何网卡。容器创建时,可以通过 --network=none 指定使用 none 网络。一些对安全性要求高并且不需要联网的应用可以使用 none 网络。比如某个容器的唯一用途是生成随机密码,就可以放到 none 网络中避免密码被窃取。
Bridge 桥接模式:
Docker 安装时会创建一个 命名为 docker0 的 linux bridge。如果不指定--network,创建的容器默认都会挂到 docker0 上。
在没有创建容器时没有网络接口桥接在docker0上:
运行一个容器时,新出现一个网络接口veth1f82179被桥接在docker0上面
[root@client ~]# docker run -d nginx
[root@client ~]# brctl show
由上图可以看出容器有一个网卡 eth0。实际上 eth0 和 veth1f82179是一对 veth pair。veth pair 是一种成对出现的特殊网络设备,可以把它们想象成由一根虚拟网线连接起来的一对网卡,网卡的一头(eth0)在容器中,另一头(veth1f82179)挂在网桥 docker0 上,保证宿主机的网络报文若发往 veth1f82179,则立即会被 eth0 接收,实现宿主机到Docker Container 网络的联通性;同时,也保证 Docker Container 单独使用 eth0,实现容器网络环境的隔离性。
[root@client ~]# docker inspect cbbe6c00caf9 #网关是 172.17.0.1,指向docker0
(1) Docker Daemon 利用 veth pair 技术,在宿主机上创建两个虚拟网络接口设备,假设为
veth0 和 veth1。而 veth pair 技术的特性可以保证无论哪一个 veth 接收到网络报文,都会将
报文传输给另一方。
(2) Docker Daemon 将 veth0 附加到 docker0 网桥上。保证宿主机的网络报文可以发往 veth0;
(3) Docker Daemon 将 veth1 添加到 Docker Container 所属的 namespace 下,并被改名为 eth0。
如此一来,保证宿主机的网络报文若发往 veth0,则立即会被 eth0 接收,实现宿主机到
Docker Container 网络的联通性;同时,也保证 Docker Container 单独使用 eth0,实现容器网络环境的隔离性。
Host 网络模式:
host 模式是 bridge 桥接模式很好的补充。采用 host 模式的 Docker Container,可以直接使用
宿主机的 IP 地址与外界进行通信,若宿主机的 eth0 是一个公有 IP,那么容器也拥有这个公
有 IP。同时容器内服务的端口也可以使用宿主机的端口,无需额外进行 NAT 转换。当然,
有这样的方便,肯定会损失部分其他的特性,最明显的是 Docker Container 网络环境隔离性
的弱化,即容器不再拥有隔离、独立的网络栈。另外,使用 host 模式的 Docker Container 虽
然可以让容器内部的服务和传统情况无差别、无改造的使用,但是由于网络隔离性的弱
化,该容器会与宿主机共享竞争网络栈的使用;另外,容器内部将不再拥有所有的端口资
源,原因是部分端口资源已经被宿主机本身的服务占用,还有部分端口已经用以 bridge 网
络模式容器的端口映射。
[root@client website]# docker run -it --name vm3 --net host ubuntu --net指定网络模式为host主机模式
Container 网络模式:
(1) 查找 other container(即需要被共享网络环境的容器)的网络 namespace;
(2) 将新创建的 Docker Container(也是需要共享其他网络的容器)的 namespace,使用
other container 的 namespace。
Docker Container 的 other container 网络模式,可以用来更好的服务于容器间的通信。
在这种模式下的 Docker Container 可以通过 localhost 来访问 namespace 下的其他容器,传输
效率较高。虽然多个容器共享网络环境,但是多个容器形成的整体依然与宿主机以及其他
容器形成网络隔离。另外,这种模式还节约了一定数量的网络资源。但是需要注意的是,
它并没有改善容器与宿主机以外世界通信的情况。
[root@client website]# docker run -it --name vm2 ubuntu bash #先运行vm2,供新的使用
[root@client website]# docker run -it --name vm4 --net container:vm2 ubuntu # 指定以container模式运行