Brc's blog
首页
前端
后端
运维
  • 工作笔记
  • 分类
  • 标签
  • 归档
关于

Brc

努力中
首页
前端
后端
运维
  • 工作笔记
  • 分类
  • 标签
  • 归档
关于
  • Linux基础

  • Linux进阶

    • shell

    • nginx

    • keepalived

    • LVS

    • ansible

    • docker

      • docker
      • docker入门
      • Dockerfile
        • Dockerfile简介
          • 简单实践
        • 构建指令
          • 基础指令
          • 其他指令
        • 构建解析
          • 构建过程
          • 构建历史
          • 镜像原理
          • 构建缓存
          • 使用原则
        • 基础镜像构建
          • ssh基础镜像
          • java镜像
        • 应用镜像构建
          • tomcat镜像
          • 应用镜像
    • mysql

  • 其他

  • 运维
  • Linux进阶
  • docker
Brc
2022-04-06
目录

Dockerfile

# Dockerfile简介

Dockerfile是将我们的docker镜像,使用自动化的方式实现出来。

注意:Dockerfile在使用的时候,首字母必须大写。

主要内容

基础镜像信息			从哪来?
维护者信息			 我是谁?
镜像操作指令			怎么干?
容器启动时执行指令      嗨! ! !
1
2
3
4

命令语法

构建镜像命令格式:
docker build -t [镜像名]:[版本号] [Dockerfile所在目录]

构建样例:
docker build -t nginx:v0.2 /opt/dockerfile/nginx/

参数详解:
	-t 指定构建后的镜像信息,默认是以构建后的docker image的id号为镜像名称
	/opt/dockerfile/nginx/代表Dockerfile存放位置,如果是当前目录,则用﹒(点)表示
1
2
3
4
5
6
7
8
9

# 简单实践

准备工作

# 创建Dockerfile专用目录
root@docker:~# mkdir /data/docker/base/ -p
root@docker:~# cd /data/docker/base/

# 准备文件
root@docker:/data/docker/base# cp ~/.pip/pip.conf ./
root@docker:/data/docker/base# ls
pip.conf
1
2
3
4
5
6
7
8

定制Dockerfile

root@docker:/data/docker/base# cat Dockerfile
# 构建一个基于python3的定制镜像
# 基础镜像
FROM ubuntu

# 作者信息
MAINTAINER bi

# 执行操作
RUN apt-get update
RUN apt-get install python3 -y && apt-get install python3-pip -y
WORKDIR /root/.pip/
ADD ./pip.conf ./pip.conf
WORKDIR /

# 入口指令
ENTRYPOINT ["/bin/bash"]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

构建镜像

# 构建镜像
root@docker:/data/docker/base# docker build -t python3:v0.1 .

# 使用新镜像启动一个容器,查看效果
root@docker:/data/docker/base# docker run -itd --name python python3:v0.1

# 容器检查
root@docker:/data/docker/base# docker ps
1
2
3
4
5
6
7
8

# 构建指令

# 基础指令

FROM

语法:
	FROM <image>
	FROM <image>:<tag>
解释:
	FROM是Dockerfile里的第一条而且只能是除了首行注释之外的第一条指令
1
2
3
4
5

MAINTAINER

语法:
	MAINTAINER <name>
解释:
	指定该dockerfile文件的维护者信息。
	类似在docker commit时候使用-a参数指定的信息
1
2
3
4
5

RUN

语法:
	RUN <command>									(shell模式)
	RUN ["executable","paraml","param2"]			(exec模式)
解释:
	表示当前镜像构建时候运行的命令
1
2
3
4
5

执行模式∶

模式 格式 示例
shell模式 类似于/bin/bash -c command RUN echo hello
exec模式 类似于RUN["/bin/bash", "-c", "command"] RUN ["echo", "hello"]

EXPOSE

语法:
	EXPOSE <port> [<port>...]
解释:
	设置Docker容器对外暴露的端口号,Docker为了安全,不会自动对外打开端口,如果需要外部提供访问,还需要启动容器时增加-p或者-P参数对容器的端口进行分配。
1
2
3
4

ENTRYPOINT

语法:
	ENTRYPOINT ["executable","paraml","param2"]				(exec模式)
	ENTRYPOINT command paraml param2						(shell模式)
解释:
	每个Dockerfile中只能有一个ENTRYPOINT,当指定多个时,只有最后一个起效。
1
2
3
4
5

# 其他指令

