从01开始 从01开始
首页
  • 计算机科学导论
  • 数字电路
  • 计算机组成原理

    • 计算机组成原理-北大网课
  • 操作系统
  • Linux
  • Docker
  • 计算机网络
  • 计算机常识
  • Git
  • JavaSE
  • Java高级
  • JavaEE

    • Ant
    • Maven
    • Log4j
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • Servlet
  • Spring
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC
  • SpringBoot
  • 学习网课的心得
  • 输入法
  • 节假日TodoList
  • 其他
  • 关于本站
  • 网站日记
  • 友人帐
  • 如何搭建一个博客
GitHub (opens new window)

peterjxl

人生如逆旅,我亦是行人
首页
  • 计算机科学导论
  • 数字电路
  • 计算机组成原理

    • 计算机组成原理-北大网课
  • 操作系统
  • Linux
  • Docker
  • 计算机网络
  • 计算机常识
  • Git
  • JavaSE
  • Java高级
  • JavaEE

    • Ant
    • Maven
    • Log4j
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • Servlet
  • Spring
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC
  • SpringBoot
  • 学习网课的心得
  • 输入法
  • 节假日TodoList
  • 其他
  • 关于本站
  • 网站日记
  • 友人帐
  • 如何搭建一个博客
GitHub (opens new window)
  • 计算机历史

  • 数字电路

  • 计算机组成原理

  • 汇编语言

  • C语言

  • 数据结构

  • 操作系统

  • Linux

    • 文本处理三剑客

    • 尚硅谷Docker实战教程

      • 教程简介
      • Docker简介
      • Docker安装
      • Docker常用命令
      • 镜像的分层概念
      • 发布镜像
      • Docker私有库
      • 容器数据卷
      • Docker常用软件安装
      • MySQL主从复制
      • 分布式存储之哈希取余算法
      • 3主3从Redis集群搭建与扩缩容
      • Dockerfile
        • 概述
        • DockerFile常用保留字
        • 案例
        • 家庭作业
      • 虚悬镜像
      • Docker微服务实战
      • Docker网络
      • Docker-compose容器编排
      • Portainer
      • Docker重量级监控
      • 完结
      • Docker
    • Linux安全

    • Linux文章集合
  • 计算机网络

  • Git

  • 数据库

  • 计算机小知识

  • 编译原理

  • 名人堂

  • 计算机基础
  • Linux
  • 尚硅谷Docker实战教程
2023-09-18
目录

Dockerfile

# 120.Dockerfile

Dockerfile非常重要,在实际工作中,使用Docker绝不是敲敲一些常用命令即可。Dockerfile几乎贯穿微服务的全部内容,务必掌握

不要求能从头开始编写Dockerfile,至少如果有个Dockerfile的模板,我们能够修改。   ‍

# 概述

Dockerfile是用来构建Docker镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本(类似Linux的shell脚本)。

之前我们给Ubuntu镜像安装了vim和ifconfig功能,然后通过docker commit 功能,形成了一个新的镜像,这是一个加强版的镜像;

在简单的情况下,这样做是可以的;但后期我们会构建微服务镜像,有很多很多的配置,每次都commit的话,就很麻烦了;就好比执行SQL语句,每执行一条就要commit一次,不方便。

Dockerfile 可以一次性搞定,想要装什么功能,只需提供一个清单即可。

​

示意图:通过 Dockerfile 一次性完成镜像的构建

​​

​官网文档:Dockerfile reference | Docker Docs (opens new window)

构建三步骤

  • 编写Dockerfile文件
  • docker build命令构建镜像
  • docker run 运行容器实例

‍

‍

Dockerfile内容基础知识:

  1. 每条保留字指令都必须为大写字母且后面要跟随至少一个参数
  2. 指令按照从上到下,顺序执行
  3. ​#​ 表示注释
  4. 每条指令都会创建一个新的镜像层并对镜像进行提交

‍

保留字,就是一些关键字,在官网文档中有提到,后面我们会详细讲解:

​​

‍

‍

‍

