1. 提前说明

到目前为止,已经介绍了如何启动一个简单的容器,并与之进行交互。同时也知道了如何停止、重启以及删除一个容器。接下来将展示一个Linux Web服务示例。

笔者将介绍通过docker command 以及 Dockerfile方式部署Linux Web服务。

Linux中主流的web服务有nginx、tomcat、apache、weblogic。因为笔者负责的java项目,这里web服务以tomcat为示例。

在该示例中,会使用到tomcat镜像。这个镜像会在"8888"端口启动一个相当简单为Web服务。

这一节只部署web服务,不会讲解容器共享数据卷存储、容器网络等要点,后续在做相关说明。

2. 通过docker command方式部署

    2.1 直接启动web容

[root@doc03 ~]# docker run -itd --name tomcat-v1.0 -p 8888:8080 tomcat
Unable to find image 'tomcat:latest' locally
....
Digest: sha256:a655be865e9f62d6d2ed3823c7382a2d77d0a034eb17714bbf2a514c3f620717
Status: Downloaded newer image for tomcat:latest
264ba249d3b6ce9eb0174a57f1f00cfc50f2417a30173ab3c02062815d427647

        ● -p

            Docker物理机的端口映射到容器内,端口信息按照 "host-port:container-port"格式显示,这一点很重要

            将Docker物理机的"8888"端口映射到容器内的"8080"(tomcat默认)端口。这意味着当有流量访问主机的"8888"端口的时候,流量会直接映射到容器内的"8080"端口

    2.2 查看web容器运行状态

