一. BusyBox工具箱
Linux系统的瑞士军刀,集成了100多个常用的软件工具箱,但大小却只有几兆,十分精巧。
首先,下载 BusyBox 镜像:
[root@localhost ~]# docker pull 192.168.255.128:5000/busybox
Using default tag: latest
latest: Pulling from busybox
e2334dd9fee4: Pull complete
Digest: sha256:a2490cec4484ee6c1068ba3a05f89934010c85242f736280b35343483b2264b6
Status: Downloaded newer image for 192.168.255.128:5000/busybox:latest
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
192.168.255.128:5000/busybox latest be5888e67be6 7 days ago 1.22MB
此处小编还是从自己配的私服上下载的,当然也可以使用阿里云镜像加速器或者DaoCloud镜像市场下载。下载完成后,启动 busybox 容器,进入 busybox 容器终端 /bin/ash,可以发现 busybox 集成了很多 linux 命令。
[root@localhost ~]# docker run -itd --name busybox 192.168.255.128:5000/busybox
f8a44c4c3b31a545bd5a9e66a5209a13d74ff147cf017d4bafc0ada742ba842f
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f8a44c4c3b31 192.168.255.128:5000/busybox "sh" 5 seconds ago Up 4 seconds busybox
[root@localhost ~]# docker exec -it busybox /bin/ash
/ # pwd
/
/ # ls | grep a
var
/ # ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:02
inet addr:172.17.0.2 Bcast:0.0.0.0 Mask:255.255.0.0
...
/ # mount --help
BusyBox v1.31.1 (2020-04-14 01:09:51 UTC) multi-call binary.
Usage: mount [OPTIONS] [-o OPT] DEVICE NODE
Mount a filesystem. Filesystem autodetection requires /proc.
-a Mount all filesystems in fstab
-f Dry run
...
ro Same as -r
There are filesystem-specific -o flags.
/ # exit
[root@localhost ~]#
二. Tomcat 应用服务器
关于 tomcat 镜像的下载此处不再赘述,注意启动Tomcat容器时,进行端口的映射,并挂载宿主机上的目录到容器中tomcat的 webapps 目录。
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
192.168.255.128:5000/tomcat latest 31a47677561a 5 days ago 529MB
192.168.255.128:5000/busybox latest be5888e67be6 7 days ago 1.22MB
[root@localhost ~]# docker run -itd --name tomcat -p 8080:8080 -v /opt/docker/tomcat/webapps:/usr/local/tomcat/webapps 192.168.255.128:5000/tomcat
697193985a92166ec45c6fff6dbf141f866e41e80c05410c8bb3ae98bd0c5579
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
697193985a92 192.168.255.128:5000/tomcat "catalina.sh run" 4 seconds ago Up 3 seconds 0.0.0.0:8080->8080/tcp tomcat
f8a44c4c3b31 192.168.255.128:5000/busybox "sh" 9 minutes ago Up 9 minutes busybox
[root@localhost ~]# cd /opt/docker/tomcat/webapps/
[root@localhost webapps]# mkdir abc
[root@localhost webapps]# cd abc
[root@localhost abc]# touch index.html
[root@localhost abc]# vim index.html
[root@localhost abc]# cat index.html
<h1>Hello, Docker!</P>
注:-p 8080:8080 -> 将主机的8080端口映射到容器的8080端口;-v /opt/docker/tomcat/webapps:/usr/local/tomcat/webapps -> 挂载主机上的目录到webapps。
在浏览器地址栏中输入 http://192.168.255.128:8080/abc/index.html 访问结果如下:
三. Mysql 数据库服务器
首先创建一个临时的 mysql 镜像,以便在挂载数据卷之前确认好相关的文件路径,必要时还可以将相关文件拷贝下来,以便在宿主机上使用:
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
redis latest df5748206578 2 days ago 98.3MB
mongo latest 4e9495ea1bc6 2 days ago 388MB
mysql latest 9b51d9275906 7 weeks ago 547MB
registry latest 708bc6af7e5e 3 months ago 25.7MB
scrapinghub/splash latest 241c7dde86d9 14 months ago 1.22GB
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
root@localhost ~]# docker run -itd --rm -e MYSQL_ROOT_PASSWORD=root123 mysql
f4a6c895c3dc61076a3530184b16b741a3a362605c775f7d8a57e7336189843b
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f4a6c895c3dc mysql "docker-entrypoint..." 5 seconds ago Up 4 seconds 3306/tcp, 33060/tcp condescending_leavitt
[root@localhost ~]# docker exec -it f4 /bin/bash
root@f4a6c895c3dc:/# cd /var/lib/mysql/
root@f4a6c895c3dc:/var/lib/mysql# ls
'#innodb_temp' binlog.000002 ca.pem f4a6c895c3dc.err ib_logfile1 mysql private_key.pem server-key.pem undo_002
auto.cnf binlog.index client-cert.pem ib_buffer_pool ibdata1 mysql.ibd public_key.pem sys
binlog.000001 ca-key.pem client-key.pem ib_logfile0 ibtmp1 performance_schema server-cert.pem undo_001
root@f4a6c895c3dc:/var/lib/mysql# cd /etc/mysql/conf.d/
root@f4a6c895c3dc:/etc/mysql/conf.d# ls
docker.cnf mysql.cnf
root@f4a6c895c3dc:/etc/mysql/conf.d# exit
exit
[root@localhost ~]# docker cp f4a6c895c3dc:/etc/mysql/conf.d/mysql.cnf /opt/docker/mysql/mysql.cnf
[root@localhost docker]# ls mysql/
mysql.cnf
注:docker run 添加 --rm 参数后,可以创建并运行一个临时的容器,当容器停止后,会自动将容器删除。
下面,我们修改宿主机上的 /opt/docker/mysql/mysql.cnf 配置文件,修改 mysql 默认的字符集为utf,在修改之前,我们不妨先查看下 mysql 的默认字符集:
[root@localhost docker]# docker exec -it mysql /bin/bash
root@a2991f6f5ea2:/# mysql -uroot -proot123
...
Server version: 8.0.19 MySQL Community Server - GPL
...
mysql> show variables like 'char%'
-> ;
+--------------------------+--------------------------------+
| Variable_name | Value |
+--------------------------+--------------------------------+
| character_set_client | latin1 |
| character_set_connection | latin1 |
| character_set_database | utf8mb4 |
| character_set_filesystem | binary |
| character_set_results | latin1 |
| character_set_server | utf8mb4 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql-8.0/charsets/ |
+--------------------------+--------------------------------+
8 rows in set (0.00 sec)
备注:要在 Mysql 中保存 4 字节长度的 UTF-8 字符,需要使用 utf8mb4 字符集,但只有 5.5.3 版本以后的才支持。低版本的MySQL支持的utf8编码,最大字符长度为 3 字节,如果遇到 4 字节的字符就会出现错误了。三个字节的 UTF-8 最大能编码的 Unicode 字符是 0xFFFF,也就是 Unicode 中的基本多文平面(BMP)。任何不在基本多文平面的 Unicode字符,都无法使用MySQL原有的 utf8 字符集存储。这些不在BMP中的字符包括哪些呢?最常见的就是Emoji 表情(Emoji 是一种特殊的 Unicode 编码,常见于 ios 和 android 手机上),和一些不常用的汉字,以及任何新增的 Unicode 字符等等。如果实际用途上来看,可以给要用到emoji的库或者说表,设置utf8mb4。比如评论要支持emoji可以用到。
打开我们拷贝到宿主机 /opt/docker/mysql/mysql.cnf 的文件,添加如下内容:
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
init_connect='SET collation_connection = utf8_unicode_ci'
init_connect='SET NAMES utf8'
character-set-server=utf8
collation-server=utf8_unicode_ci
skip-character-set-client-handshake
接下来,让我们停止刚刚创建的 mysql 临时容器:
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fd648a0e2101 mysql "docker-entrypoint..." 13 minutes ago Up 13 minutes 3306/tcp, 33060/tcp stoic_almeida
[root@localhost ~]# docker stop fd
fd
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@localhost ~]#
创建一个具有端口映射和挂载数据卷的正式 mysql 容器:
[root@localhost docker]# docker run -itd --name mysql -p 3306:3306 -v /opt/docker/mysql/mysql.cnf:/etc/mysql/conf.d/mysql.cnf -v /opt/docker/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root123 mysql
a2991f6f5ea2fd0a01b286ae7e99301132dce9430ff63a23f9faa48704ce9f24
[root@localhost docker]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a2991f6f5ea2 mysql "docker-entrypoint..." 5 seconds ago Up 3 seconds 0.0.0.0:3306->3306/tcp, 33060/tcp mysql
[root@localhost docker]# docker exec -it mysql /bin/bash
root@a2991f6f5ea2:/# mysql -uroot -proot123
...
Server version: 8.0.19 MySQL Community Server - GPL
...
mysql> show variables like 'char%'
-> ;
+--------------------------+--------------------------------+
| Variable_name | Value |
+--------------------------+--------------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql-8.0/charsets/ |
+--------------------------+--------------------------------+
8 rows in set (0.02 sec)
注:启动过程中,出现任何问题可以使用 docker logs mysql 查看 mysql 容器的输出日志。
我们挂载的宿主机目录下也将产生 mysql 的数据文件:
四. 创建支持SSH服务的镜像
本节的最后一部分我们介绍如何为Docker容器启用ssh服务:首先使用传统的 docker commit 方式为Docker容器安装ssh服务,然后将此修改提交为新的镜像;接着我们会讨论使用Dockerfile创建上述的镜像,以此来抛砖引玉,第七讲 Docker案例实战(二)将详细介绍 Dockerfile 的使用以及注意事项。
4.1 基于 docker commit 方式
首先下载 centos 镜像,并启动为 centos 容器:
[root@localhost docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
[root@localhost docker]# docker pull centos
Using default tag: latest
latest: Pulling from library/centos
8a29a15cefae: Pull complete
Digest: sha256:fe8d824220415eed5477b63addf40fb06c3b049404242b31982106ac204f6700
Status: Downloaded newer image for centos:latest
[root@localhost docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest 470671670cac 3 months ago 237MB
[root@localhost docker]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@localhost docker]# docker run -itd --name centos centos
4dc83818fba06e41b17ab6f58c15734477a4e7592708d9677791e0afc5ed3866
[root@localhost docker]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4dc83818fba0 centos "/bin/bash" 4 seconds ago Up 2 seconds centos
进入 centos 容器,下载、安装、配置并启动 ssh 服务:
[root@localhost docker]# docker exec -it centos /bin/bash
[root@4dc83818fba0 /]# yum install -y openssh-server sudo
Failed to set locale, defaulting to C.UTF-8
... 略
Installed:
openssh-server-8.0p1-4.el8_1.x86_64 sudo-1.8.25p1-8.el8_1.1.x86_64
fipscheck-1.5.0-4.el8.x86_64 fipscheck-lib-1.5.0-4.el8.x86_64
openssh-8.0p1-4.el8_1.x86_64
Complete!
[root@4dc83818fba0 /]# sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config
[root@4dc83818fba0 /]# ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key
Generating public/private dsa key pair.
... 略
The key's randomart image is:
+---[DSA 1024]----+
| . *E|
| . #.o|
| .+.@.|
| . . o=.B|
| S . +.O*|
| o . + %|
| + . =+|
| + . . ..=|
| o.. +X|
+----[SHA256]-----+
[root@4dc83818fba0 /]# ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
Generating public/private rsa key pair.
... 略
The key's randomart image is:
+---[RSA 3072]----+
|oo .o.+.oo.o ..|
|..+o.+.= E=..... |
|. o++o* o. .+ o. |
| o+oo + o + o. |
| . . S o + .o|
| . o o..o|
| o .o |
| oo. |
| oo |
+----[SHA256]-----+
[root@4dc83818fba0 /]# mkdir /var/run/sshd
[root@4dc83818fba0 /]# /usr/sbin/sshd -D
在宿主机上查看 centos 容器的IP地址,并使用 ssh 命令登录容器测试:
[root@localhost ~]# docker inspect centos | grep IPAddress
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.2",
"IPAddress": "172.17.0.2",
[root@localhost ~]# ssh root@172.17.0.2
root@172.17.0.2's password: # 输入我们设置的root用户密码12345678
Last login: Fri Apr 24 05:46:42 2020 from 172.17.0.1
[root@4dc83818fba0 ~]#
提交镜像:
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4dc83818fba0 centos "/bin/bash" About an hour ago Up About an hour centos
[root@localhost ~]# docker commit -m "my centos with ssh" centos centos-ssh:1.0
sha256:4f27624e33f2fe6d85b18564d29937333283dd5821cb57d63d336d6aa54e0abe
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos-ssh 1.0 4f27624e33f2 4 seconds ago 274MB
centos latest 470671670cac 3 months ago 237MB
运行新的镜像 centos-ssh:1.0 ,并指定端口映射及启动容器时的命令:
[root@localhost ~]# docker run -itd --name centos-ssh -p 2222:22 centos-ssh:1.0 /usr/sbin/sshd -D
758080715cee484b8d271b72049f59597121becad5991524680bb2d0e122a130
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
758080715cee centos-ssh:1.0 "/usr/sbin/sshd -D" 4 seconds ago Up 4 seconds 0.0.0.0:2222->22/tcp centos-ssh
4dc83818fba0 centos "/bin/bash" About an hour ago Up About an hour centos
在局域网的其它主机上即可使用 ssh 命令登录到我们刚刚创建的容器:
[root@localhost ~]# ssh -p2222 root@192.168.255.128
The authenticity of host '[192.168.255.128]:2222 ([192.168.255.128]:2222)' can't be established.
RSA key fingerprint is SHA256:Q6AN5pejJINAc8taZ1F1Wgv9+H7gz8RlQ5QaOstgSNw.
RSA key fingerprint is MD5:48:e0:fa:bb:9f:98:8e:be:3f:36:b3:55:37:00:a6:20.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[192.168.255.128]:2222' (RSA) to the list of known hosts.
root@192.168.255.128's password:
Last login: Fri Apr 24 05:58:56 2020 from 172.17.0.1
[root@758080715cee ~]#
总结:基于 docker commit 命令创建镜像只适合于创建临时的镜像,一旦软件需要更新或者要修改容器的其它内容,我们都必须进入容器再进行修改,不利于扩展。Dockerfile 则是一种更加推荐的方式,可以将我们创建镜像的命令记录下来,当需要修改镜像时,只需要更新该脚本文件即可,非常简洁。下面就让我们领会下Dockerfile的强大吧!
4.2 基于 Dockerfile 方式
首先创建一个空目录,在目录下新建文件 Dockerfile ,文件内容如下:
[root@localhost dockerfile]# ls
Dockerfile
[root@localhost dockerfile]# cat Dockerfile
FROM centos:latest
LABEL maintainer="miali MiaLi0521@outlook.com" description="centos with sshd"
RUN yum install -y openssh-server sudo
RUN sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config
RUN echo "root:12345678"|chpasswd
RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
RUN mkdir /var/run/sshd
EXPOSE 22
CMD ["/usr/sbin/sshd","-D"]
[root@localhost dockerfile]#
上述的 Dockerfile 中记录了我们在4.1中的操作,因此 Dockerfile 创建镜像的方式具有很好的扩展性。上述 Dockerfile 中用到的指令总结如下:
这里只抛砖引玉介绍了Dockerfile最常用的几个指令,下一讲中,我们将详细介绍Dockerfile的更多细节。注意RUN和CMD的区别:不要混淆 RUN和 CMD。RUN 实际上运行一个命令并提交结果; CMD 在构建时不执行任何操作,但指定镜像的默认命令。
Dockerfile 文件编辑完成后,即可使用 dcoker build 命令来创建镜像了:
[root@localhost dockerfile]# ls
Dockerfile
[root@localhost dockerfile]# docker build -t centos-ssh:2.0 .
Sending build context to Docker daemon 2.048kB
Step 1/10 : FROM centos:latest
---> 470671670cac
Step 2/10 : LABEL maintainer "miali MiaLi0521@outlook.com" description "centos with sshd"
---> Running in 85876864991a
---> fd93b5681921
Removing intermediate container 85876864991a
Step 3/10 : RUN yum install -y openssh-server sudo
---> Running in 4e24b0f735ba
CentOS-8 - AppStream 2.1 MB/s | 5.7 MB 00:02
CentOS-8 - Base 267 kB/s | 2.2 MB 00:08
CentOS-8 - Extras 7.8 kB/s | 5.5 kB 00:00
Dependencies resolved.
... 略
Installed:
openssh-server-8.0p1-4.el8_1.x86_64 sudo-1.8.25p1-8.el8_1.1.x86_64
fipscheck-1.5.0-4.el8.x86_64 fipscheck-lib-1.5.0-4.el8.x86_64
openssh-8.0p1-4.el8_1.x86_64
Complete!
---> 354e1b84c6a1
Removing intermediate container 4e24b0f735ba
Step 4/10 : RUN sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config
---> Running in 6e2bf574016c
---> 84436db4d051
Removing intermediate container 6e2bf574016c
Step 5/10 : RUN echo "root:12345678"|chpasswd
---> Running in aa22909bac6d
---> 16a97d3c55f0
Removing intermediate container aa22909bac6d
Step 6/10 : RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key
---> Running in e4a787153c89
Enter passphrase (empty for no passphrase): Enter same passphrase again: Generating public/private dsa key pair.
... 略
The key's randomart image is:
+---[DSA 1024]----+
| o=.o. |
| +.=o.. |
|. Eo.. |
|ooB.=. . |
|*oB* . S |
|o%.+. . |
|*=*o |
|+O+ |
|o.+o. |
+----[SHA256]-----+
---> 0735d70f817e
Removing intermediate container e4a787153c89
Step 7/10 : RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
---> Running in 7b101987969c
Enter passphrase (empty for no passphrase): Enter same passphrase again: Generating public/private rsa key pair.
... 略
The key's randomart image is:
+---[RSA 3072]----+
| .. ..=|
| o. .X=|
| . o. +O=B|
| ... . =**|
| S. . o o+|
| o o ..ooE|
| = . . .*o+|
| o . .o=+|
| .o=o|
+----[SHA256]-----+
---> ea08f06c0e6c
Removing intermediate container 7b101987969c
Step 8/10 : RUN mkdir /var/run/sshd
---> Running in 983401b4c171
---> 5375b063e253
Removing intermediate container 983401b4c171
Step 9/10 : EXPOSE 22
---> Running in dd837d3c9d17
---> d699d8eee6a3
Removing intermediate container dd837d3c9d17
Step 10/10 : CMD /usr/sbin/sshd -D
---> Running in d43d558687b7
---> f086b91faede
Removing intermediate container d43d558687b7
Successfully built f086b91faede
Successfully tagged centos-ssh:2.0
[root@localhost dockerfile]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos-ssh 2.0 f086b91faede 12 seconds ago 274MB
[root@localhost dockerfile]# docker run -itd --name centos-ssh2.0 -p 2223:22 centos-ssh:2.0
5ccd02e765a69e260f34d1b95c59393e1b1f0f3e2f416c61c40241077c9a5b41
[root@localhost dockerfile]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5ccd02e765a6 centos-ssh:2.0 "/usr/sbin/sshd -D" 9 seconds ago Up 7 seconds 0.0.0.0:2223->22/tcp centos-ssh2.0
仔细观察上面 Dockerfile 的执行过程,你会发现,每一个RUN命令都会创建一个容器,进行修改,然后提交一个新的镜像,并删除当前容器;然后下一个RUN命令运行刚刚创建的镜像,依次进行修改、提交、删除容器;依次类推,直到所有的RUN指令执行完毕。