Dockerfile

什么是Dockerfile?

Dockerfile可以看做是被Docker程序所解释翻译的脚本,由一组命令集合而成,每一条命令都对应一条操作命令,有其翻译为Linux下的具体命令。用户可以通过自定义内容来快速构建镜像。

构建docker镜像时有两种方式,一种是用commit的方式构建镜像,而Dockerfile是另一种构建镜像的方式。

Dockerfile构建镜像是以基础镜像为基础的,Dockerfile是一个文本文件,内容是用户编写的一些docker指令,每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。

Dockerfile的基本指令有十三个,分别是:FROM、MAINTAINER、RUN、CMD、EXPOSE、ENV、ADD、COPY、ENTRYPOINT、VOLUME、USER、WORKDIR、ONBUILD.

学习Dockerfile之前,我们先来学习一些Dockerfile常用的指令。

Dockerfile常用指令:

类型   命令
基础镜像信息 FROM
维护者信息 MAINTAINER
镜像操作指令 RUN、COPY、ADD、EXPOSE、WORKDIR、ONBUILD、USER、VOLUME ENV等
容器启动时执行指令 CMD、ENTRYPOINT

1、FROM指令

两种形式如下:

FROM <IMAGE>
FROM <IMAGE>:<TAG>

通过FROM指定的镜像名称必须是一个已经存在的镜像,这个镜像称之为基础镜像,必须位于第一条非注释指令。

2、MAINTAINER 指令

指定镜像的作者信息,包含镜像的所有者和联系人信息。

MAINTAINER <NAME>

3、RUN 指令

用于指定构建镜像时运行的命令,两种模式:

RUN <command>                                     (shell模式)
RUN [ "executable", "param1", "param2" ]           (exec模式)

多条RUN指令可以合并为一条,这样在构建的时候会减少产生中间层镜像。

RUN cd /usr/src/nginx-1.10.2 \
    && mkdir /usr/local/nginx \
    && ./configure --prefix=/usr/local/nginx && make && make install \
    && nginx

4、EXPOSE 指令
指定运行该镜像的容器使用的端口,可以是多个。

EXPOSE <端口1> [<端口2>...]

使用这个指令的目的是告诉应用程序容器内应用程序会使用的端口,在运行时还需要使用-p参数指定映射端口。这是docker处于安全的目的,不会自动打开端口。

docker run --name tomcat -p 8080:8080 -v /root/webapps:/usr/local/tomcat/webapps/ -d tomcat

5、CMD 指令

CMD 命令用于容器启动时需要执行的命令,CMD 在 Dockerfile 中只能出现一次,如果出现多个,那么只有最后一个会有效。
其作用是在启动容器的时候提供一个默认的命令项。如果用户执行docker run的时候提供了命令项,就会覆盖掉这个命令,没提供就会使用构建时的命令。

格式:

shell 格式: CMD <命令>
exec  格式: CMD ["可执行文件", "参数1", "参数2"...]

如容器启动时进入bash:

CMD /bin/bash

也可以用exec写法:

CMD ["/bin/bash"]

6、ENTRYPOINT指令

与CMD类似,ENTRYPOINT不会被docker run中指定的命令覆盖,如果想覆盖ENTRYPOINT,则需要在docker run中指定--entrypoint选项.

它有两种模式:

ENTRYPOINT <command>                             (shell模式)
ENTRYPOINT [ "executable", "param1", "param2" ]  (exec模式)

7、ADD 和 COPY 指令

作用都是将文件或目录复制到Dockerfile构建的镜像中

COPY [--chown=<user>:<group>] <源路径>... <目标路径>
COPY [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"]

ADD [--chown=<user>:<group>] <源路径>... <目标路径>
ADD [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"]

ADD包含了类似tar的解压功能,如果只是单纯复制文件,建议使用COPY,而且,两者的源文件路径使用Dockerfile相对路径,目标路径使用绝对路径。

8、VOLUME 指令
用于向容器添加卷,可以提供共享存储等功能

VOLUME ['/data']

9、WORKDIR 指令 

在容器内部设置工作目录,这样ENTRYPOINT和CMD指定的命令都会在容器中这个目录下进行,如果切换到的目录不存在,WORKDIR会为此创建目录。

WORKDIR /path/to/workdir

10、USER 指令
指定运行容器时的用户,需要注意的是这个用户必须是已经存在,否则无法指定.

USER daemon

镜像就会以daemon身份运行,可以使用uid,gid等各种组合使用

11、ENV 指令
ENV 指令用于设置容器的环境变量,这些变量以”key=value”的形式存在,在容器内被脚本或者程序调用,容器运行的时候这个变量也会保留。

1) 设置一个: ENV <key> <value>
2) 设置多个:ENV <key1>=<value1> <key2>=<value2>...

