Centos7 Docker基本特性入门实践-2

本文介绍了如何在CentOS 7上使用Docker构建和管理自定义Image。从理解Dockerfile开始,通过hello-world Image的示例解析其构建过程,然后演示了编写和使用Dockerfile创建自定义Image,包括安装应用、构建流程和预下载依赖Image。此外,文章还讨论了Docker网络,包括默认网络和自定义网络的创建与管理。
摘要由CSDN通过智能技术生成

续CentOS 7 Docker基本特性入门实践-1

构建Image

通过创建Dockerfile可以构建Image,Docker会从一个Dockerfile中读取一系列指令来构建Image。一个Dockerfile是一个文本文件,它包含了一组能够运行的命令行,这些命令行就组装成了一个Docker Image。
下面,我们看一下前面提到的名称为hello-world的Image是如何构建,可以在Github上看到该Image的代码,链接在这里:https://github.com/docker-library/hello-world
hello-world一定对应一个Dockerfile,内容如下所示:

1 FROM scratch
2 COPY hello /
3 CMD ["/hello"]

上面这3条命令,就对应着hello-world这个Image:
第一行,FROM命令:是从一个已知的基础Image来构建新的Image,这里scratch是一个显式指定的空Image;
第二行,COPY命令:是将指定的新文件或目录,拷贝到Container中指定的目录下面,这里讲hello这个可执行文件复制到Container中的根路径/下面;
第三行,CMD命令:是运行指定的命令行,包含指定的命令名称、参数列表
可见,上面的hello可执行文件是已经构编译好的文件,它是从一个C程序文件(Github链接:https://github.com/docker-library/hello-world/blob/master/hello.c)编译而来的,源码文件hello.c内容如下所示:

01 #include <sys/syscall.h>
02  
03 #ifndef DOCKER_IMAGE
04     #define DOCKER_IMAGE "hello-world"
05 #endif
06  
07 #ifndef DOCKER_GREETING
08     #define DOCKER_GREETING "Hello from Docker!"
09 #endif
10  
11 const char message[] =
12     "\n"
13     DOCKER_GREETING "\n"
14     "This message shows that your installation appears to be working correctly.\n"
15     "\n"
16     "To generate this message, Docker took the following steps:\n"
17     " 1. The Docker client contacted the Docker daemon.\n"
18     " 2. The Docker daemon pulled the \"" DOCKER_IMAGE "\" image from the Docker Hub.\n"
19     " 3. The Docker daemon created a new container from that image which runs the\n"
20     "    executable that produces the output you are currently reading.\n"
21     " 4. The Docker daemon streamed that output to the Docker client, which sent it\n"
22     "    to your terminal.\n"
23     "\n"
24     "To try something more ambitious, you can run an Ubuntu container with:\n"
25     " $ docker run -it ubuntu bash\n"
26     "\n"
27     "Share images, automate workflows, and more with a free Docker ID:\n"
28     https://cloud.docker.com/\n"
29     "\n"
30     "For more examples and ideas, visit:\n"
32     "\n";
33  
34 void _start() {
35     //write(1, message, sizeof(message) - 1);
36     syscall(SYS_write, 1, message, sizeof(message) - 1);
37  
38     //_exit(0);
39     syscall(SYS_exit, 0);
40 }

编译生成可执行文件hello,然后可以使用Docker的build命令来构建生成Image:

1 docker build -t hello-world

现在,hello-world是如何构建Image的就已经非常清楚了。下面,我们通过参考官网的用户指南,编写一个Dockerfile来制作一个Image,了解如何实现自己的应用:

  • 编写Dockerfile

首先,创建一个单独的目录来存放我们将要构建的Dockerfile文件:

1 mkdir mydockerbuild
2 cd mydockerbuild
3 vi Dockerfile

在Dockerfile中输入如下内容:

1 FROM docker/whalesay:latest
2 RUN apt-get -y update && apt-get install -y fortunes
3 CMD /usr/games/fortune -a | cowsay

上面FROM命令表示,Docker基于该docker/whalesay:latest来构建新的Image,这个Image在Docker Hub上,链接在这里:https://hub.docker.com/r/docker/whalesay/,对应的源码可以看Github:https://github.com/docker/whalesay。RUN命令行表示安装fortunes程序包,最后的CMD命令指示将运行/usr/games/fortune命令。

  • 构建Image

保存上述3行命令到文件中,在当前mydockerbuild目录中执行构建Image的命令:

1 docker build -t docker-whale .

构建过程,输出信息如下:

01 Sending build context to Docker daemon 2.048 kB
02 Step 1/3 : FROM docker/whalesay:latest
03  ---> 6b362a9f73eb
04 Step 2/3 : RUN apt-get -y update && apt-get install -y fortunes
05  ---> Running in bfddc2134d23
06 Ign http://archive.ubuntu.com trusty InRelease
07 Get:1 http://archive.ubuntu.com trusty-updates InRelease [65.9 kB]
08 Get:2 http://archive.ubuntu.com trusty-security InRelease [65.9 kB]
09 Hit http://archive.ubuntu.com trusty Release.gpg
10 Get:3 http://archive.ubuntu.com trusty-updates/main Sources [485 kB]
11 Get:4 http://archive.ubuntu.com trusty-updates/restricted Sources [5957 B]
12 Get:5 http://archive.ubuntu.com trusty-updates/universe Sources [220 kB]
13 Get:6 http://archive.ubuntu.com trusty-updates/main amd64 Packages [1197 kB]
14 Get:7 http://archive.ubuntu.com trusty-updates/restricted amd64 Packages [20.4 kB]
15 Get:8 http://archive.ubuntu.com trusty-updates/universe amd64 Packages [516 kB]
16 Get:9 http://archive.ubuntu.com trusty-security/main Sources [160 kB]
17 Get:10 http://archive.ubuntu.com trusty-security/restricted Sources [4667 B]
18 Get:11 http://archive.ubuntu.com trusty-security/universe Sources [59.4 kB]
19 Get:12 http://archive.ubuntu.com trusty-security/main amd64 Packages [730 kB]
20 Get:13 http://archive.ubuntu.com trusty-security/restricted amd64 Packages [17.0 kB]
21 Get:14 http://archive.ubuntu.com trusty-security/universe amd64 Packages [199 kB]
22 Hit http://archive.ubuntu.com trusty Release
23 Hit http://archive.ubuntu.com trusty/main Sources
24 Hit http://archive.ubuntu.com trusty/restricted Sources
25 Hit http://archive.ubuntu.com trusty/universe Sources
26 Hit http://archive.ubuntu.com trusty/main amd64 Packages
27 Hit http://archive.ubuntu.com trusty/restricted amd64 Packages
28 Hit http://archive.ubuntu.com trusty/universe amd64 Packages
29 Fetched 3745 kB in 55s (67.1 kB/s)
30 Reading package lists...
31 Reading package lists...
32 Building dependency tree...
33 Reading state information...
34 The following extra packages will be installed:
35   fortune-mod fortunes-min librecode0
36 Suggested packages:
37   x11-utils bsdmainutils
38 The following NEW packages will be installed:
39   fortune-mod fortunes fortunes-min librecode0
40 0 upgraded, 4 newly installed, 0 to remove and 92 not upgraded.
41 Need to get 1961 kB of archives.
42 After this operation, 4817 kB of additional disk space will be used.
43 Get:1 http://archive.ubuntu.com/ubuntu/ trusty/main librecode0 amd64 3.6-21 [771 kB]
44 Get:2 http://archive.ubuntu.com/ubuntu/ trusty/universe fortune-mod amd64 1:1.99.1-7 [39.5 kB]
45 Get:3 http://archive.ubuntu.com/ubuntu/ trusty/universe fortunes-min all 1:1.99.1-7 [61.8 kB]
46 Get:4 http://archive.ubuntu.com/ubuntu/ trusty/universe fortunes all 1:1.99.1-7 [1089 kB]
47 debconf: unable to initialize frontend: Dialog
48 debconf: (TERM is not set, so the dialog frontend is not usable.)
49 debconf: falling back to frontend: Readline
50 debconf: unable to initialize frontend: Readline
51 debconf: (This frontend requires a controlling tty.)
52 debconf: falling back to frontend: Teletype
53 dpkg-preconfigure: unable to re-open stdin:
54 Fetched 1961 kB in 5s (340 kB/s)
55 Selecting previously unselected package librecode0:amd64.
56 (Reading database ... 13116 files and directories currently installed.)
57 Preparing to unpack .../librecode0_3.6-21_amd64.deb ...
58 Unpacking librecode0:amd64 (3.6-21) ...
59 Selecting previously unselected package fortune-mod.
60 Preparing to unpack .../fortune-mod_1%3a1.99.1-7_amd64.deb ...
61 Unpacking fortune-mod (1:1.99.1-7) ...
62 Selecting previously unselected package fortunes-min.
63 Preparing to unpack .../fortunes-min_1%3a1.99.1-7_all.deb ...
64 Unpacking fortunes-min (1:1.99.1-7) ...
65 Selecting previously unselected package fortunes.
66 Preparing to unpack .../fortunes_1%3a1.99.1-7_all.deb ...
67 Unpacking fortunes (1:1.99.1-7) ...
68 Setting up librecode0:amd64 (3.6-21) ...
69 Setting up fortune-mod (1:1.99.1-7) ...
70 Setting up fortunes-min (1:1.99.1-7) ...
71 Setting up fortunes (1:1.99.1-7) ...
72 Processing triggers for libc-bin (2.19-0ubuntu6.6) ...
73  ---> 98403143b081
74 Removing intermediate container bfddc2134d23
75 Step 3/3 : CMD /usr/games/fortune -a | cowsay
76  ---> Running in 8831a7231adc
77  ---> 08d234c4ee26
78 Removing intermediate container 8831a7231adc
79 Successfully built 08d234c4ee26

或者,可以通过-f选项,直接指定Dockerfile文件的绝对路径,构建命令如下所示:

1 docker build -f ~/mydockerbuild/Dockerfile -t docker-whale .

这样我们自己的Image就构建好了,名称为docker-whale。下面,看下构建我们这个Image的基本流程流程:

  1. Docker检查确保当前Dockerfile中是否有需要build的内容
  2. Docker检查是否存在whalesay这个Image
  3. Docker会启动一个临时的容器6b362a9f73eb,来运行whalesay这个image。在这个临时的Container中,Docker会执行RUN这行命令,安装fortune程序包
  4. 一个新的中间container被创建8831a7231adc,在Dockerfile中增加了一个CMD层(Layer),对应一个Container,然后中间container8831a7231adc被删除

我们在构建一个Image时,会自动下载依赖的Docker Image,其实也可以预先下载对应的Image,使用类似下面的命令:

1 docker pull mysql:5.5

这样就可以下载MySQL 5.5的Image到本地。

  • 查看构建的Image

查看当前image列表,其中包含我们刚刚构建好的Image,执行docker images命令,结果如下所示:

1 REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
2 docker-whale        latest              08d234c4ee26        9 minutes ago       256 MB
3 ubuntu              latest              f49eec89601e        5 weeks ago         129 MB
4 hello-world         latest              48b5124b2768        6 weeks ago         1.84 kB
5 docker/whalesay     latest              6b362a9f73eb        21 months ago       247 MB

第一个docker-whale,就是我们自己创建的。

  • 启动Docker Container

接着,基于我们已经构建好的Image,在Docker Container中运行这个应用,执行命令:

1 docker run docker-whale

运行结果,如下所示:

01 ______________________________
02 / IBM:                         \
03 |                              |
04 | I've Been Moved              |
05 |                              |
06 | Idiots Become Managers       |
07 |                              |
08 | Idiots Buy More              |
09 |                              |
10 | Impossible to Buy Machine    |
11 |                              |
12 | Incredibly Big Machine       |
13 |                              |
14 | Industry's Biggest Mistake   |
15 |                              |
16 | International Brotherhood of |
17 | Mercenaries                  |
18 |                              |
19 | It Boggles the Mind          |
20 |                              |
21 | It's Better Manually         |
22 |                              |
23 \ Itty-Bitty Machines          /
24  ------------------------------
25     \
26      \
27       \    
28                     ##        .          
29               ## ## ##       ==          
30            ## ## ## ##      ===          
31        /""""""""""""""""___/ ===      
32   ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ /  ===- ~~~  
33        \______ o          __/          
34         \    \        __/            
35           \____\______/  

另外,我们可以进入到Docker Hub:https://hub.docker.com,创建一个自己的账号,然后创建自己的Image,当然也可以找到各种免费共享的Image,可以基于这些Image来构建自己的Image。Docker Hub页面,如下所示:

下面是一个例子,可以在启动Docker Container时,通过命令行直接向Container内部应用传递参数值,命令行如下所示:

1 docker run docker/whalesay cowsay boo
2 docker run docker/whalesay cowsay boo-boo

可以看到,输出的内容根据启动Container传递的参数值而变化。

  • 查看Docker Container

查看当前主机上所有状态的Docker Container,可以执行如下命令(下面的命令都是等价的):

1 docker ps -a
2 docker container ps -a
3 docker container ls -a

示例结果,如下所示:

1 CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
2 5ab157767bbd        training/postgres   "su postgres -c '/..."   6 seconds ago       Up 5 seconds        5432/tcp            pgdb
3 da91889d6313        training/postgres   "su postgres -c '/..."   49 seconds ago       Up 2 seconds        5432/tcp            webappdb
4 5d86616e9a1d        docker-whale        "/bin/sh -c '/usr/..."   24 minutes ago       Exited (0) 7 seconds ago                             elastic_mcnulty
5 abec6410bcac        docker/whalesay     "cowsay boo"             27 minutes ago       Exited (0) 27 minutes ago                            upbeat_edison
6 72d0b2bb5d6a        training/postgres   "su postgres -c '/..."   4 hours ago         Up 4 hours          5432/tcp            db
7 fc9b0bb6ae8e        ubuntu              "/bin/bash"              4 hours ago         Up 4 hours                              networktest
8 fc9b0bb6ae8e        ubuntu              "/bin/bash"              7 days ago           Exited (255) 3 days ago                              networktest

查看当前运行中的Container,可以执行如下命令查看(下面的命令都是等价的):

1 docker ps
2 docker container ps
3 docker container ls

Docker网络

Docker支持Container之间通过网络互连,提供了两种网络Driver,分别为Bridge和Overlay,我们也可以实现自己的网络Driver插件来管理我们的Docker Container网络。目前,有很多Docker网络的解决方案,如Flannel、Weave、Pipework、libnetwork等,感兴趣可以深入研究一下。
在安装Docker Engine之后,会包含三个默认的网络,可以通过如下命令查看当前所有的网络:

1 docker network ls

结果如下所示:

1 NETWORK ID          NAME                DRIVER              SCOPE
2 b92d9ca4d992        bridge              bridge              local
3 6d33880bf521        host                host                local
4 a200b158f39c        none                null                local

名称为host的网络,表示宿主机的网络,如果启动Docker Container指定该网络,则Container与宿主机使用相同的Network Namespace,也就是启动的Container的网络会使用宿主机的网卡、IP、端口。
在启动Docker Container时,如果我们没有显式指定网络名称,Docker会使用默认的bridge网络。这种网络模式下,Docker会为Container创建一个独立于宿主机的Network Namespace,并使用独立的IP段,Container连接到一个虚拟网桥上,默认是docker0网桥。虚拟网桥与交换机的工作方式类似,启动的Docker Container连接到虚拟网桥上,这就构成了一个二层网络。
为了更加直观说明,我们参考了网上的一个Docker网络的结构图,如下图所示:

下面,通过Docker网络功能,看如何将Container网络连接起来。

  • 创建Docker网络

创建一个Docker网络,名称为my-bridge-network,执行如下命令:

1 docker network create -d bridge my-bridge-network

创建的结果,输出了新建Docker网络的ID,如下所示:

1 fc19452525e5d2f5f1fc109656f0385bf2f268b47788353c3d9ee672da31b33a

上面fc19452525e5d2f5f1fc109656f0385bf2f268b47788353c3d9ee672da31b33a就是新创建网络my-bridge-network的ID,可以通过如下命令查看:

1 docker network ls

当前主机上存在的所有Docker网络信息,如下所示:

1 NETWORK ID          NAME                DRIVER              SCOPE
2 b92d9ca4d992        bridge              bridge              local
3 6d33880bf521        host                host                local
4 fc19452525e5        my-bridge-network   bridge              local
5 a200b158f39c        none                null                local
  • 查看一个Docker网络

查看一个Docker网络的详细信息,查看默认的bridge网络,可以执行如下命令:

1 docker network inspect bridge

执行结果,如下所示:

01 [
02     {
03         "Name": "bridge",
04         "Id": "2872de41fddddc22420eecad253107e09a305f3512ade31d4172d3b80723d8b6",
05         "Created": "2017-03-05T21:46:12.413438219+08:00",
06         "Scope": "local",
07         "Driver": "bridge",
08         "EnableIPv6": false,
09         "IPAM": {
10             "Driver": "default",
11             "Options": null,
12             "Config": [
13                 {
14                     "Subnet": "172.17.0.0/16",
15                     "Gateway": "172.17.0.1"
16                 }
17             ]
18         },
19         "Internal": false,
20         "Attachable": false,
21         "Containers": {
22             "5ab157767bbd991401c351cfb452d663f5cd93dd1edc56767372095a5c2e7f73": {
23                 "Name": "pgdb",
24                 "EndpointID": "e0368c3219bcafea7c2839b7ede628fa67ad0a5350d150fdf55a4aa88c01c480",
25                 "MacAddress": "02:42:ac:11:00:02",
26                 "IPv4Address": "172.17.0.2/16",
27                 "IPv6Address": ""
28             },
29             "da91889d63139019bbdcc6266704fb21e0a1800d0ae63b3448e65d1e17ef7368": {
30                 "Name": "webappdb",
31                 "EndpointID": "422ab05dd2cbb55266964b31f0dd9292688f1459e3a687662d1b119875d4ce44",
32                 "MacAddress": "02:42:ac:11:00:03",
33                 "IPv4Address": "172.17.0.3/16",
34                 "IPv6Address": ""
35             }
36         },
37         "Options": {
38             "com.docker.network.bridge.default_bridge": "true",
39             "com.docker.network.bridge.enable_icc": "true",
40             "com.docker.network.bridge.enable_ip_masquerade": "true",
41             "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
42             "com.docker.network.bridge.name": "docker0",
43             "com.docker.network.driver.mtu": "1500"
44         },
45         "Labels": {}
46     }
47 ]

通过上面结果信息可以看到,当前bridge网络的ID为2872de41fddddc22420eecad253107e09a305f3512ade31d4172d3b80723d8b6,在该Docker网络内部运行中的Container有2个,分别为pgdb和webapp,他们在Container内部的IP地址分别为172.17.0.2和172.17.0.3,因为在同一个bridge网络中,所以共享相同的IP地址段。
或者,我们也可以格式化输出某个Container所在网络的设置,执行如下命令:

1 docker inspect --format='{{json .NetworkSettings.Networks}}'  pgdb

输出结果如下所示(结果格式化过):

01 {
02     "bridge": {
03         "IPAMConfig": null,
04         "Links": null,
05         "Aliases": null,
06         "NetworkID": "2872de41fddddc22420eecad253107e09a305f3512ade31d4172d3b80723d8b6",
07         "EndpointID": "e0368c3219bcafea7c2839b7ede628fa67ad0a5350d150fdf55a4aa88c01c480",
08         "Gateway": "172.17.0.1",
09         "IPAddress": "172.17.0.2",
10         "IPPrefixLen": 16,
11         "IPv6Gateway": "",
12         "GlobalIPv6Address": "",
13         "GlobalIPv6PrefixLen": 0,
14         "MacAddress": "02:42:ac:11:00:02"
15     }
16 }

可见和上面的命令类似,能输出Docker网络bridge的基本信息。

转载至:http://shiyanjun.cn/archives/1608.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值