Docker 学习记录(二)


一、Docker 镜像详述

1.1 镜像是什么

  镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时的库、环境变量和配置文件。所有的应用直接打包成 docker 镜像,就可以直接跑起来。

  获得镜像的方法:

  • 从远程仓库下载
  • 他人拷贝
  • 自己制作

1.2 Docker 镜像相关原理

UnionFS(联合文件系统)

  Union 文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层地叠加,同时可以将不同目录挂在到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union 文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
  特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。

Docker 镜像加载原理

  Docker 镜像实际上由一层一层的文件系统组成,这种层级的文件系统 UnionFS。

  bootfs(boot file system)主要包含 bootloader 和 kernel,bootloader 主要是引导加载 kernel,Linux 刚启动时会加载 bootfs 文件系统,在 Docker 镜像的最底层是 bootfs。这一层与我们典型的 Linux/Unix 系统是一样的,包括 boot 加载器和内核。当 boot 加载完成之后整个内核就都在内存中了,此时内存的使用权已由 bootfs 转交给内核,此时系统也会卸载 bootfs。

  rootfs(root file system),在 bootfs 之上,包含的就是典型 Linux 系统中的 /dev、/proc、/bin、/etc 等标准目录和文件。rootfs 就是各种不同的操作系统发行版,比如 Ubuntu、CentOS 等等。

  • Docker 中的 CentOS 为什么这么小:对于一个精简的 OS,rootfs 可以很小,只需要包含最基本的命令,工具和程序库就可以,因为底层直接用 Host 的kernel,自己只需要提供 rootfs就可以了。由此可见对于不同的 Linux 发行版,bootfs 基本是一致的,rootfs 会有差别,因此不同的发型版可以公用 bootfs。

1.3 分层理解

分层的镜像

  下载的镜像一层一层的下载,如之前下载的 mysql 的日志过程为例:

~ % docker pull mysql
Using default tag: latest
latest: Pulling from library/mysql
12a06ca91af8: Pull complete
1fec1cb1944f: Pull complete
aede38c79379: Pull complete
51b980849561: Pull complete
f503d79ed4bc: Pull complete
6fb44db361f7: Pull complete
943b6dcee7de: Pull complete
911277c1fe4b: Pull complete
a477017d0457: Pull complete
84b5061403a5: Pull complete
5ff27d035d66: Pull complete
Digest: sha256:3d7ae561cf6095f6aca8eb7830e1d14734227b1fb4748092f2be2cfbccf7d614
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest

分层结构的好处在于,资源共享!例如有多个镜像都从相同的 Base 镜像构建而来,那么宿主机只需要在磁盘上保留一份 Base 镜像,同时内存中也只需要加载一份 base 镜像,这样就可以为所有的容器服务,而且镜像的每一层都可以被共享。

查看镜像的分层通过使用 docker image inspect 镜像名

~ % docker image inspect centos
[
    {
    ...
		"RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:d871dadfb37b53ef1ca45be04fc527562b91989991a8f545345ae3be0b93f92a"
            ]
        },

分析
  所有的 Docker 镜像都起始于一个基础镜像层,当进行修改或者增加内容时,就会在当前镜像层之上,创建新的镜像层。如以下图中的例子,基于 Ubuntu 16.04 创建一个新的镜像,这就是镜像的第一层,如果在该镜像中添加 python 包,就会在基础镜像层上创建第二个镜像层,如果再添加一个安全补丁,就会创建第三个镜像层。
分层示例

  在添加额外的镜像层的同时,镜像始终保持当前所有镜像的组合,下图中展示的是一个稍微复杂的三层镜像,在外部看来整个镜像只有6个文件,因为最上层中的文件7是文件5的一个更新版。
添加文件

  这种情况下,上层镜像层中的文件覆盖了底层镜像层的文件,这样就使得文件的更新版本作为一个新的镜像层添加到镜像当中,Docker 通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统。下图展示了与系统显示相同的三层镜像,所有镜像层堆叠并合并,对外提供统一的视图。

合并堆叠

特点:Docker 镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部,这一层就是我们常说的容器层,容器之下都叫镜像层。


二、实战打包一个新的镜像

2.1 部署 tomcat

