Docker-高级篇(1)-Dockerfile(核心&构建Redis&构建JDK8)
文章目录一、基本介绍二、体系结构2.1 Docker保留字2.2 案例解释当前目录下标准文件名可以不指定路径三、构建Redis四、构建java8一、基本介绍Dockerfile用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本构建的三个步骤编写Dockerfiledocker build -f-t [:tag] .-f :指定Dockerfile位置,如果文件在当前目录
·
一、基本介绍
- Dockerfile用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本
- 构建的三个步骤
- 编写Dockerfile
- docker build -f -t [:tag] .
- -f :指定Dockerfile位置,如果文件在当前目录且名字叫 Dockerfile 则不用指定
- docker build之后将会生成一个新镜像
- docker run <新镜像id>
- Dockerfile在官网镜像中都有对应的DockerFile可以参考
- Dockerfile基础知识
- 每条保留字指令都必须大写且后面至少有一个参数,使用空格分隔
- 指令按照从上到下,依次顺序执行
- # 表示注释
- 每条指令都会创建一个新的镜像层,并对镜像进行提交
- Docker执行Dockerfile的大致流程
- docker从基础镜像运行一个容器
- 执行一条指令并对容器做出更改
- 执行类似Docker commit的操作提交一个新的镜像层
- docker再基于刚提交的镜像运行一个新容器
- 执行dockerf中的下一条指令直到所有指令都执行完成
- 从应用软件的角度来看,Dockerfile、Docker镜像与Docker容器分别代表软件的三个不同阶段
- Dockerfile是软件的原材料
- Docker镜像是软件的交付品
- Docker容器则可以认为是软件的运行态
- Dockerfile面向开发,Docker镜像称为交付标准,Docker容器则设计部署与运维,三者缺一不可
Dockerfile
- 需要定义一个Dockerfile,Dockerfile定义了进程需要的一切东西
- Dockerfile涉及的内容包括执行代码或者是文件、环境变量、依赖包、运行时环境、动态链接库、操作系统的发行版、服务进程和内核进程(当应用进程需要和系统服务和内核进程打交道,这时需要考虑如何设计namespace的权限控制)等等
Docker镜像
- 在用Dockerfile定义一个文件之后,docker build时会产生一个Docker镜像,当运行Docker镜像时,会真正开始提供服务
Docker容器
- 容器直接提供服务,为最终提供服务的运行态
Docker整体结构图
二、体系结构
2.1 Docker保留字
- FROM
- 基础镜像,新镜像的基础镜像
- MAINTAINER
- 镜像维护者姓名和邮箱地址
- RUN
- 容器构建时需要运行的命令
- 两种格式
- shell格式:RUN yum -y install vim
- exec格式:RUN [“yum”, “-y”, “install”, “vim”]
- RUN是在 docker build时运行
- EXPOSE
- 当前镜像对外暴露的端口
- WORKDIR
- 指定创建容器后,终端默认登录进来的工作目录
- ENV
- 用来构建镜像过程中设置环境变量
- ENV MY_PATH /usr/mytest:这个环境变量可以在后续的任何RUN指令中使用,这就如同在命令前面指定了环境变量前缀一样
- WORKDIR $MY_PATH:指令中直接使用这些环境变量
- ADD
- 将宿主机目录下的文件拷贝到镜像且ADD会自动处理URL和解压缩tar包,相当于 COPY + 解压
- COPY
- 将宿主机目录下的文件拷贝到镜像
- 拷贝有以下两种方式
- COPY src dest
- COPY [“src”, “dest”]
- VOLUME
- 容器数据卷,用于数据保存和持久化工作
- CMD
- 指定一个容器启动时要运行的命令
- Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效
- CMD会被 docker run 之后的参数替换
- 指令格式:CMD 命令 | CMD [“可执行文件”,“参数1”, “参数n”]
- 参数列表:CMD [“参数1”,“参数n”],在指定ENTRYPOINT指令后,用CMD指定具体参数
- CMD是在docker run 时运行
- ENTRYPOINT
- 指定一个容器启动时要运行的命令
- 类似于 CMD 指令,但是ENTRYPOINT不会被docker run后面的命令覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序
- 多个ENTRYPOINT不会覆盖,而是追加
- 指令格式:ENTRYPOINT [“可执行文件”,“参数1”, “参数n”]
- ENTRYPOINT可以和CMD一起用,一般是变参才会使用 CMD ,这里的 CMD 等于是在给 ENTRYPOINT 传参
- 当指定了ENTRYPOINT后,CMD的含义就发生了变化,不再是直接运行其命令而是将CMD的内容作为参数传递给ENTRYPOINT指令,他两个组合会变:ENTRYPOINT CMD
- 优点:在执行docker run的时候可以指定 ENTRYPOINT 运行所需的参数
- 如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效
- ONBUILD
- 触发器,当构建一个被继承的Dockerfile时运行命令,父镜像在被子继承后父镜像的onbuild被触发
- USER
- 指定该镜像以什么样的用户去执行,如果都不指定,默认是root
2.2 案例解释
- scratch:相当于java中的Object,是镜像的基础镜像
- Docker Hub 中 99% 的镜像都是通过在 base 镜像中安装和配置需要的软件构建出来的
- 下载的centos只有200M左右,因为其很多指令被舍弃,只有精简内核
- 现在自定义 centos 镜像,具备以下功能
- 登陆后的默认路径载/opt下
- 支持vim编辑器
- 查看网络配置的ifconfig支持
- 编写Dockerfile
FROM centos:7
MAINTAINER tianxincoord@163.com
ENV WORK /opt
RUN yum -y install vim
CMD echo "vim编辑器安装完成"
RUN yum -y install net-tools
CMD echo "网络工具安装完成"
WORKDIR $WORK
CMD echo "工具目录设置完成"
EXPOSE 80
CMD /bin/bash
- 构建Dockerfile,生成镜像
......
# 构建成功消息
Successfully built a1467c43b30c
Successfully tagged tianxin/centos:1.0
# 构建成功后查看镜像
[root@localhost docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tianxin/centos 1.0 a1467c43b30c 9 seconds ago 515MB
redis latest aa4d65e670d6 2 weeks ago 105MB
mysql 5.7 8cf625070931 2 weeks ago 448MB
centos 7 8652b9f0cb4c 8 months ago 204MB
- 运行新镜像
- docker run -it --name tianxin-centos tianxin/centos:1.0
- 可以成功看到镜像当前工作目录为/opt,包含网络命令
[root@localhost docker]# docker run -it --name tianxin-centos tianxin/centos:1.0
[root@3e307a37f9ac opt]# pwd
/opt
[root@3e307a37f9ac opt]# 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
- 查看镜像历史
- docker history imagesID
[root@localhost redis]# docker history a1467c43b30c
IMAGE CREATED CREATED BY SIZE
a1467c43b30c 14 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "/bin… 0B
fac2dd7bdf3c 14 minutes ago /bin/sh -c #(nop) EXPOSE 80 0B
6ed0b3d96497 14 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "echo… 0B
6279934b0024 14 minutes ago /bin/sh -c #(nop) WORKDIR /opt 0B
ed95908c5c7b 14 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "echo… 0B
abd1744d570e 14 minutes ago /bin/sh -c yum -y install net-tools 128MB
4a7efc540d58 14 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "echo… 0B
d9ce990fb919 14 minutes ago /bin/sh -c yum -y install vim 183MB
42b4307fde4f 15 minutes ago /bin/sh -c #(nop) ENV WORK=/opt 0B
54a76e7e02be 15 minutes ago /bin/sh -c #(nop) MAINTAINER tianxincoord@1… 0B
8652b9f0cb4c 8 months ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
<missing> 8 months ago /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B
<missing> 8 months ago /bin/sh -c #(nop) ADD file:b3ebbe8bd304723d4… 204MB
三、构建Redis
- 工作目录:/root/workspace/redis
- 准备Dockerfile文件和redis安装包、已经关闭端口绑定的redis.conf配置文件
[root@localhost redis]# ll
total 2472
-rw-r--r--. 1 root root 0 Aug 7 07:50 Dockerfile
-rw-r--r--. 1 root root 2465302 Jul 21 18:51 redis-6.2.5.tar.gz
-rw-r--r--. 1 root root 62186 Aug 7 08:02 redis.conf
- 编写Dockerfle文件
# 设置基础信息
FROM centos:7
# 拷贝安装文件(先确保Dockerfile同级目录含有安装文件)
ADD redis-6.2.5.tar.gz /opt/
# 进入工作目录
WORKDIR /opt/redis-6.2.5/src/
# 安装redis所需依赖
RUN yum -y install gcc gcc-c++ tcl automake autoconf libtool make
# 编译和安装
RUN make
RUN make install
# 清除中间文件
RUN make distclean
# 切换工作目录
WORKDIR /opt/redis-6.2.5/
# 删除原始配置文件
RUN rm -f redis.conf
# 拷贝新redis文件
COPY redis.conf /opt/redis-6.2.5/
WORKDIR /opt/redis-6.2.5/src/
# 暴露端口
EXPOSE 6379
# 默认启动服务,可以启动容器时覆盖命令
CMD ["redis-server"]
- 构建DockerFile
docker build -t tianxin/redis .
- 构建完成后运行容器
docker run -d --name redis02 -p 6380:6379 tianxin/redis
四、构建java8
- 下载jdk8 linux版本,此处使用的版本为jdk-8u251-linux-x64.tar.gz
- 将jdk上传到/root/docker/jdk,选择任意路径均可
- 拉取centos:7镜像
docker pull centos:7
- 编写Dockerfile,和jdk-8u251-linux-x64.tar.gz在同一个文件夹下,内容如下
FROM centos:7
MAINTAINER tianxincoord@163.com
RUN mkdir /usr/local/jdk
WORKDIR /usr/local/jdk
ADD jdk-8u251-linux-x64.tar.gz /usr/local/jdk
ENV JAVA_HOME /usr/local/jdk/jdk1.8.0_251
ENV JRE_HOME /usr/local/jdk/jdk1.8.0_251/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
- 构建镜像
# docker build -t java:8 .
Sending build context to Docker daemon 195.1MB
Step 1/10 : FROM centos:7
---> eeb6ee3f44bd
Step 2/10 : MAINTAINER tianxincoord@163.com
---> Running in 045e51b633e2
Removing intermediate container 045e51b633e2
---> aaa06e3b387b
Step 3/10 : RUN mkdir /usr/local/jdk
---> Running in 138074b4eec0
Removing intermediate container 138074b4eec0
---> bf5cdee73362
Step 4/10 : WORKDIR /usr/local/jdk
---> Running in 251e26d7be7f
Removing intermediate container 251e26d7be7f
---> 3324c3cc346c
Step 5/10 : ADD jdk-8u251-linux-x64.tar.gz /usr/local/jdk
---> d82f82248fc6
Step 6/10 : ENV JAVA_HOME /usr/local/jdk/jdk1.8.0_251
---> Running in 81b46ea286be
Removing intermediate container 81b46ea286be
---> ba1f722dd501
Step 7/10 : ENV JRE_HOME /usr/local/jdk/jdk1.8.0_251/jre
---> Running in 2905af64f88c
Removing intermediate container 2905af64f88c
---> c4f00b71b7f1
Step 8/10 : ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH
---> Running in 9e27b3d384d1
Removing intermediate container 9e27b3d384d1
---> 768a812042b2
Step 9/10 : ENV PATH $JAVA_HOME/bin:$PATH
---> Running in b33cbb2e1213
Removing intermediate container b33cbb2e1213
---> 75325c4bd9f2
Step 10/10 : EXPOSE 80
---> Running in c55b08485621
Removing intermediate container c55b08485621
---> 95064f52c03b
Successfully built 95064f52c03b
Successfully tagged java:8
See 'docker --help'
[root@server01 jdk]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
# 完成的镜像
java 8 95064f52c03b 14 seconds ago 610MB
centos 7 eeb6ee3f44bd 6 months ago 204MB
- 运行容器并进入容器内部,查看jdk是否安装成功
# 进入容器内部
# docker run -it --name java8 java:8
# 查看java版本
[root@4fc4e341d672 jdk]# java -version
# jdk安装成功
java version "1.8.0_251"
Java(TM) SE Runtime Environment (build 1.8.0_251-b08)
Java HotSpot(TM) 64-Bit Server VM (build 25.251-b08, mixed mode)
[root@4fc4e341d672 jdk]# pwd
/usr/local/jdk
更多推荐
已为社区贡献1条内容
所有评论(0)