12、ONBUILD 指令
ONBUILD 用于配置当前所创建的镜像作为其它新创建镜像的基础镜像时,所执行的操作指令,意思就是:这个镜像创建后,如果其它镜像以这个镜像为基础,会先执行这个镜像的ONBUILD命令.

ONBUILD [INSTRUCTION]

 实例:

使用dockerfile构建Nginx镜像

1.在某一个目录下面创建一个专门存放此demo的目录.

[root@localhost ~]# mkdir -p docker_demo/nginx 
[root@localhost ~]# cd docker_demo/nginx
[root@localhost nginx]# touch Dockerfile
[root@localhost nginx]# pwd
/root/docker_demo/nginx

2.接下来就开始编写Dockerfile文件了,这里以编译nginx提供web服务来构建新的镜像.

1、>下载nginx源码包到docker_demo这个目录下

[root@localhost nginx]# ll
-rw-r--r-- 1 root root    386 May  6 11:13 dockerfile
-rw-r--r-- 1 root root 885562 Nov 17  2015 nginx-1.9.7.tar.gz

2、> 以下是编写好的Dockerfile:

FROM centos:7
MAINTAINER saneri 838118461@qq.com
RUN yum install -y wget proc-devel net-tools gcc zlib zlib-devel make openssl-devel
#RUN wget http://nginx.org/download/nginx-1.9.7.tar.gz
ADD nginx-1.9.7.tar.gz .
WORKDIR nginx-1.9.7
RUN ./configure --prefix=/usr/local/nginx && make && make install
EXPOSE 80
ENV PATH /usr/local/nginx/sbin:$PATH
CMD /bin/sh -c 'nginx -g "daemon off;"'

3、> 执行docker build进行构建:

[root@localhost nginx]# docker build -t nginx_centos .

构建成功后,查看新构建的镜像:

[root@localhost nginx]# docker images
REPOSITORY                 TAG                 IMAGE ID            CREATED             SIZE
nginx_centos               latest              4c79631898cb        21 minutes ago      366 MB

4、>然后使用构建的镜像启动一个container并开启nginx服务:

[root@localhost ~]# docker run -d -p80:80 --name nginx_centos nginx_centos

5、> 查看container运行状态:

[root@localhost ~]# docker ps -l
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
b7ce7b4ca2e3        nginx_centos        "/bin/sh -c '/bin/..."   2 hours ago         Up 2 hours          0.0.0.0:80->80/tcp   nginx_centos

5.> 测试nginx 80 端口访问

[root@localhost ~]# lsof -i:80
COMMAND     PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
docker-pr 45542 root    4u  IPv6 472743      0t0  TCP *:http (LISTEN)
[root@localhost ~]# curl -I http://192.168.10.20:80
HTTP/1.1 200 OK
Server: nginx/1.9.7
Date: Wed, 06 May 2020 09:20:24 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Wed, 06 May 2020 03:32:24 GMT
Connection: keep-alive
ETag: "5eb22fc8-264"
Accept-Ranges: bytes

[root@localhost ~]# 

使用Dockerfile安装centos7镜像,并完成ssh连接

1.创建一个专门存放此demo的目录.

[root@localhost ~]# mkdir -p docker_demo/ssh_centos/
[root@localhost ~]# cd docker_demo/ssh_centos/
[root@localhost ssh_centos]# touch Dockerfile
[root@localhost ssh_centos]# pwd
/root/docker_demo/ssh_centos

2.以下是编写好的Dockerfile:

FROM centos:7
MAINTAINER saneri 838118461@qq.com

# 更新yum源
RUN yum makecache fast && yum -y update glibc
# 安装常用软件
RUN yum install -y openssh-server vim tar wget curl rsync bzip2 iptables tcpdump less telnet net-tools lsof
# 初始化ssh登陆
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N ''
RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key -N ''
RUN ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -N ''
RUN ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N ''

RUN echo '123456' | passwd --stdin root
RUN echo "RSAAuthentication yes" >> /etc/ssh/sshd_config
RUN echo "PubkeyAuthentication yes" >> /etc/ssh/sshd_config

# 启动sshd服务并且暴露22端口
RUN mkdir /var/run/sshd

EXPOSE 22

CMD ["/usr/sbin/sshd", "-D"]

3.执行docker build进行构建:

[root@localhost ssh_centos]# docker build -t sshd_centos7 .

构建成功后,查看新构建的镜像:

[root@localhost ssh_centos]# docker images
REPOSITORY                 TAG                 IMAGE ID            CREATED             SIZE
sshd_centos7               latest              96657c13c530        45 minutes ago      422 MB

4.启动容器,将ssh容器的22端口映射为15000端口.

[root@localhost ~]# docker run -d --name sshd_centos7 --rm -p 15000:22 sshd_centos7
5995979a12e2e408be38fb3dd4c26451219458a6b583f056449bc29767ff3023

查看容器启动情况

[root@localhost ssh_centos]# docker ps -l
CONTAINER ID        IMAGE               COMMAND               CREATED             STATUS              PORTS                   NAMES
5995979a12e2        sshd_centos7        "/usr/sbin/sshd -D"   41 minutes ago      Up 41 minutes       0.0.0.0:15000->22/tcp   sshd_centos7

5.进入容器并开启ssh连接,回车两次,其中有个警告,可以忽略.

[root@localhost ssh_centos]# docker exec  -it  sshd_centos7 /bin/bash
[root@5995979a12e2 /]# /usr/sbin/sshd -D &
[1] 81
[root@5995979a12e2 /]# /etc/ssh/sshd_config line 140: Deprecated option RSAAuthentication

[1]+  Exit 255                /usr/sbin/sshd -D
[root@5995979a12e2 /]# 

6.查看是否已经启动:lsof -i:22,出现如下信息则表示启动成功

[root@5995979a12e2 /]# lsof -i:22
COMMAND PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
sshd      1 root    3u  IPv4 523483      0t0  TCP *:ssh (LISTEN)
sshd      1 root    4u  IPv6 523489      0t0  TCP *:ssh (LISTEN)

7.进行ssh远程登录测试,输入密码后测试连接成功.

 

使用dockerfile构建tomcat镜像,并发布war包

1.上传tomcat包和jdk的包至服务器目录,文件目录结构如下.

[root@localhost dockerfile]# tree -L 1 tomcat
tomcat
├── apache-tomcat-8.5.51.tar.gz
├── Dockerfile
└── jdk-8u65-linux-x64.tar.gz

0 directories, 3 files

2.编写dockerfile文件,内容如下

FROM centos:7
MAINTAINER saneri

#将宿主机的jdk目录下的文件拷至镜像的/usr/local目录下
ADD jdk-8u65-linux-x64.tar.gz /usr/local/
#将宿主机的tomcat目录下的文件拷至镜像的/usr/local目录下
ADD apache-tomcat-8.5.51.tar.gz /usr/local/

#设置环境变量
ENV JAVA_HOME=/usr/local/jdk1.8.0_65
ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.51
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin

#公开端口
EXPOSE 8080
#设置启动命令
CMD ["/usr/local/apache-tomcat-8.5.51/bin/catalina.sh","run"]

3.构建镜像

[root@localhost tomcat]# docker build -t local/tomcat7-jdk1.8 . -f Dockerfile

镜像生成后,使用 docker images 查看本地镜像,如下

[root@localhost tomcat]# docker images
REPOSITORY                 TAG                 IMAGE ID            CREATED             SIZE
local/tomcat7-jdk1.8       latest              aac779847112        6 hours ago         583 MB

4.创建容器:

[root@localhost tomcat]# docker run -d -p 8080:8080 --name tomcat7-jdk1.8 local/tomcat7-jdk1.8:latest
86aa4f015c436c6b71511638df98d37e23301e877673dc7506334a8e832b57d0

5.查看容器,并验证也可以在浏览器中直接输入ip:port。

[root@localhost tomcat]# docker ps -l
CONTAINER ID        IMAGE                         COMMAND                  CREATED             STATUS              PORTS                    NAMES
86aa4f015c43        local/tomcat7-jdk1.8:latest   "/usr/local/apache..."   2 minutes ago       Up 2 minutes        0.0.0.0:8080->8080/tcp   tomcat7-jdk1.8
[root@localhost tomcat]# 
[root@localhost tomcat]# curl -I http://192.168.10.20:8080
HTTP/1.1 200 
Content-Type: text/html;charset=UTF-8
Transfer-Encoding: chunked
Date: Sat, 09 May 2020 15:27:41 GMT

6.下载helloworld.war包,放入容器的webapps目录下即可.

docker cp helloworld.war  86aa4f015c43:/usr/local/apache-tomcat-8.5.51/webapps/

这样所有的java应用都可以用此方法在tomcat中运行了.

 

参考文档:https://blog.csdn.net/wuapeng/article/details/80974417

posted @ 2020-04-29 17:31  梦徒  阅读(382)  评论(0)    收藏  举报