# 下载 tomcat 镜像
~ % docker pull tomcat
Using default tag: latest
latest: Pulling from library/tomcat
94a23d3cb5be: Pull complete
ac9d381bd1e9: Pull complete
aa9c5b49b9db: Pull complete
841dd868500b: Pull complete
42dee876d816: Pull complete
c4851c976ae9: Pull complete
e80a0433b650: Pull complete
e10afb8c99ce: Pull complete
7870523e466f: Pull complete
Digest: sha256:9dee185c3b161cdfede1f5e35e8b56ebc9de88ed3a79526939701f3537a52324
Status: Downloaded newer image for tomcat:latest
docker.io/library/tomcat:latest

~ % docker images
REPOSITORY               TAG       IMAGE ID       CREATED         SIZE
tomcat                   latest    b64abfdee99c   13 months ago   668MB
docker/getting-started   latest    720f449e5af2   14 months ago   27.2MB
centos                   latest    e6a0117ec169   16 months ago   272MB

# 启动 tomcat 镜像 暴露端口为8080
~ % docker run -d -p 8080:8080 --name tomcat1 tomcat
cc21a207133db346be97f7fa0f3300421134232bbf6624e03a3653ed00796d6a

  此时我们的tomcat已经启动成功,访问本地 localhost:8080 地址,可以得到如下页面,由于该镜像内容并不完整,会出现这样的页面,但是这说明我们的 tomcat 已经部署成功。

访问结果

  接下来,我们将它完善一下

# 查看镜像信息
~ % docker ps
CONTAINER ID   IMAGE     COMMAND             CREATED          STATUS          PORTS                    NAMES
cc21a207133d   tomcat    "catalina.sh run"   11 minutes ago   Up 11 minutes   0.0.0.0:8080->8080/tcp   tomcat1

# 进入镜像中查看内容
~ % docker exec -it cc21a207133d /bin/bash
root@cc21a207133d:/usr/local/tomcat# ls
BUILDING.txt	 NOTICE		RUNNING.txt  lib	     temp	   work
CONTRIBUTING.md  README.md	bin	     logs	     webapps
LICENSE		 RELEASE-NOTES	conf	     native-jni-lib  webapps.dist
root@cc21a207133d:/usr/local/tomcat# cd webapps
root@cc21a207133d:/usr/local/tomcat/webapps# ls
root@cc21a207133d:/usr/local/tomcat#

# 我们发现 webapps 文件夹下没有任何文件,文件都在 webapps.dist 下,将内容都拷贝进 webapps 中
root@cc21a207133d:/usr/local/tomcat# cp -r webapps.dist/* webapps
root@cc21a207133d:/usr/local/tomcat# cd webapps
root@cc21a207133d:/usr/local/tomcat/webapps# ls
ROOT  docs  examples  host-manager  manager

  现在我们已经将它完善部署成功了,我们重新访问本地 localhost:8080 地址,就能得到这样的页面,说明已经完善成功。

tomcat

2.2 Commit 提交自己的镜像

  将我们完善好的 tomcat 镜像打包成新的镜像,使用的命令为docker commit

docker commit -m="提交的描述信息" -a="作者信息" 容器ID 目标镜像名:[TAG]

# 打包镜像
~ % docker ps
CONTAINER ID   IMAGE     COMMAND             CREATED          STATUS          PORTS                    NAMES
cc21a207133d   tomcat    "catalina.sh run"   30 minutes ago   Up 30 minutes   0.0.0.0:8080->8080/tcp   tomcat1

~ % docker commit -m="add webapps app" -a="sihengshen" cc21a207133d tomcat2:1.0
sha256:da365a5106011f1d3bb8a205527de1e73b287480dc6e91f8c41392bd569647c6

~ % docker images
REPOSITORY               TAG       IMAGE ID       CREATED          SIZE
tomcat2                  1.0       da365a510601   43 seconds ago   673MB	# 这是我们自己打包的镜像
tomcat                   latest    b64abfdee99c   13 months ago    668MB
docker/getting-started   latest    720f449e5af2   14 months ago    27.2MB
centos                   latest    e6a0117ec169   16 months ago    272MB

  至此,我们就完成了实战打包镜像的过程。


三、容器数据卷

