简介

定义

  • 用来构建docker 镜像的文件

构建步骤

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

基础知识

  • 每个保留关键字 (指令) 都必须是大写字母
  • 从上倒下顺序执行
  • 表示注释

  • 每一个指令都会创建提交一个新的镜像层并提交
  • DockerFile 是面向开发的, 之后需要发布项目, 做镜像, 就需要编写dockerfile 文件, 且逐渐成为了企业交付的标准

    关系

  • DockerFile: 构建文件, 定义了一切的步骤, 源代码

  • DockerImages: 通过DockerFile 构建生成的镜像, 最终发布和运行的产品, 原来是jar, war
  • Docker 容器: 容器就是镜像运行起来提供服务

指令

指令 含义
FROM 基础镜像, 一切从这里开始构建
MAINTAINER 镜像是谁写的, 姓名 + 邮箱
RUN Docker 镜像构建时需要运行的命令
ADD 添加内容
e.g. 添加 tomcat 压缩包, ADD 后需要跟上tomcat 压缩包,
格式: ADD source_dir/file dest_dir/file
WORKDIR 镜像的工作目录
格式: WORKDIR path_dir
VOLUME 挂载目录
EXPOSE 端口配置
CMD 指定启动容器时需要运行的命令 (只有最后一个会生效, 可以被替代)
e.g. docker run -l
在容器运行时, CMD ls -a, 这时 -l 会替代 ls -a
ENTRYPOINT 指定启动容器时需要运行的命令 (可以追加命令)
e.g. 如上, -l 会追加到 ls -a 后, 形成ls -a -l 命令
ONBUILD 当构建一个被继承 DockerFile 这个时候就会运行 ONBUILD 的指令, 触发指令
COPY 类似ADD, 将文件拷贝到镜像中
格式: COPY source_dir/file dest_dir/file
ENV 构建时设置环境变量
格式: ENV key value
ARG 设置编译镜像时加入的参数
格式: ARG variable

实战测试

  • Docker Hub 中99% 的镜像都是以sretch 为基础镜像

image.png

  • 创建一个自己的centos:
    1. 编写dockerfile: ```shell

      因为不写版本导致使用了最新版本的镜像, 在后面执行yum install 时就会报下载失败, 没有mirror url 的地址

      FROM centos:7 MAINTAINER flmfuliming018@icloud.com

ENV MYPATH /usr/local WORKDIR $MYPATH

RUN yum -y install vim RUN yum -y install net-tools

EXPOSE 80

CMD echo $MYPATH CMD echo “——end——“ CMD /bin/bash

  1. b. 通过这个文件构建镜像
  2. ```shell
  3. #-f: 后面跟dockerfile 文件路径
  4. #-t: 后面跟镜像名:[tag]
  5. docker build -f mydockerfile-centos -t mycentos:0.1 .

image.png
c. 启动自定义镜像, 观察dockerfile 中的配置
image.png

  • 可以使用ifconfig 命令
  • 可以使用vim 命令
  • 已进入系统, 默认工作路径为/usr/local

History 命令

  • 作用:
    • 查看镜像生成步骤
  • 语法:

    1. docker history 镜像ID
  • 效果:

image.png

CMD 与ENTRYPOINT 的区别