ADD

语法:
	ADD <src>... <dest>
	ADD ["<src>" ,... "<dest>"]
解释:
	将指定的文件复制到容器文件系统中的
	src指的是宿主机,dest指的是容器
	如果源文件是个压缩文件,则docker会自动帮解压到指定的容器中(无论目标是文件还是目录,都会当成目录处理)。
1
2
3
4
5
6
7

COPY

语法:
	COPY <src>... <dest>
	COPY ["<src>" ,... "<dest>"]
解释:
	单纯复制文件场景,Docker推荐使用COPY
1
2
3
4
5

VOLUME

语法:
	VOLUME ["/data"]
解释:
	VOLUME指令可以在镜像中创建挂载点,这样只要通过该镜像创建的容器都有了挂载点
	通过VOLUME指令创建的挂载点,无法指定主机上对应的目录,是自动生成的。
1
2
3
4
5

ENV

语法:
	ENV <key> <value>
	ENV <key>=<value> ...
解释:
	设置环境变量,可以在RUN之前使用,然后RUN命令时调用,容器启动时这些环境变量都会被指定。
1
2
3
4
5

WORKDIR

语法:
	WORKDIR /path/to/workdir		(shell模式)
解释:
	切换目录,为后续的RUN、CMD、ENTRYPOINT指令配置工作目录。相当于cd
1
2
3
4

# 构建解析

# 构建过程

  1. 从基础镜像1创建一个容器A
  2. 遇到一条Dockerfile指令,都对容器A做一次修改操作
  3. 执行完一条指令,提交生成一个新镜像2
  4. 再基于新的镜像2运行一个容器B
  5. 遇到一条Dockerfile指令,都对容器B做一次修改操作
  6. 执行完一条指令,提交生成一个新镜像3
  7. ...

# 构建历史

  • 构建过程中,创建了很多镜像,这些中间镜像,我们可以直接使用来启动容器,通过查看容器效果,从侧面能看到我们每次构建的效果。
  • 提供了镜像调试的能力
  • 我们可以通过docker history <镜像名>来查看整个构建过程所产生的镜像

# 镜像原理

image-20220406202330024

对于Docker镜像文件整体来说,它是一个只读的文件,但是根据我们对构建过程的理解,我们发现,对于Docker镜像还有很多更深层的东西:

  • 镜像文件是基于分层机制实现的
    • 最底层是bootfs用于启动容器之前系统引导的文件系统,容器启动完毕后,卸载该部分内容以 便节省资源
    • 其他层是rootfs,有内核挂载为只读模式,而后通过"联合挂载"在其基础上挂载一个"可写层"
  • 下层镜像是上层镜像的父镜像,最底层的称为基础镜像
    • 最上层的是可写的,其他各层都是只读的

# 构建缓存

第一次构建很慢,之后的构建都会很快,因为它们用到了构建的镜像缓存。

不使用构建缓存方法:

全部不用缓存:
	docker build --no-cache -t [镜像名]:[镜像版本] [Dockerfile位置]
部分不用缓存:
	更改Dockerfile的部分代码即可
1
2
3
4

# 使用原则

在工作中,经常会因为业务需求,而定制各种各样的Doker镜像,由于Dockerfile的便捷性,所以经常会基于Dockerfile来创建我们业务场景中所需要的各种镜像。

根据我自己的工作经验,在使用Dockerfile的过程中,一般只需要关注三个方面即可:

  1. Dockerfile在使用的过程中,构建的指令越少越好,能合并的就合并。
  2. 基于Docker镜像的分层特性,我们最好按照项目的架构级别来定制不同层的镜像
  3. Dockerfiel构建的过程中,功能越简单越好,最好只有一个

# 基础镜像构建

# ssh基础镜像

定制一个标准的ssh基础镜像,用于我们远程连接或者进行其他的应用镜像的基础镜像

简单实践

# 创建Dockerfile专用目录
root@docker:~# mkdir /docker/images/ssh -p
root@docker:~# cd /docker/images/ssh

# 创建秘钥认证
root@docker:/docker/images/ssh# ssh-keygen -t rsa
root@docker:/docker/images/ssh# cat ~/.ssh/id_rsa.pub > authorized_keys

# 定制Dockerfile
root@docker:/docker/images/ssh# cat Dockerfile
#构建一个基于ubuntu的ssh定制镜像
#基础镜像
FROM ubuntu
#镜像作者
MAINTAINER bi