3.1 命令挂载

  容器数据卷的概念:如果数据存在容器之中,那么我们删除容器数据就会丢失,例如使用 Mysql数据库,删了容器之后数据库就没了,若要保证不会出现删库跑路的情况,就需要容器之间有一个数据共享的技术,即 Docker 容器中的数据同步到本地。

  使用数据卷的方法

docker run -it -v 主机目录地址:容器内目录地址

# 测试 将 CentOS 容器的目录 /home 挂载在 本机目录 /home/ceshi下
docker run -it -v /home/ceshi:/home centos /bin/bash

# 通过 docker inspect 容器ID

挂载目录

  至此,我们就完成了目录的搭载,能够保证容器内容不会丢失,我们需要修改内容只需要在本地修改,容器内会自动同步,还有一个Mysql的实战大家可以自己尝试。

具名挂载和匿名挂载:是否在-v后添加卷名称,查看数据卷相关操作可以使用docker volume --help查看。

# 匿名挂载
docker -v 容器内路径

# 具名挂载
docker -v 卷名:容器内路径

# 指定路径挂载
docker -v 宿主机路径:容器内路径

读写权限:docker run -d -P -v name:路径:ro/rw
ro:readonly——只读
rw:readwrite——可读可写

3.2 Dockerfile 挂载

  Dockerfile 就是用来构建 docker 镜像的构建文件,命令脚本,通过这个脚本可以生成镜像,镜像是一层一层的,脚本一个个的命令,每个命令都是一层。

  先编写一个 Dockerfile 文件,然后构建镜像。

# 创建一个 dockerfile 文件,名字建议为 Dockerfile
# 文件中所有内容指令大写
~ % cat Dockerfile 
FROM centos

VOLUME ["volume01", "volume02"]

CMD echo "---end---"

CMD /bin/bash

# 构建镜像
~ % docker build -f ./Dockerfile -t centos:1.0 .
Sending build context to Docker daemon  2.048kB
Step 1/4 : FROM centos
latest: Pulling from library/centos
a1d0c7532777: Already exists 
Digest: sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177
Status: Downloaded newer image for centos:latest
 ---> 5d0da3dc9764
Step 2/4 : VOLUME ["volume01", "volume02"]
 ---> Running in b7e68fd690d9
Removing intermediate container b7e68fd690d9
 ---> 3e2806f7944b
Step 3/4 : CMD echo "---end---"
 ---> Running in 6689c2dd857b
Removing intermediate container 6689c2dd857b
 ---> 5978d9517c38
Step 4/4 : CMD /bin/bash
 ---> Running in 048dd2705ef4
Removing intermediate container 048dd2705ef4
 ---> d6430d99300d
Successfully built d6430d99300d
Successfully tagged centos:1.0

~ % docker images
REPOSITORY          TAG       IMAGE ID       CREATED         SIZE
centos   			1.0       d6430d99300d   2 minutes ago   231MB

这种方法是匿名挂载,这种方式我们未来使用特别多,如果构建镜像的时候没有挂载数据卷,就需要使用-v 卷名:容器内路径手动挂载。

3.3 数据卷容器

  能够实现两个或者多个容器之间数据共享,使用命令--volume-from 容器名。容器之间配置信息的传递,数据卷容器的生命一直持续到没有容器使用为止。但是一旦持久化到了本地,即将数据挂载到本地,本地数据就是不会删除的。


四、Dockerfile

4.1 Dockerfile 介绍

  在上一小节中,我们初步的认识了一下 Dockerfile,它是用来构建 docker 镜像的文件,命令参数脚本。具体构建步骤为:

  • 编写一个 dockerfile 文件;
  • docker build构建成为一个镜像;
  • docker run运行镜像;
  • docker push发布镜像(DockerHub、阿里云镜像仓库)。

4.2 Dockerfile 构建过程

基础内容

  • 所有保留关键字(指令)都必须是大写字母
  • 执行从上到下顺序执行
  • # 表示注释
  • 每个指令都会创建提交一个新的镜像层并提交

层级关系

  Dockerfile 是面向开发的,之后需要发布项目做镜像,就需要通过编写 Dockerfile 文件。Docker 镜像逐渐成为企业交付的标准。开发、部署、运维缺一不可。

  • Dockerfile:构建文件,定义了一切的步骤,源代码;
  • Docker 镜像:通过 Dockerfile 构建生成的镜像,最终发布和运行的产品;
  • Docker 容器:容器就是镜像运行起来提供服务的。