测试CMD (只有最后一个命令会被运行)

  1. 编写dockerfile

    1. FROM centos
    2. CMD ["ls", "-a"]
  2. 构建镜像

    1. docker build -f dockerfile-cmd-test -t cmdtest:0.1 .
  3. 启动容器

    1. docker run cmdtest:0.1
    2. #以下是容器启动后的提示
    3. .
    4. ..
    5. .dockerenv
    6. bin
    7. dev
    8. etc
    9. home
    10. lib
    11. lib64
    12. lost+found
    13. media
    14. mnt
    15. opt
    16. proc
    17. root
    18. run
    19. sbin
    20. srv
    21. sys
    22. tmp
    23. usr
    24. var
  • 错误示范: 想在ls -a 命令之后追加参数-l, 发现错误

    1. docker run cmdtest:0.1 -l
    2. #出现以下错误:
    3. #原因: 使用CMD 命令的情况下, 会将ls -a 替换成-l, 而-l 不是一条完整的命令, 就会报错
    4. container_linux.go:235: starting container process caused "exec: \"-l\": executable file not found in $PATH"
    5. /usr/bin/docker-current: Error response from daemon: oci runtime error: container_linux.go:235: starting container process caused "exec: \"-l\": executable file not found in $PATH".
    6. ERRO[0000] error getting events from daemon: net/http: request canceled
  • 正确写法:

    1. #写成ls -al
    2. docker run cmdtest:0.1 ls -al
    3. #产生以下提示
    4. total 0
    5. drwxr-xr-x. 1 root root 17 Feb 1 08:06 .
    6. drwxr-xr-x. 1 root root 17 Feb 1 08:06 ..
    7. -rwxr-xr-x. 1 root root 0 Feb 1 08:06 .dockerenv
    8. lrwxrwxrwx. 1 root root 7 Nov 3 2020 bin -> usr/bin
    9. drwxr-xr-x. 5 root root 340 Feb 1 08:06 dev
    10. drwxr-xr-x. 1 root root 66 Feb 1 08:06 etc
    11. drwxr-xr-x. 2 root root 6 Nov 3 2020 home
    12. lrwxrwxrwx. 1 root root 7 Nov 3 2020 lib -> usr/lib
    13. lrwxrwxrwx. 1 root root 9 Nov 3 2020 lib64 -> usr/lib64
    14. drwx------. 2 root root 6 Sep 15 14:17 lost+found
    15. drwxr-xr-x. 2 root root 6 Nov 3 2020 media
    16. drwxr-xr-x. 2 root root 6 Nov 3 2020 mnt
    17. drwxr-xr-x. 2 root root 6 Nov 3 2020 opt
    18. dr-xr-xr-x. 213 root root 0 Feb 1 08:06 proc
    19. dr-xr-x---. 2 root root 162 Sep 15 14:17 root
    20. drwxr-xr-x. 1 root root 21 Feb 1 08:06 run
    21. lrwxrwxrwx. 1 root root 8 Nov 3 2020 sbin -> usr/sbin
    22. drwxr-xr-x. 2 root root 6 Nov 3 2020 srv
    23. dr-xr-xr-x. 13 root root 0 Feb 1 06:30 sys
    24. drwxrwxrwt. 7 root root 171 Sep 15 14:17 tmp
    25. drwxr-xr-x. 12 root root 144 Sep 15 14:17 usr
    26. drwxr-xr-x. 20 root root 262 Sep 15 14:17 var

测试ENTRYPOINT

  1. 编写dockerfile

    1. FROM centos
    2. ENTRYPOINT ["ls", "-a"]
  2. 构建镜像

    1. docker build -f dockerfile-cmd-entrypoint -t entrypoint-test:0.1 .
    2. #产生以下提示, 说明镜像生成成功
    3. Sending build context to Docker daemon 4.096 kB
    4. Step 1/2 : FROM centos:7
    5. ---> eeb6ee3f44bd
    6. Step 2/2 : ENTRYPOINT ls -a
    7. ---> Running in 36fd4f02cd9d
    8. ---> 66afa7c89a03
    9. Removing intermediate container 36fd4f02cd9d
    10. Successfully built 66afa7c89a03
  3. 启动容器

    1. docker run entrypoint-test:0.1
    2. #以下是容器启动后的提示
    3. .
    4. ..
    5. .dockerenv
    6. bin
    7. dev
    8. etc
    9. home
    10. lib
    11. lib64
    12. lost+found
    13. media
    14. mnt
    15. opt
    16. proc
    17. root
    18. run
    19. sbin
    20. srv
    21. sys
    22. tmp
    23. usr
    24. var
  • 在run 命令后添加需要追加的参数:
    1. #会拼接在ENTRYPOINT 的命令后
    2. docker run entrypoint-test:0.1 -l
    3. total 12
    4. drwxr-xr-x. 1 root root 17 Feb 1 08:08 .
    5. drwxr-xr-x. 1 root root 17 Feb 1 08:08 ..
    6. -rwxr-xr-x. 1 root root 0 Feb 1 08:08 .dockerenv
    7. -rw-r--r--. 1 root root 12114 Nov 13 2020 anaconda-post.log
    8. lrwxrwxrwx. 1 root root 7 Nov 13 2020 bin -> usr/bin
    9. drwxr-xr-x. 5 root root 340 Feb 1 08:08 dev
    10. drwxr-xr-x. 1 root root 66 Feb 1 08:08 etc
    11. drwxr-xr-x. 2 root root 6 Apr 11 2018 home
    12. lrwxrwxrwx. 1 root root 7 Nov 13 2020 lib -> usr/lib
    13. lrwxrwxrwx. 1 root root 9 Nov 13 2020 lib64 -> usr/lib64
    14. drwxr-xr-x. 2 root root 6 Apr 11 2018 media
    15. drwxr-xr-x. 2 root root 6 Apr 11 2018 mnt
    16. drwxr-xr-x. 2 root root 6 Apr 11 2018 opt
    17. dr-xr-xr-x. 214 root root 0 Feb 1 08:08 proc
    18. dr-xr-x---. 2 root root 114 Nov 13 2020 root
    19. drwxr-xr-x. 1 root root 21 Feb 1 08:08 run
    20. lrwxrwxrwx. 1 root root 8 Nov 13 2020 sbin -> usr/sbin
    21. drwxr-xr-x. 2 root root 6 Apr 11 2018 srv
    22. dr-xr-xr-x. 13 root root 0 Feb 1 06:30 sys
    23. drwxrwxrwt. 7 root root 132 Nov 13 2020 tmp
    24. drwxr-xr-x. 13 root root 155 Nov 13 2020 usr
    25. drwxr-xr-x. 18 root root 238 Nov 13 2020 var