Docker执行Dockerfile的大致流程

  1. docker从基础镜像运行一个容器
  2. 执行一条指令并对容器作出修改
  3. 执行类似docker commit的操作提交一个新的镜像层
  4. docker再基于刚提交的镜像运行一个新容器
  5. 执行dockerfile中的下一条指令直到所有指令都执行完成

‍

从应用软件的角度来看,Dockerfile、Docker镜像与Docker容器分别代表软件的三个不同阶段:

  • Dockerfile是软件的原材料

  • Docker镜像是软件的交付品

  • Docker容器则可以认为是软件镜像的运行态,也即依照镜像运行的容器实例

Dockerfile面向开发,Docker镜像成为交付标准,Docker容器则涉及部署与运维,三者缺一不可,合力充当Docker体系的基石。

​​

  • Dockerfile 定义了进程需要的一切东西。Dockerfile涉及的内容包括执行代码或者是文件、环境变量、依赖包、运行时环境、动态链接库、操作系统的发行版、服务进程和内核进程(当应用进程需要和系统服务和内核进程打交道,这时需要考虑如何设计namespace的权限控制)等等
  • Docker镜像,在用Dockerfile定义一个文件之后,docker build时会产生一个Docker镜像,当运行 Docker镜像时会真正开始提供服务
  • Docker容器,容器是直接提供服务的。

‍

# DockerFile常用保留字

我们之前使用的镜像,很多也是用Dockerfile的,例如Tomcat。我们以Tomcat的Dockerfile为例,简单介绍下常用的保留字。

可以在GitHub (opens new window)上看到其Dockerfile:里面有很多的关键字,在最后会有run,然后会expose一个端口8080,然后执行命令(Tomcat的启动命令,catalina.sh)

FROM amazoncorretto:8-al2-jdk

ENV CATALINA_HOME /usr/local/tomcat
ENV PATH $CATALINA_HOME/bin:$PATH
RUN mkdir -p "$CATALINA_HOME"
WORKDIR $CATALINA_HOME


..........



# verify Tomcat Native is working properly
RUN set -eux; \
	nativeLines="$(catalina.sh configtest 2>&1)"; \
	nativeLines="$(echo "$nativeLines" | grep 'Apache Tomcat Native')"; \
	nativeLines="$(echo "$nativeLines" | sort -u)"; \
	if ! echo "$nativeLines" | grep -E 'INFO: Loaded( APR based)? Apache Tomcat Native library' >&2; then \
		echo >&2 "$nativeLines"; \
		exit 1; \
	fi

EXPOSE 8080
CMD ["catalina.sh", "run"]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

‍

该文件可能很多行,不过不用担心,去掉注释后就没剩下多少了;而且也不要求从头开始编写,看得懂、能依样画葫芦即可。

‍

‍

# from

指明基础镜像,当前新镜像是基于哪个镜像的(例如可以基于Ubuntu),指定一个已经存在的镜像作为模板,第一条必须是from。

‍

‍

# MAINTAINER

镜像维护者的姓名和邮箱地址

‍

‍

# RUN

容器构建时(docker build时)需要运行的命令。两种格式:

  • shell 模式。​RUN <命令行命令>​ ,等同于在终端执行shell命令,例如 RUN yum -y install vim​
  • exec 模式。稍微有点复杂,RUN ["可执行文件", "参数1", "参数2"]​,例如 RUN ["./test.php", "dev", "offline"] ​​等价于RUN ./test.php", "dev", "offline"​

‍

# EXPOSE

当前容器对外暴露出的端口(还记得运行容器时,可以指定端口映射的选项 -p么)

‍

# USER

指定该镜像以什么样的用户去执行,如果不指定,默认是root

‍

# WORKDIR

指定在创建容器后,终端默认登陆的进来工作目录。

‍

‍

比如我们进入Tomcat时,默认是去到了/usr/local/tomcat​目录:

$ docker run -d -p 8080:8080 --name t1 tomcat

$ docker exec -it t1 bash

$ pwd
/usr/local/tomcat
1
2
3
4
5
6

‍

Dockerfile也是这样配的:

ENV CATALINA_HOME /usr/local/tomcat
WORKDIR $CATALINA_HOME
1
2

‍

‍

# ENV

用来在构建镜像过程中设置环境变量

ENV MY_PATH /usr/mytest
1

这个环境变量可以在后续的任何RUN指令中使用,这就如同在命令前面指定了环境变量前缀一样;

‍

也可以在其它指令中直接使用这些环境变量,比如:

WORKDIR $MY_PATH
1

‍

‍

# VOLUME

配置容器数据卷,用于数据保存和持久化工作

‍

‍

# ADD

可以将宿主机目录下指定的文件拷贝进镜像,且会自动处理URL和解压tar压缩包

例如要在镜像内装个Java8,并且是通过解压安装的方式,就可以用该命令。

‍

# COPY

类似ADD,拷贝文件和目录到镜像中。 将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 <目标路径> 位置。命令格式:

  • ​COPY src dest​
  • ​COPY ["src", "dest"]​

​<src源路径>​:源文件或者源目录

​<dest目标路径>​:容器内的指定路径, 路径不存在的话,会自动创建。

‍

‍

‍

# CMD

指定容器启动后的要干的事情。CMD 指令的格式和 RUN 类似,格式:

  • shell 模式:CMD <命令>​
  • exec 模式:CMD ["可执行文件", "参数1", "参数2"]​
  • 参数列表模式:CMD ["参数1", "参数2"...]​。如果指定了 ENTRYPOINT 指令,那么 CMD 就只用来传参了(后面再说)

‍

例如,Tomcat最后启动的命令:

CMD ["catalina.sh", "run"]
1

Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效。

‍

‍

CMD 会被 docker run 之后的参数替换。例如我们启动一个Tomcat,带上bash操作:

docker run -it -p 8080:8080 --name t1 tomcat bash
1

‍

‍

那么Tomcat就不会启动了,因为CMD命令替换了:

​​​​

‍

‍

‍

CMD 和RUN命令的区别:

  • CMD是在docker run 时运行
  • RUN是在 docker build时运行

‍

‍

# ENTRYPOINT

也是用来指定一个容器启动时要运行的命令。类似于 CMD 指令,但是 ENTRYPOINT 不会被docker run后面的命令覆盖, 而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序

命令格式:

ENTRYPOINT ["<executeable>", "<param1>", "<param2>", ...]
1

ENTRYPOINT可以和CMD一起用,一般是变参才会使用 CMD ,这里的 CMD 等于是在给 ENTRYPOINT 传参。

当指定了ENTRYPOINT后,CMD的含义就发生了变化,不再是直接运行其命令而是将CMD的内容作为参数传递给ENTRYPOINT指令,他两个组合会变成 <ENTRYPOINT> "<CMD>"​

‍

案例如下:假设已通过 Dockerfile 构建了 nginx:test 镜像:

FROM nginx;

ENTRYPOINT ["nginx", "-c"] # 定参
CMD ["/etc/nginx/nginx.conf"] # 变参
1
2
3
4

‍

是否传参 按照dockerfile编写执行 传参运行
Docker命令 docker run nginx:test docker run nginx:test -c /etc/nginx/new.conf
衍生出的实际命令 nginx -c /etc/nginx/nginx.conf nginx -c /etc/nginx/new.conf

如果传参运行,相当于用自己传入的配置,覆盖Dockerfile中的默认配置。

‍

优点:在执行docker run的时候可以指定 ENTRYPOINT 运行所需的参数。

注意:如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。

‍

‍

# 小结

BUILD Both RUN
FROM WORKDIR CMD
MAINTAINER USER ENV
COPY EXPOSE
ADD VOLUME
RUN ENTRYPOINT
ONBUILD
.dockerignore

‍

​​

# 案例

讲了下常用保留字,可能有点不好理解,我们用实际例子来说明。

我们自定义一个镜像:mycentosjava8。要求在Centos7镜像基础上,安装vim+ifconfig+jdk8

‍

先下载Centos镜像:

 docker pull centos:7
1

如果是Centos8等镜像,可能会要额外设置一些yum,这里不展开,建议用Centos7,我们课程目的是学Docker。

