随着容器技术的发展,微服务架构被许多互联网公司推崇。docker作为一种容器的交付方式,可以实现快速交付,应用隔离,保持环境一致性等多方面的优点。这里对docker的操作做简单的介绍。
安装部署
docker的安装和配置非常简单,如果对版本没有要求在系统的默认镜像源中就有,可直接安装即可。
1
<code>yum </code><code>install</code> <code>docker -y</code>
<code>vim </code><code>/usr/lib/systemd/system/docker</code><code>.service</code>
添加一行--registry-mirror的
<code>ExecStart=</code><code>/usr/bin/dockerd-current</code> <code>--registry-mirror=https:</code><code>//qxx96o44</code><code>.mirror.aliyuncs.com \</code>
启动docker:
2
<code> </code><code>systemctl daemon-reload</code>
<code> </code><code>systemctl start docker</code>
使用docker daemon --help 可以查看后台启动进程的一些可配置参数。
Docker 常用管理命令
镜像管理
对于docker我们可以通过本地导入镜像的方式,或者直接从网络上的镜像仓库进行下载。
显示镜像 docker images
搜索镜像 docker search nginx
下载镜像 docker pull nginx
导出镜像 docker save nginx > /tmp/nginx.tar.gz
导入镜像 docker load < /tmp/nginx.tar.gz
删除镜像 docker rmi nginx
命名镜像 docker tag image-id name:tag
容器管理
当下载好一个镜像之后,下一步就是使用这个镜像来启动一个容器,启动容器我们使用docker run 命令,这里会自动创建并启动。
启动一个容器,并进入终端, 退出后容器停止
<code>docker run -it nginx sh </code><code># -i -t 打开一个伪终端,打开标准输入, sh 执行的命令</code>
如果要想退出终端后容器不停止,可以使用 组合键:ctrl + p + q
或者登录容器使用 exec 命令(退出登录后容器不终止):
<code>docker </code><code>exec</code> <code>-it con-name sh</code>
也可以使用如下命令登录容器,但是与其他的登录者共享一个终端,能看到实时操作(退出会终止):
<code>docker attach Con-name</code>
如果你看不见shell提示符,按键盘方向键的上箭头。
启动容器,命名为test,并让其在后台运行:
<code>docker run -d --name </code><code>test</code> <code>centos </code><code>bash</code> <code>-c </code><code>"for n in {1..10};do echo up;sleep 1;done"</code>
可以使用docker logs 查看容器的运行状态信息:
<code>docker logs </code><code>test</code>
<code>docker logs </code><code>test</code> <code>-f </code><code>#实时查看日志</code>
启动一个容器,命名为mynginx,退出后容器删除:
<code>docker run -it --</code><code>rm</code> <code>--name mynginx nginx </code><code>bash</code>
后台启动一个mynginx的容器
<code>docker run -d --name mynginx nginx</code>
查看容器的具体信息:
<code>docker inspect Docker-Name</code>
进入一个正在运行的容器,可以使用如下脚本(退出时需要注意,直接退出会终止容器):
3
<code>#!/bin/bash</code>
<code>pid=`docker inspect --</code><code>format</code> <code>"``.`State`.`Pid`"</code> <code>$1` </code>
<code>nsenter -t $pid -m -u -i -n -p </code><code># nsenter的参数不能少</code>
如果没有这个命令可以采用yum install util-linux -y进行安装。
停止一个容器:
<code>docker stop mynginx</code>
或者使用kill ID 的方式:
<code>docker </code><code>kill</code> <code>Docker-ID</code>
杀死所有运行的容器:
<code>docker </code><code>kill</code> <code>$(docker </code><code>ps</code> <code>-a -q)</code>
查看所有容器(包含未运行的容器):
<code>docker </code><code>ps</code> <code>-a</code>
删除所有的容器(强制删除正在运行的容器加-f 参数):
<code>docker </code><code>rm</code> <code>`docker </code><code>ps</code> <code>--all|</code><code>awk</code> <code>'{print $1}'</code><code>|</code><code>grep</code> <code>-</code><code>v</code> <code>"CONTAINER"</code><code>`</code>
容器端口管理
在启动容器的时候,如果不指定对应的参数,在容器外部是无法通过网络来访问容器内的网 络应用和服务的。当容器中运行一些网络应用,要让外部访问这些应用时,可以通过P或 者p参数来指定容器端口映射。当使用P(大写)时,docker会随机映射一个端口到容器内 部开放的端口
随机端口映射:
<code>docker run --</code><code>rm</code> <code>-it -P nginx</code>
<code>docker run --</code><code>rm</code> <code>-it -p 127.0.0.1::80 nginx</code>
指定端口:
<code>docker run -it --</code><code>rm</code> <code>-p 80:80 nginx </code><code># 第一个端口为宿主机端口,第二个为容器内部端口</code>
绑定多个端口:
<code>docker run --</code><code>rm</code> <code>-it -p 82:80 -p 822:22 nginx</code>
指定IP绑定端口:
<code>docker run –</code><code>rm</code> <code>it p 127.0.0.1:80:80 nginx</code>
默认使用的是TCP协议,也可指定协议:
<code>docker run –</code><code>rm</code> <code>it p 127.0.0.1:80:80</code><code>/udp</code> <code>nginx</code>
网络功能
docker创建的容器默认是使用的Bridge进行网络通信的,默认情况下创建的容器都在172.17.0.0/16的bridge网络中。
docker会在宿主机创建一个docker0的网卡,默认情况下自带三种网络:
4
5
6
<code># docker network ls</code>
<code>NETWORK ID NAME DRIVER SCOPE</code>
<code>19d6580ec589 bridge bridge </code><code>local</code>
<code>7d48677c86bc host host </code><code>local</code>
<code>01b58b1cb415 none null </code><code>local</code>
host网络是在主机的网络堆栈上添加一个容器,使用host网络,主机和容器之间没有隔离。 例如,如果您使用主机网络运行在端口80上运行Web服务器的容器,则Web服务器可在主机端口80上使用。
host网络和none网络是无法直接配置的,我们可以配置和自定义bridge网络。
查看网络类型的具体说明:
docker network inspect bridge
内容会显示当前分配的容器网络地址。
当我们要创建一个基于某个网络的容器时,使用 docker run --net=<NETWORK> 指定
容器互联
您可以使用Docker链接功能来允许容器相互发现,并将有关一个容器的信息安全地传输到另一个容器。 通过引入Docker网络功能,您仍然可以创建链接,但它们在默认网桥和用户定义网络之间的行为方式不同,容器的互联需要通过容器的name来指定。
创建一个名为web的容器,将它与test容器互联:
<code>docker run -d --link </code><code>test</code> <code>--name web nginx</code>
这样两个容器在默认的docker0中网络就打通了,其实也是利用DNS的主机和IP解析,在test容器中的/etc/hosts文件添加了web容器主机名解析配置。不过官方不推荐这样做,更好的做法是自定义一个bridge网络。
由于默认容器是以bridge方式接入宿主机网络的,所以这种方式如果不添加路由只支持在同一台宿主机上的容器互联。
自定义网络
建议使用用户定义的bridge网络来控制哪些容器可以相互通信,还可以使用自动DNS解析容器名称到IP地址。 Docker提供了创建这些网络的默认网络驱动程序。 您可以创建一个新的桥接网络,覆盖网络或MACVLAN网络。 您还可以创建一个网络插件或远程网络进行完整的自定义和控制。
您可以根据需要创建任意数量的网络,并且可以在任何给定时间将容器连接到这些网络中的零个或多个网络。 此外,您可以连接并断开网络中的运行容器,而无需重新启动容器。 当容器连接到多个网络时,其外部连接通过第一个非内部网络以字母顺序提供网络连接。
Bridge 网络
Bridge网络是Docker中最常见的网络类型。 Bridge网络类似于桥接网络,但是与传统的桥接网络不通,docker的bridge网络添加了一些新功能并删除一些旧的功能。 以下示例创建一些桥接网络,并对这些网络上的容器执行一些实验。
系统默认的是172.17.0.1/16网段的,如果我们想要修改这个网段(即docker0地址)需要修改启动文件:
在ExecStart=区域,加上参数:
<code>--bip=10.10.0.1</code><code>/24</code> <code>\</code>
这里指定的网段必须以1结尾,不能使用0表示一个网段,否则服务无法启动。
查看默认的docker0网络:
7
8
9
10
11
12
13
14
15
16
17
<code># ip a</code>
<code>1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN </code>
<code> </code><code>link</code><code>/loopback</code> <code>00:00:00:00:00:00 brd 00:00:00:00:00:00</code>
<code> </code><code>inet 127.0.0.1</code><code>/8</code> <code>scope host lo</code>
<code> </code><code>valid_lft forever preferred_lft forever</code>
<code>2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000</code>
<code> </code><code>link</code><code>/ether</code> <code>52:54:00:7f:52:5a brd ff:ff:ff:ff:ff:ff</code>
<code> </code><code>inet 192.168.20.231</code><code>/24</code> <code>brd 192.168.20.255 scope global ens3</code>
<code>3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN </code>
<code> </code><code>link</code><code>/ether</code> <code>02:42:3d:be:20:1d brd ff:ff:ff:ff:ff:ff</code>
<code> </code><code>inet 10.10.0.1</code><code>/24</code> <code>scope global docker0</code>
<code>76: br-0d7cff84eda0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN </code>
<code> </code><code>link</code><code>/ether</code> <code>02:42:98:d5:cf:bf brd ff:ff:ff:ff:ff:ff</code>
<code> </code><code>inet 172.18.0.1</code><code>/16</code> <code>scope global br-0d7cff84eda0</code>
创建一个自定义的bridge网络:
<code>docker network create backend </code><code>#默认会使用bridge驱动</code>
18
19
20
21
22
23
24
<code># docker network inspect backend</code>
<code>[</code>
<code> </code><code>{</code>
<code> </code><code>"Name"</code><code>: </code><code>"backend"</code><code>,</code>
<code> </code><code>"Id"</code><code>: </code><code>"0d7cff84eda06d5648a9ec3b079b4f41dfad836a7ea15dbdd2e1521318d93478"</code><code>,</code>
<code> </code><code>"Scope"</code><code>: </code><code>"local"</code><code>,</code>
<code> </code><code>"Driver"</code><code>: </code><code>"bridge"</code><code>,</code>
<code> </code><code>"EnableIPv6"</code><code>: </code><code>false</code><code>,</code>
<code> </code><code>"IPAM"</code><code>: {</code>
<code> </code><code>"Driver"</code><code>: </code><code>"default"</code><code>,</code>
<code> </code><code>"Options"</code><code>: {},</code>
<code> </code><code>"Config"</code><code>: [</code>
<code> </code><code>{</code>
<code> </code><code>"Subnet"</code><code>: </code><code>"172.18.0.0/16"</code><code>,</code>
<code> </code><code>"Gateway"</code><code>: </code><code>"172.18.0.1/16"</code>
<code> </code><code>}</code>
<code> </code><code>]</code>
<code> </code><code>},</code>
<code> </code><code>"Internal"</code><code>: </code><code>false</code><code>,</code>
<code> </code><code>"Containers"</code><code>: {},</code>
<code> </code><code>"Options"</code><code>: {},</code>
<code> </code><code>"Labels"</code><code>: {}</code>
<code> </code><code>}</code>
<code>]</code>
<code>0d7cff84eda0 backend bridge </code><code>local</code>
<code>239f46f2ac1c bridge bridge </code><code>local</code>
创建一个容器,并指定backend网络:
<code># docker run --network=backend -itd --name=ts-net centos</code>
<code>04ddbd92fea9c63f6ec54c7e63409054fabe1ae8a5d4ab4e4134722df9ca890c</code>
查看自定义的网络状态:
25
26
27
28
29
30
31
32
<code> </code><code>"Containers"</code><code>: {</code>
<code> </code><code>"04ddbd92fea9c63f6ec54c7e63409054fabe1ae8a5d4ab4e4134722df9ca890c"</code><code>: {</code>
<code> </code><code>"Name"</code><code>: </code><code>"ts-net"</code><code>,</code>
<code> </code><code>"EndpointID"</code><code>: </code><code>"0b9d8cdf461a4a623693b86cb465c624573ff466453e6a0d202bd40937bf23c4"</code><code>,</code>
<code> </code><code>"MacAddress"</code><code>: </code><code>"02:42:ac:12:00:02"</code><code>,</code>
<code> </code><code>"IPv4Address"</code><code>: </code><code>"172.18.0.2/16"</code><code>,</code>
<code> </code><code>"IPv6Address"</code><code>: </code><code>""</code>
<code> </code><code>}</code>
启动到此网络的容器必须驻留在相同的Docker宿主机上。 网络中的每个容器都可以立即与网络中的其他容器进行通信。 虽然网络本身将容器与外部网络隔离开来。
用户自定义的bridge网络不支持link方式。可以使用之前介绍的端口映射或者使用expose的方式。
如果两个不同网络的容器要相互通信那应该怎么办呢? 其实很简单,容器也可以配置多个网络,就像物理机的多网卡一样,添加容器到其它网络可以给它再增加一个虚拟机网卡即可:
给容器test1添加网络backend,无论容器是否开启此命令都能生效。这样容器test1中就会有两个网段的IP地址。
本文转自 酥心糖 51CTO博客,原文链接:http://blog.51cto.com/tryingstuff/1945403