实战: Tomcat 镜像

  1. 准备镜像文件 tomcat 压缩包, jdk 的压缩包

image.png

  1. 编写docker 文件
  • 命名: 最好使用Dockerfile, 这样在build 时不需要添加-f 参数, docker 会自动寻找Dockerfile 文件 ```shell FROM centos:7 MAINTAINER flmfuliming018@icloud.com

COPY readme.txt /usr/local/readme.txt

ADD jdk-8u321-linux-x64.tar.gz /usr/local/ ADD apache-tomcat-9.0.58.tar.gz /usr/local/

RUN yum -y install vim

ENV MYPATH /usr/local WORKDIR $MYPATH

ENV JAVA_HOME /usr/local/jdk1.8.0_321 ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.58 ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.58 ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin

EXPOSE 8080

CMD /usr/local/apache-tomcat-9.0.58/bin/startup.sh && tail -f /usr/local/apache-tomcat-9.0.58/logs/catalina.out

  1. 3. 生成镜像
  2. ```shell
  3. docker build -t diytomcat .

看到以下提示说明生成镜像成功
image.png

  1. 启动容器

    1. #这里的挂载了两个数据卷, 目录映射关系如下所示:
    2. # 外部 -> 内部
    3. #1. /home/flm/build/tomcat/test -> /usr/local/apache-tomcat-9.0.58/webapps/test
    4. #2. /home/flm/build/tomcat/logs -> /usr/local/apache-tomcat-9.0.58/webapps/logs
    5. docker run -p 9090:8080 --name flmtomcat01 -v /home/flm/build/tomcat/test:/usr/local/apache-tomcat-9.0.58/webapps/test -v /home/flm/build/tomcat/logs:/usr/local/apache-tomcat-9.0.58/webapps/logs diytomcat
  2. 访问测试

    1. curl docker 服务器IP:9090
  3. 发布项目 (由于做了卷挂载, 可以直接在本地编写项目就可以发布)

  • 编辑web.xml, 并放在/home/flm/build/tomcat/test/WEB-INF 目录下

    1. <web-app xmlns="http://java.sun.com/xml/ns/javaee"
    2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    3. xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    4. version="3.0"
    5. metadata-complete="true">
    6. </web-app>
  • 编辑index.jsp, 并放在/home/flm/build/tomcat/test 目录下

    <html>
      <head>
             <title>第一个 JSP 程序</title>
      </head>
      <body>
             <%
                    out.println("Hello World!");
             %>
      </body>
    </html>
    
  1. 访问测试: docker 服务器IP:9090/test

image.png
日志同步如下:
image.png

  • 注: 访问之前先指定setenfore 0, 不然从容器中无法打开宿主机的index.jsp 文件, 就会导致tomcat 报403 错误, 这是因为docker 的启动参数中带了selinux=enable 的原因, 具体的解释参照: https://www.cnblogs.com/elnino/p/10845449.html

大致的意思是根据selinux label 不同, 从容器访问到的宿主机资源也不同

发布自己的镜像

发布到docker hub

  1. 注册Docker hub 的帐号
  2. 在Docker hub 上提交自己的镜像 ```shell

    登录docker, 使用login 命令, 使用方法如下:

    docker login —help

Usage: docker login [OPTIONS] [SERVER]

Log in to a Docker registry

Options: —help Print usage -p, —password string Password -u, —username string Username

![image.png](https://cdn.nlark.com/yuque/0/2022/png/2516625/1643713907051-8b8e657d-e53a-4387-a5ab-96b80d36afa6.png#clientId=u770371b4-4dd1-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=55&id=u1b03de59&margin=%5Bobject%20Object%5D&name=image.png&originHeight=97&originWidth=846&originalType=binary&ratio=1&rotation=0&showTitle=false&size=9075&status=done&style=none&taskId=u3bbbd4d7-d161-4515-9196-0c77fe4b73d&title=&width=483.42857142857144)

3. 登录完毕后, 使用docker push 命令提交镜像
```shell
#命令模版
docker push 账号名/镜像名:版本号

#命令实例
docker push flm/diytomcat:1.0

image.png
注: 因为虚拟机的关系, 无法连接到docker hub, 导致push 失败

发布到阿里云镜像服务

  1. 登录阿里云
  2. 找到容器镜像服务
  3. 创建命名空间 -> 创建镜像仓管 -> 选择本地仓库

image.png

  1. 浏览仓库, 查看push 步骤

image.png

总结

image.png