#安装ssh服务
RUN apt-get update && apt-get install -y openssh-server curl vim net-tools && mkdir -p /var/run/sshd && mkdir -p /root/.ssh && sed -i "s/.*pam_loginuid.so/#&/" /etc/pam.d/sshd && apt-get autoclean && apt-get clean && apt-get autoremove

#复制配置文件到相应位置,并赋予脚本可执行权限
ADD authorized_keys /root/.ssh/authorized_keys

#对外端口
EXPOSE 22

# 启动ssh
CMD ["/usr/sbin/sshd" , "-D"]
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

测试效果

# 构建镜像
root@docker:/docker/images/ssh# docker build -t ubuntu-ssh .

# 使用新镜像启动一个容器,查看效果
root@docker:/docker/images/ssh# docker run -d -p 10086:22 ubuntu-ssh

# 容器检查
root@docker:/docker/images/ssh# docker ps
root@docker:/docker/images/ssh# docker port ed90eebaa81c

# ssh查看效果
root@docker:/docker/images/ssh# ssh 10.0.0.21 -p 10086
1
2
3
4
5
6
7
8
9
10
11
12

# java镜像

定制标准的java环境,以便于基于java环境的业务环境使用

简单实践

# 创建Dockerfile专用目录
root@docker:~# mkdir /docker/images/java -p
root@docker:~# cd /docker/images/java

# 定制Dockerfile
root@docker:/docker/images/java# cat Dockerfile
# 构建一个基于ubuntu-ssh定制java镜像
# 基础镜像
FROM ubuntu-ssh
# 镜像作者
MAINTAINER bi

# 添加文件到容器
ADD jdk-8u121-linux-x64.tar.gz /data/server/
RUN ln -s /data/server/jdk1.8.0_121 /data/server/java

# 定制环境变量
ENV JAVA_HOME /data/server/java
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/:$JRE_HOME/lib/
ENV PATH $PATH:$JAVA_HOME/bin
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

测试效果

# 构建镜像
root@docker:/docker/images/java# docker build -t ubuntu-jdk:8u121 .

# 使用新镜像启动一个容器,查看效果
root@docker:/docker/images/java# docker run -it --rm ubuntu-jdk:8u121 bash

# 在容器内检查
root@6b30a3b762fd:/# java -version
root@6b30a3b762fd:/# echo $JAVA_HOME
1
2
3
4
5
6
7
8
9

# 应用镜像构建

# tomcat镜像

基于java环境镜像定制tomcat镜像

简单实践

# 创建Dockerfile专用目录
root@docker:~# mkdir /docker/images/tomcat -p
root@docker:~# cd /docker/images/tomcat

# 获取应用文件
root@docker:/docker/images/tomcat# wget https://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-10/v10.0.20/bin/apache-tomcat-10.0.20.tar.gz

# 定制Dockerfile
root@docker:/docker/images/tomcat# cat Dockerfile
# 构建一个基于ubuntu-jdk定制tomcat镜像
# 基础镜像
FROM ubuntu-jdk:8u121
# 镜像作者
MAINTAINER bi

# 定制环境变量
ENV TZ "Asia/Shanghai"
ENV LANG en_US.UTF-8
ENV TERM xterm
ENV TOMCAT_MAJOR_VERSION 10
ENV TOMCAT_MINOR_VERSION 10.0.20
ENV CATALINA_HOME /apps/tomcat
ENV APP_DIR ${CATALINA_HOME}/webapps

# 添加文件到容器
ADD apache-tomcat-10.0.20.tar.gz /apps
RUN ln -s /apps/apache-tomcat-10.0.20 /apps/tomcat

# 定制容器的启动命令
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

测试效果

# 构建镜像
root@docker:/docker/images/tomcat# docker build -t ubuntu-tomcat:v10.0.20 .

# 使用新镜像启动一个容器,查看效果
docker run -it --rm -p 8080:8080 ubuntu-tomcat:v10.0.20 bash
注意:
	因为在构建镜像的时候,已经启动了命令bash,所以可以直接进入进去

# 容器检查
root@a23396901623:/# /apps/tomcat/bin/catalina.sh start
root@a23396901623:/# netstat -tnulp
1
2
3
4
5
6
7
8
9
10
11

# 应用镜像

基于基础的tomcat镜像,运行两个专用的tomcat项目

简单实践

# 创建Dockerfile专用目录
root@docker:~# mkdir /docker/web/tomcat/tomcat-app{1,2} -p
root@docker:~# cd /docker/web/tomcat

