理解Docker 深入引擎室
Docker的架构
宿主机上的Docker分为两个部分:一个具有REST风格API的守护进程,以及一个与守护进程通信的客户端。
调用Docker客户端可以从守护进程获取信息或给它发送指令。守护进程是一个服务器,它使用HTTP协议接收来自客户端的请求并返回响应。相应地,会向其他服务发起请求来发送和接收镜像。使用的同样是HTTP协议。
Docker守护进程
Docker守护进程是用户与Docker交互的枢纽。
守护进程与服务器:
守护进程是运行在后台的一个进程,不在用户的直接控制之下,服务器是负责接收客户端请求,并执行用于满足该请求所需的操作的一个进程,守护进程通常是一个服务器,接收来自客户端的请求。
开放Docker守护进程
默认情况下Docker的守护进程只能在宿主机上访问,但是有些情况下还是需要允许其他人访问它。(不安全)
使用开放的TCP地址启动Docker守护进程。
在开放Docker守护进程之前,必须停止运行的实例。
systemctl stop docker
向外界开放
docker daemon -H tcp://0.0.0.0:2375
-H标志定义宿主机服务器,使用TCP协议,绑定到所有IP地址上,并以标准的Docker服务器端口2375开放。
从外部使用命令如下:
docekr -H tcp://<宿主机IP>:2375
本机机器内部也需要这么做。
以守护进程的方式运行容器
以服务方式运行Docker容器,通过软件隔离实现可预测行为。
Docker容器与多数进程一样,默认在前台运行。在后台运行Docker容器最常见的方式是使用标准的&控制操作。虽然行得通,如果用户注销终端会话就可能出现问题,用户被迫使用nohup标志,而这将在本地目录中创建一个不得不管理的输出文件。
使用-d
标志即可。
docker run -d -i -p 1234:1234 --name daemon ubuntu nc -l 1234
- -d 标志将守护进程方式运行容器
- -i 标志赋予容器与Telnet会话交互的能力
- -p 将容器的1234端口公布到宿主机上。
- –name 标志赋予容器一个名称
- netcat(nc)在1234端口上运行一个简单的监听应答(echo)服务器
重启标志
docker run --restart
标志允许应用一组容器终止时需要遵循的规则。
策略 | 描述 |
no | 容器退出时不重启 |
always | 容器退出时总是自动重启 |
on-failure[:max-retry] | 只有失败时重启 |
将Docker移动到不同分区
Docker将所有与容器和镜像有关的数据都存储在一个目录下,由于它可能会存储大量不同的镜像,这个目录可能会迅速变大。
停止Docker守护进程
docker daemon -g /home/dockeruser/mydocker
这些目录是Docker内部使用的,容器和镜像从之前的Docker守护进程清除了,如果杀掉刚才运行的Docker进程,并重启Docker服务,Docker客户端会指回它原来的位置,容器和镜像也将回归。
如果想让这个移动永久有效,需要对宿主机系统的启动进程进行相应配置。
Docker客户端
使用socat监控Docker API流量
将自己的请求与服务器套接字之间插入一个代理Unix域套接字,并查看通过它的内容。
sudo socat -v UNIX-LISTEN:/tmp/dockerapi.sock UNIX-CONNECT:/var/run/docker.sock &
socat是一个强大的命令,能让用户在两个几乎任务类型的数据通道中中继数据。可以认为是netcat的加强版。
-v 用于提高输出的可读性
UNIX-LISTEN 让socat在一个Unix套接字上进行监听。
UNIX-CONNECT 让socat连接到Docker的Unix套接字上。
& 符号指定在后台运行该命令
发送守护进程的请求如下
使用端口连接容器
Docker容器从一开始就被设计用于运行服务,在大多数的情况下,都是这样或那样的HTTP服务。
当多个Docker容器在在其内部环境中80端口上,它们将无法全部通过宿主机的80端口进行访问。
以tutum-wordpress镜像为例。运行两个实例来服务不同的博客。
通过将容器的端口映射到宿舍机上。
docker run -d -p 10001:80 --name blog1 tutum/wordpress
docker run -d -p 10002:80 --name blog2 tutum/wordpress
通过浏览http://localhost:10001和http://localhost:10002来访问自己的容器。
如果需要的话,就可以通过管理端口分配到宿主机上运行多个相同的镜像和服务了。牢记-p标志的参数顺序。
链接容器实现端口隔离
出于内部目的,想要让容器间实现通信。
docker run --name wp-mysql -e MYSQL_ROOT_PASSWORD=yoursecretpassword -d mysql
docker run --name wordpress --link wp-mysql:mysql -p 10003:80 -d wordpress
- 将mysql容器命名为wp-mysql,用于在后面引用它,还提供一个环境变量以便mysql容器可以初始化数据库。-d表示守护进程方式运行
- wordpress命名为wordpress以便后面引用它,将wp-mysql容器链接到wordpress容器中,在wordpress容器中对mysql服务器引用将发送到名为wp-mysql容器中。
这样便于将不同的mysql容器交换进来。为了使用这种方式连接容器,在构建镜像的必须执行暴露的端口。
在浏览器中使用DOcker
使用一个开发端口启动Docker守护进程,并启用CORS,然后使用所选择Web服务器为Docker终端仓库提供服务。
首先获取代码
git clone https:///aidanhs/Docker-Terminal.git
cd Docker-Terminal
然后需要提供文件服务
python2 -m SimpleHTTPServer 8000
上述命令使用Python内置的一个模块为目录中的静态文件服务,用户可以使用任何自己喜欢的等效服务。
- 不能使用任何类型的代理
- 需要给出外部IP地址
- Docker终端需要知道上哪里找到Docker API。
Docker注册中心
建立一个本地的Docker注册中心
docker run -d -p 5000:5000 -v $HOME/registry:/var/lib/registry registry:2
这条命令让注册中心运行于Docker宿主机的5000端口上,并使用主目录下的registry作为容器的/var/lib/registry目录,后者是容器里面的registry默认存储文件的位置。同时制定了容器内的registry将文件存储在/registry目录下。
现在可以执行
docker push HOSTNAME:5000/image:tag
Docker Hub
Docker Hub是由Docker公司维护的一个注册中心,拥有成千上万镜像可供下载和运行。
搜索并运行一个Docker镜像
docker search node //搜索镜像
docker pull node // 拉取node镜像
docker run -t -i node /bin/bash
- -t -i 标志以交互方式运行
- -t指明创建一个tty设备
- -i 表明该Docker会话是交互式的