` docker(一) | 听云轩

docker(一)

什么是docker

    docker是基于GO语言和遵循apache2.0协议实现的开源容器引擎。docker可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化

    应用场景:

    1、web应用的自动化打包和发布

    2、自动化测试和持续集成、发布

    3、在服务型环境中部署和调整数据库或者其他的后台应用

    4、从头编译或者扩展现有的openshift或者cloud foundry平台来搭建自己的PaaS

    优点:

    1、更快速的交付和部署

    使用docker,开发人员可以使用镜像来快速构建一套标准开发环境,然后使用完全相同的环境来部署代码。可以快速创建和删除容器,节约开发、测试、部署的大量时间。

    2、更高效的资源利用

    运行docker容器不需要额外的虚拟化管理程序的支持,它本身就是内核级的虚拟化,可以实现更高的性能,同时对资源的额外的需求很低。

    3、更轻松的迁移和扩展

    docker几乎可以在任意的平台上运行,包括物理机、虚拟机、公有云、私有云、个人PC,服务器等,同时支持主流的操作系统。具有高兼容性

    4、更简单的更新管理

    使用dockerfile,只需要进行小小的配置修改,就可以代替以往大量的更新工作,所有修改都已增量的方式被分布和更新,从而实现自动化并且高效的容器管理。

关于docker的安装

1
2
3
4
5
yum install -y yum-util device-mapper-persistent-data lvm2
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum makecache fast
yum install -y docker-ce
systemctl enable docker && systemctl start docker

配置docker的加速:

V9ZKnU.png

1
2
systemctl daemon-reload
systemctl restart docker

6种namespaces

    1、UTS:实现主机名和域名隔离

    2、User:实现用户组和用户隔离

    3、Mount:实现挂载点(文件系统)隔离

    类似于chroot,mount命名空间可以将一个进程的根文件系统限制到一个特定的目录下。

    挂载命名空间允许不同命名空间的进程看到的本地文件位于宿主机不同路径下,每个命名空间中的进程所看到的的文件目录彼此是隔离的。也就是,不同命名空间中的进程,都认为自己独自占了一个完整的根文件系统(rootfs),但是实际上,不同命名空间中的文件彼此隔离,不会造成互相影响。

    4、IPC:实现信号量、消息队列和共享内存隔离

    5、Pid:进程隔离

Linux通过进程命名空间来 管理进程号,对于同一个进程,在不同的命名空间里有不同的进程号,每个进程命名空间有一套自己的进程号管理方法。进程命名空间是一个父子关系结构,子空间中的进程对于父空间是可见的。新fork出来的一个进程,在父命名空间和子命名空间将分别对应不同的进程号:

Zy8p6S.png

    然后我们用pstree,查看进程树:

Zy8FTs.png

6、Net:网络设备,网络栈、端口等隔离

    一个网络命名空间为进程提供了一个完全独立的网络协议栈的视图,包括ipv4和ipv6协议栈,ip路由表,防火墙规则等。这样每个容器的网络就能隔离开来。可以使用docker network ls查看当前主机上存在的网桥。

    使用brctl工具还可以看见连接在网桥上的虚拟网口的信息。每个容器默认分配了一个网桥上的虚拟网口,并将docker0的IP地址设置为默认的网关。容器发起的网络流量通过宿主机的iptables规则进行转发。

    在内核3.8以后,用户就可以在proc/[pid]/ns文件下看到指向不同namespace号的文件,如下图,其中$$表示当前运行的进程号:

ZEFxl6.png

    如果两个进程指向的namespace相同,就说明他们在同一个namespace下,否则不是。

关于docker的四种网络模式

    基于docker run创建docker容器的时候,可以使用–net选项来指定容器的网络模式,默认有以下四种网络模式:

  • host模式,使用–net=host指定

    容器将不会获得一个独立的network namespace,而是与宿主机共用一个network namespace,容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。

  • container模式,使用–net=container:NAME_OR_ID指定

    模式指定新创建的容器和已经存在的一个容器共享一个network namespace,除了网络方面相同一样,其他的像文件系统、进程列表还是隔离的,两个容器的进程通过lo网卡进行通信。

  • none模式,使用–net=none指定

    如果docker处于这个模式下,docker容器拥有自己的network namespace,但是并不为docker容器进行任何网络配置。该容器没有网卡、IP、路由等信息,需要手工添加。

  • bridge模式,使用–net=bridge指定,默认设置

    该模式会为每一个容器分配network namespace,设置IP、路由等,默认会将docker容器连接到一个虚拟网桥交换机docker0上。

关于桥接模式

    1、启动docker容器,首先会在docker宿主机上创建一对虚拟网卡veth pare设备,veth设备总是成对出现的,组成了一条数据通道,数据从一段设备进入,就会从另一端设备出来,veth设备常用来连接两个网络设备

    2、docker将veth pair设备的一端放在新创建的容器中,并取名为eth0,然后将另一端放在宿主机中,以vethxxx这样类似的名字命名,并将这个网络设备加入到docker0网桥中

    3、从docker0子网中分配一个IP给容器使用,并设置docker0IP的地址为容器的默认网关

    4、此时,容器IP与宿主机能够通信,宿主机也可访问容器中的IP地址,在bridge模式下,连在同一网桥上的容器之间可以互相通信,同时也可以访问外网,但是其他宿主机不能访问docker容器IP,需要通过NAT将容器IP的port映射为宿主机的IP和port才可以

A3QTrn.png

docker的架构

    docker目前采用了标准的C/S架构,包括客户端、服务器两大核心组件,同时通过镜像仓库来存储镜像。客户端和服务端既可以运行在一个机器上,也可以通过socket或者是RESTful API来进行通信。

    1、服务端

    docker服务端一般在宿主主机后台运行,dockerd作为服务端接收来自客户的请求,并通过containerd具体处理与容器相关的请求,包括创建、运行、删减容器等。主要包括四个组件:

  • dockerd:为客户端提供RESTful API接口,响应来自客户端的请求,采用模块化的架构,通过专门的engine模块来分发管理来自客户端的任务。
  • docker-proxy:是dockerd的子进程,当需要进行容器端口映射的时候,docker-proxy完成网络映射配置。
  • containerd:是dockerd的子进程,提供GRPC接口响应来自dockerd的请求,对下管理runC容器和镜像环境。
  • containerd-shim:是containerd的子进程,为runC容器提供支持,同时作为容器内进程的根进程。

    dockerd默认监听本地的unix:///var/run/docker.sock套接字,只允许本地的root用户或docker用户组成员访问。可以通过dockerd -H 127.0.0.1:port 来指定监听的端口。

2、客户端

    docker客户端为用户提供一系列可执行命令,使用这些命令可实现与docker服务端进行交互。我们使用的docker可执行命令即为客户端程序。与docker服务端保持运行方式不同,客户端发送命令后,等待服务端返回;一旦收到返回后,客户端立即执行结束并退出。客户执行新的命令,需要再次调用客户端命令。

    客户端默认通过本地的默认监听本地的unix:///var/run/docker.sock套接字向服务端发送命令,如果服务端没有监听在该端口,需要显示的指出服务端地址。比如:假定服务端监听在本地的TCP连接1234端口上,那么我们可以这样:

1
docker -H tcp://127.0.0.1:1234 info
------ 本文结束 ------
您的支持将鼓励我继续创作