# 定制tomcat-app1
root@docker:/docker/web/tomcat# cd /docker/images/tomcat/
root@docker:/docker/images/tomcat# tar xf apache-tomcat-10.0.20.tar.gz
root@docker:/docker/images/tomcat# cp apache-tomcat-10.0.20/conf/server.xml /docker/web/tomcat/tomcat-app1

# 修改 tomcat-app1/server.xml 配置文件
root@docker:/docker/images/tomcat# cd /docker/web/tomcat/tomcat-app1
#   开放8009端口
    <Connector protocol="AJP/1.3"
               address="::1"
               port="8009"
               redirectPort="8443" />
#   定制应用目录
    <Host name="localhost"  appBase="/data/server/tomcat/webapps"
            unpackWARs="true" autoDeploy="true">

# 定制tomcat-app1的应用首页
root@docker:/docker/web/tomcat/tomcat-app1# mkdir ROOT
root@docker:/docker/web/tomcat/tomcat-app1# echo "welcome to Tomcat-app1" > ROOT/index.jsp
root@docker:/docker/web/tomcat/tomcat-app1# tar zcf ROOT.tar.gz ROOT

# 定制tomcat服务启动脚本
root@docker:/docker/web/tomcat/tomcat-app1# cat tomcat_service.sh
# !/bin/bash
# 定制容器里面的tomcat服务启动脚本

# 定制dns解析文件
echo "nameserver 10.0.0.2"> /etc/resolv.conf

# 定制服务启动命令
/apps/tomcat/bin/catalina.sh start

# 定制信息的输出
tail -f /etc/hosts

# 定制Dockerfile
root@docker:/docker/web/tomcat/tomcat-app1# cat Dockerfile
# 构建一个基于ubuntu-tomcat定制tomcat app镜像
# 基础镜像
FROM ubuntu-tomcat:v10.0.20
# 镜像作者
MAINTAINER bi

# 增加相关文件
ADD server.xml /apps/tomcat/conf/server.xml
ADD tomcat_service.sh /apps/tomcat/bin/tomcat_service.sh
ADD ROOT.tar.gz /data/server/tomcat/webapps/

# 开放tomcat服务端口
EXPOSE 8080 8009

# 定制容器的启动命令
CMD ["/bin/bash","/apps/tomcat/bin/tomcat_service.sh"]
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

测试效果

# 构建镜像
root@docker:/docker/web/tomcat/tomcat-app1# docker build -t tomcat-web:app1 .

# 使用新镜像启动一个容器,查看效果
root@docker:/docker/web/tomcat/tomcat-app1# docker run -d -p 8080:8080 tomcat-web:app1

# 容器检查
root@docker:/docker/web/tomcat/tomcat-app1# docker port 5e72ea0547f8
root@docker:/docker/web/tomcat/tomcat-app1# curl 127.0.0.1:8080
welcome to Tomcat-app1
1
2
3
4
5
6
7
8
9
10

同样的方式定制第二个tomcat web镜像

# 准备文件
root@docker:/docker/web/tomcat/tomcat-app1# cd /docker/web/tomcat
root@docker:/docker/web/tomcat# cp -a tomcat-app1/* tomcat-app2/
root@docker:/docker/web/tomcat# cd tomcat-app2/
root@docker:/docker/web/tomcat/tomcat-app2# sed -i 's#app1#app2#' ROOT/index.jsp
root@docker:/docker/web/tomcat/tomcat-app2# rm -rf ROOT.tar.gz
root@docker:/docker/web/tomcat/tomcat-app2# tar zcf ROOT.tar.gz ROOT

# 构建镜像
root@docker:/docker/web/tomcat/tomcat-app2# docker build -t tomcat-web:app2 .

# 测试效果
root@docker:/docker/web/tomcat/tomcat-app2# docker run -d -p 8081:8080 tomcat-web:app2
root@docker:/docker/web/tomcat/tomcat-app2# curl 127.0.0.1:8081
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#docker#Dockerfile
Last Updated: 2022/04/06, 22:48:37
docker入门
mysql

← docker入门 mysql→

最近更新
01
谷歌云创建GKE集群
07-26
02
ElastiCacheForRedis启用密码
07-26
03
upload-to-gcs
06-29
更多文章>
Theme by Vdoing | Copyright © 2021-2024 Brc | MIT License | 浙ICP备19031881号-4
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式