4.3 Dockerfile 指令

FROM		# 基础镜像,一切从这里开始构建
MAINTAINER	# 镜像是谁写的,姓名 + 邮箱
RUN			# 镜像构建的时候需要运行的命令
ADD			# 添加内容
WORKDIR		# 镜像的工作目录
EXPOSE		# 暴露端口设置
CMD			# 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT	# 指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD		# 当构建一个被继承 Dockerfile 这个时候就会运行 ONBUILD 命令。触发指令
COPY		# 类似 ADD,将文锦啊拷贝到镜像中
ENV			# 构建的时候设置环境变量

Dockerfile 指令

4.4 实战测试

4.4.1 实战一:构建自己的 CentOS

  之前都是使用别人搭建好的镜像,现在我们动手实战构建一个尝试一下。Docker Hub 中99%的镜像都是从FROM scratch这个基础镜像过来的,然后配置需要的软件和配置来进行构建。

  1. 编写 Dockerfile
~ % cat Dockerfile 
FROM centos
MAINTAINER Mark<sihengshen@foxmail.com>

ENV MYPATH /usr/local
WORKDIR $MYPATH

RUN cd /etc/yum.repos.d/ \
	&& sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-* \
	&& sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-* \
	&& yum makecache \
	&& yum update -y \
	&& yum -y install vim \
	&& yum -y install net-tools

EXPOSE 80

CMD echo $MYPATH
CMD echo "----end-----"
CMD /bin/bash

⚠️注意: 如果按照视频中编写 Dockerfile,会出现如下报错信息Error: Failed to download metadata for repo ‘appstream‘: Cannot prepare internal mirrorlist,这是因为 CentOS 已经停止维护。因此需要进行相应的修改,上述内容是修改后可以成功运行的内容。

  1. 通过这个文件构建镜像
# 构建命令 docker build -f Dockerfile文件路径 -t 镜像名:[tag]
~ % docker build -f Dockerfile -t centosplus:latest .
...
Successfully built d19008ae7207
Successfully tagged centosplus:latest

这样就说明构建成功。

⚠️注意: 镜像构建成功后,使用docker images命令查看,发现很多<none>:<none>的镜像,这样的镜像可能有用,有用的镜像是由于镜像分层的中间镜像。它们只会在docker images -a才会显示出来,用docker images是不会显示的。它们也不会造成占用磁盘空间问题;也可能无用,无用的镜像会占用空间,主要是由于新加镜像替换原来相对标签的镜像,原来镜像就变成了<none>:<none>而没有被删除,无用的镜像可以使用命令docker rmi $(docker images -f "dangling=true" -q)删除。

  1. 验证一下
~ % docker run -it centosplus