‍

‍

‍

然后我们下载Java 8:Java Downloads | Oracle (opens new window),这里我们选择x64 Compressed Archive的版本(下载Java最新版的,这里是8u381,后期可能有更新,没关系用最新版的即可)

​​

‍

‍

接下来准备编写Dockerfile文件(注意Dockerfile文件,首字母得是大写的D):

$ mkdir /myfile

$ cd  /myfile

$ touch Dockerfile

$ pwd
/myfile


$  ll
总用量 136012
-rw-r--r-- 1 root root         0 9月   9 21:00 Dockerfile
-rwxr-x--- 1 root root 139273048 9月   9 21:00 jdk-8u381-linux-x64.tar.gz
1
2
3
4
5
6
7
8
9
10
11
12
13
14

请自行将下载好的Java安装包挪到该目录

‍

然后在Dockerfile文件里粘贴如下内容:

FROM centos:7
MAINTAINER peterjxl<peterjxl@qq.com>
 
ENV MYPATH /usr/local
WORKDIR $MYPATH
 
#安装vim编辑器
RUN yum -y install vim


#安装ifconfig命令
RUN yum -y install net-tools


#安装java8及lib库
RUN yum -y install glibc.i686
RUN mkdir /usr/local/java


#ADD 是相对路径jar,把jdk-8u171-linux-x64.tar.gz添加到容器中,安装包必须要和Dockerfile文件在同一位置
ADD jdk-8u381-linux-x64.tar.gz /usr/local/java/


#配置java环境变量
ENV JAVA_HOME /usr/local/java/jdk1.8.0_381
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH
ENV PATH $JAVA_HOME/bin:$PATH
 
EXPOSE 80
 
CMD echo $MYPATH
CMD echo "success--------------ok"
CMD /bin/bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

‍

该Dockerfile里的内容,都是之前讲过的,稍微看看应该都能看懂。如果下载的Java版本比较新,注意修改第21行处的对应文件名,此外解压太Java压缩包后,目录名也要修改(第25行)

接下来我们构建该镜像,命令格式:docker build -t 新镜像名字:TAG .​

选项 -t 是什么意思呢?查看下帮助,就是构建时要带的一个选项:

$ docker build --help
............
  -t, --tag stringArray               Name and optionally a tag (format: "name:tag")
      --target string                 Set the target build stage to build
      --ulimit ulimit                 Ulimit options (default [])
1
2
3
4
5

‍

接下来我们开始构建,执行如下命令:

docker build -t centosjava8:1.5 .
1

‍

安装完后,我们可以检查下镜像,可以看到我们自己的镜像大了不少,有1.24G:

$ docker images centos*
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
centosjava8   1.5       9263eda71f21   2 minutes ago   1.24GB
centos        7         eeb6ee3f44bd   24 months ago   204MB
1
2
3
4

‍

‍

接下来我们运行下该镜像,命令格式:docker run -it 新镜像名字:TAG​

docker run -it centosjava8:1.5
1

‍

接下来测试下,首先是登录后的位置:

# pwd
/usr/local
1
2

‍

vim命令:

$ vim -version
VIM - Vi IMproved 7.4 (2013 Aug 10, compiled Dec 15 2020 16:44:08)
Garbage after option argument: "-version"
More info with: "vim -h"
1
2
3
4

‍

ifconfig命令:

$ 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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

‍

‍

Java版本:

$ java -version
java version "1.8.0_381"
Java(TM) SE Runtime Environment (build 1.8.0_381-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.381-b09, mixed mode)
1
2
3
4

‍

‍

# 家庭作业

在Ubuntu镜像基础上,安装vim,ifconfig和Java8

‍

(完)

在GitHub上编辑此页 (opens new window)
上次更新: 2023/9/18 12:28:56
3主3从Redis集群搭建与扩缩容
虚悬镜像

← 3主3从Redis集群搭建与扩缩容 虚悬镜像→

Theme by Vdoing | Copyright © 2022-2023 粤ICP备2022067627号-1 粤公网安备 44011302003646号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式