[root@doc03 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
264ba249d3b6        tomcat              "catalina.sh run"   3 minutes ago       Up 3 minutes        0.0.0.0:8888->8080/tcp   tomcat-v1.0

        当host不指名时,默认使用"0.0.0.0"所有地址

    2.3 访问Web服务

        获取请求本机http://$ip:8888的http状态码

[root@doc03 ~]# curl -o /dev/null -s -w %{http_code} http://10.125.7.74:8888 && echo ""
404

        http状态码404一般是2种情况

    ● 请求的地址不存在(tomcat默认项目路径为webapps/ROOT)

    ● 请求的地址没有权限访问

[root@doc03 ~]# docker exec -it tomcat-v1.0 /bin/bash
root@264ba249d3b6:/usr/local/tomcat# cd webapps
root@264ba249d3b6:/usr/local/tomcat/webapps# ls
root@264ba249d3b6:/usr/local/tomcat/webapps

        发现"webapps"下没有任何项目路径

root@264ba249d3b6:/usr/local/tomcat/webapps# mkdir -pm 755 ROOT
root@264ba249d3b6:/usr/local/tomcat/webapps# echo "Hi, Docker Daemon" > ROOT/index.html

        创建Web首页,注意目录、文件权限

[root@doc03 ~]# curl -o /dev/null -s -w %{http_code} http://10.125.7.74:8888
200
[root@doc03 ~]# curl http://10.125.7.74:8888
Hi, Docker Daemon

        http状态码为200且主页地址正常访问

        笔者做过一个尝试,将"tomcat-v1.0"容器导出为镜像,再基于此镜像创建2个容器"tomcat-v1.1"、"tomcat-v1.2",启动时抛出"无法找到java环境"导致启动失败。

        "export" 和 "import" 导出的是一个容器当时的快照, 不是镜像本身, 也就是说没有镜像分层(依赖镜像)。快照文件将丢弃所有的历史记录和元数据信息,例如工作目录(workdir)、启动命令(entrypoint)、历史提交信息(commit)等都会丢失。所以启动时会抛出"Neither the JAVA_HOME nor the JRE_HOME environment variable is defined"

        对此笔者有个疑问,"import"的作用是什么?nginx、apache的Web服务是否会受此限制,后续试验一下。

        相比于"save"、"load",最大的区别于以下四点:

            ● docker save 保存的是镜像(image),docker export 保存的是容器(container)

            ● docker load 用来载入镜像包,docker import 用来载入容器包,但两者都会恢复为镜像

            ● docker load 不能对载入的镜像重命名,而 docker import 可以为镜像指定新名称

            ● docker load 保存镜像完整记录,包含分层镜像,所以文件体积会比docker export的更大一些

3. 通过dockerfile方式部署   

    3.1 什么是Dockerfile

        Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。

        这里仅讲解如何运行 Dockerfile 文件来定制一个镜像,具体 Dockerfile 文件内指令详解,将在下一节中介绍,这里你只要知道构建的流程即可。

    3.1 简单的tomcat dockerfile镜像文件

[root@doc03 ~]# cat tomcat_dockerfile
FROM tomcat
MAINTAINER wangtianci<13623650548@163.com>
WORKDIR /usr/local/tomcat
RUN mkdir -pm 755 ./webapps/ROOT
COPY ./index.html ./webapps/ROOT
EXPOSE 8080
CMD ["./bin/catalina.sh", "run"]
[root@doc03 ~]# cat index.html 
Dcoerkfile make image

        ● FROM

            下载目标镜像,每个Dockerfile文件一行都是FORM指令,当前应用的剩余内容会作为新增镜像层添加到基础镜像层之上        

        ● MAINTAINER

            作者信息,作为镜像的元数据信息,不构建镜像

        ● WORKDIR

            为Dockerfile中尚未执行的指令设置工作目录,该目录与镜像相关,并且会作为元数据记录到镜像配置中,但不会创建新的镜像层,笔者理解类似于家目录

        ● RUN

            执行shell command,进入容器后执行的命令

        ● COPY

            拷贝文件,host_file_path:container_file_path,将应用相关文件从构建上下文复制到了当前镜像中

            笔者测试时 "host_file_path"文件必须与dockerfile文件在同一目录

        ● EXPOSE

            指定容器内监听的tcp端口,作为元数据被保存下来,不会产生新的镜像层

        ● CMD

            为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效

        ● 镜像分层图可以理解如下

容器 - Web服务示例(6)_docker、容器、dockerfile

        其他参数可参考

            https://www.runoob.com/docker/docker-dockerfile.html   

    3.3 创建镜像

[root@doc03 ~]# docker build -f /root/tomcat_dockerfile -t tomcat_dockerfile:v1 .
Sending build context to Docker daemon  216.6MB
Step 1/7 : FROM tomcat
 ---> bd431ca8553c
Step 2/7 : MAINTAINER wangtianci<13623650548@163.com>
 ---> Running in 4683fbd16a41
Removing intermediate container 4683fbd16a41
 ---> ee23a3dedb31
Step 3/7 : WORKDIR /usr/local/tomcat
 ---> Running in 665b3f0e6185
Removing intermediate container 665b3f0e6185
 ---> d297b25ac4d8
Step 4/7 : RUN mkdir -pm 755 ./webapps/ROOT
 ---> Running in 055a60198fcf
Removing intermediate container 055a60198fcf
 ---> 5a00a1e6bb7d
Step 5/7 : COPY ./index.html ./webapps/ROOT
 ---> ceede2153756
Step 6/7 : EXPOSE 8080
 ---> Running in a94bc7fcbf1b
Removing intermediate container a94bc7fcbf1b
 ---> d89243858b42
Step 7/7 : CMD ["./bin/catalina.sh", "run"]
 ---> Running in 7358b3ea7e21
Removing intermediate container 7358b3ea7e21
 ---> 5af688cf0cdd
Successfully built 5af688cf0cdd
Successfully tagged tomcat_dockerfile:v1

        ● -f

            指明Dockerfile文件路径,可以是绝对路径或者是目标目录

        ● -t

            制定镜像生成的标签,格式为<REPOSITORY>:<TAG>

        ● .

            注意末尾的".",这个非常重要,一定要在目录最后包含这个"."。命令最后的"."表示Dockerfile在进行构建的时候,使用当前目录作为构建上下文

[root@doc03 ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
tomcat_dockerfile   v1                  5af688cf0cdd        49 seconds ago      667MB
tomcat_cp           tomcat_v1.0         1fe040a4a939        20 hours ago        659MB
tomcat              latest              bd431ca8553c        5 days ago          667MB
[root@doc03 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
264ba249d3b6        tomcat              "catalina.sh run"   20 hours ago        Up 20 hours         0.0.0.0:8888->8080/tcp   tomcat-v1.0

    3.4 创建容器并验证    

[root@doc03 ~]# docker run -d --name tomcat_dockerfile-v1.0 -p 9999:8080 tomcat_dockerfile:v1
13d20727b68c95da939416943b120e09d8b2a900e5d3bf447a9fe9e58a602f81
[root@doc03 ~]# docker ps
CONTAINER ID        IMAGE                  COMMAND                  CREATED             STATUS              PORTS                    NAMES
13d20727b68c        tomcat_dockerfile:v1   "./bin/catalina.sh r…"   3 seconds ago       Up 1 second         0.0.0.0:9999->8080/tcp   tomcat_dockerfile-v1.0
264ba249d3b6        tomcat                 "catalina.sh run"        20 hours ago        Up 20 hours         0.0.0.0:8888->8080/tcp   tomcat-v1.0
[root@doc03 ~]# curl http://10.125.7.74:9999
Dcoerkfile make image