[root@4884d292c133 local]# pwd
/usr/local
[root@4884d292c133 local]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.4  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:ac:11:00:04  txqueuelen 0  (Ethernet)
        RX packets 8  bytes 656 (656.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
[root@4884d292c133 local]# nano

验证成功,我们需要安装的内容已经成功安装。

补充: 我们还可以通过命令docker history 镜像ID查看镜像的构建步骤。

4.4.2 CMD 和 ENTRYPOINT 的区别

CMD			# 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT	# 指定这个容器启动的时候要运行的命令,可以追加命令
  • 测试 CMD
# 编写 Dockerfile 文件
~ % cat cmd-Dockerfile 
FROM centos
CMD ["ls", "-a"]

# 构建镜像
~ % docker build -f cmd-Dockerfile -t cmdcentos:latest .
Sending build context to Docker daemon  3.072kB
Step 1/2 : FROM centos
 ---> 5d0da3dc9764
Step 2/2 : CMD ["ls", "-a"]
 ---> Running in f38ad3f00d47
Removing intermediate container f38ad3f00d47
 ---> ed9e59c253f4
Successfully built ed9e59c253f4
Successfully tagged cmdcentos:latest

# 运行镜像,我们的命令 ls -a 生效
~ % docker run ed9e59c253f4
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var

# 追加命令 -l,成为 ls -al
~ % docker run ed9e59c253f4 -l
docker: Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "-l": executable file not found in $PATH: unknown.
ERRO[0001] error waiting for container: context canceled

# CMD 指令下,是直接替换上一个命令,因此会报错,如下运行就可以实现
~ % docker run ed9e59c253f4 ls -al
total 56
drwxr-xr-x   1 root root 4096 Feb  1 06:29 .
drwxr-xr-x   1 root root 4096 Feb  1 06:29 ..
-rwxr-xr-x   1 root root    0 Feb  1 06:29 .dockerenv
lrwxrwxrwx   1 root root    7 Nov  3  2020 bin -> usr/bin
drwxr-xr-x   5 root root  340 Feb  1 06:29 dev
drwxr-xr-x   1 root root 4096 Feb  1 06:29 etc
drwxr-xr-x   2 root root 4096 Nov  3  2020 home
lrwxrwxrwx   1 root root    7 Nov  3  2020 lib -> usr/lib
lrwxrwxrwx   1 root root    9 Nov  3  2020 lib64 -> usr/lib64
drwx------   2 root root 4096 Sep 15  2021 lost+found
drwxr-xr-x   2 root root 4096 Nov  3  2020 media
drwxr-xr-x   2 root root 4096 Nov  3  2020 mnt
drwxr-xr-x   2 root root 4096 Nov  3  2020 opt
dr-xr-xr-x 123 root root    0 Feb  1 06:29 proc
dr-xr-x---   2 root root 4096 Sep 15  2021 root
drwxr-xr-x  11 root root 4096 Sep 15  2021 run
lrwxrwxrwx   1 root root    8 Nov  3  2020 sbin -> usr/sbin
drwxr-xr-x   2 root root 4096 Nov  3  2020 srv
dr-xr-xr-x  13 root root    0 Feb  1 06:29 sys
drwxrwxrwt   7 root root 4096 Sep 15  2021 tmp
drwxr-xr-x  12 root root 4096 Sep 15  2021 usr
drwxr-xr-x  20 root root 4096 Sep 15  2021 var
  • 测试 ENTRYPOINT
# 编写 Dockerfile 文件
~ % cat cmd-Dockerfile 
FROM centos
ENTRYPOINT ["ls", "-a"]

# 构建镜像
~ % docker build -f entrypoint-Dockerfile -t entcentos:latest .
Sending build context to Docker daemon  4.096kB
Step 1/2 : FROM centos
 ---> 5d0da3dc9764
Step 2/2 : ENTRYPOINT ["ls", "-a"]
 ---> Running in 55fd70dc9072
Removing intermediate container 55fd70dc9072
 ---> dbee450e5e1f
Successfully built dbee450e5e1f
Successfully tagged entcentos:latest

# 运行镜像,我们的命令 ls -a 生效
~ % docker run dbee450e5e1f
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var

# 使用了 
~ % docker run dbee450e5e1f -l
total 56
drwxr-xr-x   1 root root 4096 Feb  1 06:41 .
drwxr-xr-x   1 root root 4096 Feb  1 06:41 ..
-rwxr-xr-x   1 root root    0 Feb  1 06:41 .dockerenv
lrwxrwxrwx   1 root root    7 Nov  3  2020 bin -> usr/bin
drwxr-xr-x   5 root root  340 Feb  1 06:41 dev
drwxr-xr-x   1 root root 4096 Feb  1 06:41 etc
drwxr-xr-x   2 root root 4096 Nov  3  2020 home
lrwxrwxrwx   1 root root    7 Nov  3  2020 lib -> usr/lib
lrwxrwxrwx   1 root root    9 Nov  3  2020 lib64 -> usr/lib64
drwx------   2 root root 4096 Sep 15  2021 lost+found
drwxr-xr-x   2 root root 4096 Nov  3  2020 media
drwxr-xr-x   2 root root 4096 Nov  3  2020 mnt
drwxr-xr-x   2 root root 4096 Nov  3  2020 opt
dr-xr-xr-x 123 root root    0 Feb  1 06:41 proc
dr-xr-x---   2 root root 4096 Sep 15  2021 root
drwxr-xr-x  11 root root 4096 Sep 15  2021 run
lrwxrwxrwx   1 root root    8 Nov  3  2020 sbin -> usr/sbin
drwxr-xr-x   2 root root 4096 Nov  3  2020 srv
dr-xr-xr-x  13 root root    0 Feb  1 06:29 sys
drwxrwxrwt   7 root root 4096 Sep 15  2021 tmp
drwxr-xr-x  12 root root 4096 Sep 15  2021 usr
drwxr-xr-x  20 root root 4096 Sep 15  2021 var

4.4.3 实战二:部署 tomcat

  现在我们来部署一个更复杂的镜像,自己构建一个 tomcat 镜像并部署。

  1. 准备压缩包

  我们需要先在服务器中新建一个文件夹 tomcat,并准备好两个压缩包:apache-tomcat-8.0.23.tar.gzjdk-8u131-linux-x64.tar.gz,下面是如何在服务器利用命令下载压缩包的方式。

  • tomcat 压缩包:使用命令wget https://archive.apache.org/dist/tomcat/tomcat-8/v8.0.23/bin/apache-tomcat-8.0.23.tar.gz下载;
  • jdk 压缩包:去官网搜索相关压缩包,登录后复制下载链接,因为不花时间再登录了,就复制了一个别人的下载链接,直接使用命令wget --no-check-certificate --no-cookies --header "Cookie: oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u131-b11/d54c1d3a095b4ff2b6607d096fa80163/jdk-8u131-linux-x64.tar.gz就能下载成功。

此刻我们的压缩包已经准备完成。

~/tomcat % ls
apache-tomcat-8.0.23.tar.gz  jdk-8u131-linux-x64.tar.gz
  1. 编写 Dockerfile 文件
~/tomcat % cat Dockerfile
FROM centos
MAINTAINER siheng<sihengshen@foxmail.com>

COPY README.md /usr/local/README.md
ADD jdk-8u131-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-8.0.23.tar.gz /usr/local/

RUN cd /etc/yum.repos.d/ \
	&& sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-* \
	&& sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-* \
	&& yum makecache \
	&& yum update -y \
	&& yum -y install nano

ENV MYPATH /usr/local
WORKDIR $MYPATH

ENV JAVA_HOME /usr/local/jdk1.8.0_131
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools/jar
ENV CATALINA_HOME /usr/local/apache-tomcat-8.0.23
ENV CATALINA_BASH /usr/local/apache-tomcat-8.0.23
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin

EXPOSE 8080

CMD /usr/local/apache-tomcat-8.0.23/bin/startup.sh && tail -F /url/local/apache-tomcat-8.0.23/bin/logs/catalina.out
  1. 构建镜像
~/tomcat % docker build -t diytomcat .

构建镜像

  1. 启动镜像

  使用命令docker run -d -p 8082:8080 --name sihengtomcat -v /root/ssh/tomcat/test:/usr/local/apache-tomcat-8.0.23/webapps/test -v /root/ssh/tomcat/tomcatlogs:/usr/local/apache-tomcat-8.0.23/logs diytomcat启动容器,其中对应暴露端口以及挂载目录。运行后测试访问8082端口成功。

成功

  1. 发布项目

  因为我们做了挂载目录的操作,因此只需要在本机的/root/ssh/tomcat/test目录下发布项目内容即可。首先在其中创建一个 index.html 文件。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>tomcat</title>
	</head>
	
	<body>
		<h1>
			我自己的第一个tomcat镜像!
		</h1>
	</body>
</html>

然后访问8082端口的 test 目录,测试成功。
tomcat测试

综上,我们以后开发的过程中,只要部署成功即可直接访问。

4.5 发布镜像

发布到 Docker Hub

  1. 注册一个 Docker Hub 账号;
  2. 在服务器使用命令docker login -u 用户名登录账号,然后输入密码,密码正确即可登录成功;
  3. 发布之前使用命令docker tag 用户名/镜像名:[tag]修改要发布的镜像标签,然后使用命令docker push 用户名/镜像名:[tag]发布镜像。

发布到阿里云镜像仓库

  1. 登录到阿里云,进入控制台,选择容器镜像服务

容器镜像服务

  1. 创建相关内容

  如果是第一次使用,需要经过以下步骤:

  • 创建个人实例
  • 创建命名空间
  • 创建镜像仓库:填写相关内容,选择本地仓库为代码源。

创建镜像仓库1
创建镜像仓库2

仓库创建成功后,点击进去可以看到对应的推送操作,按照过程执行命令即可。

4.6 小结

Docker全流程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值