目 录CONTENT

文章目录

Dockerfile

Sakura
2023-09-14 / 0 评论 / 0 点赞 / 21 阅读 / 15164 字 / 正在检测是否收录...

一: 容器镜像的获取方法

1. 在 DockerHub 直接下载

默认会加 latest 标签

docker pull debian

2. 把操作系统中文件系统打包成为镜像

  1. 安装最小的文件系统

  1. 把操作系统中的文件系统进行打包

tar --numeric-owner --exclude=/proc --exclude=/sys -cvf centos7u6.tar /

--numeric-owner表示打包过程中的文件属组和属主都是以数字的方式出现

--exclude=/proc --exclude=/sys排除的两个文件夹 , 因为这两个文件夹运行时现在系统中运行的文件

-cvf分别表示创建 , 显示过程 , 指定文件

/对根目录进行打包

  1. 把打包后的文件加载到本地文件

# 使用 scp 命令将打包好的命令上传到另一台linux主机中
scp 要上传的文件 192.168.10.153:/root
# 使用功能 docker import 将本地文件生成容器镜像
docker import centos7u6.tar centos7u6:v1
# docker images 查看镜像
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
centos7u6    v1        130cb005b2dc   7 seconds ago   1.09GB

3. 把正在运行的容器打包成容器镜像 ( 基本不用 )

  1. 首先先运行一个容器

docker run -it centos7u6:v1 bash
  1. 在容器中安装软件

yum -y install httpd
  1. 把正在运行的容器打包为容器镜像

# 把正在运行的容器打包为容器镜像 
docker commit 064aace45718 centos7u6-httpd:v1

4. 通过Dockerfile实现容器镜像的自定义及生成 ( 重要 )

Dockerfile 是一种能够被 Docker 程序解释的剧本。Dockerfile 由一条一条的指令组成,并且有自己的书写格式和支持的命令。当我们需要在容器镜像中指定自己额外的需求时,只需在 Dockerfile 上添加或修改指令,然后通过 docker build 生成我们自定义的容器镜像 ( image )

二: Dockerfile 指令

  • 构建类指令

    • 用于构建 image

    • 其指定的操作不会在运行 image 的容器上执行(FROM、MAINTAINER、RUN、ENV、ADD、COPY)

  • 设置类指令

    • 用于设置 image 的属性

    • 其指定的操作将在运行 image 的容器中执行(CMD、ENTRYPOINT、USER 、EXPOSE、VOLUME、WORKDIR、ONBUILD)

三: 指令详细解释

通过man dockerfile可以查看到详细的说明,这里简单的翻译并列出常用的指令

1. FROM

FROM 指令用于指定其后构建新镜像所使用的基础镜像。

FROM 指令必是 Dockerfile 文件中的首条命令。

FROM 指令指定的基础 image 可以是官方远程仓库中的 , 也可以位于本地仓库 , 优先本地仓库。

# 格式:FROM <image>:<tag>
FROM centos:latest

2. RUN

RUN指令用于在构建镜像中执行命令,有以下两种格式 :

  • shell格式

# 格式:RUN <命令>
RUN echo 'kubemsb' > /var/www/html/index.html
  • exec格式

# 格式:RUN ["可执行文件", "参数1", "参数2"]
RUN ["/bin/bash", "-c", "echo kubemsb > /var/www/html/index.html"]

3. CMD

CMD不同于 RUN,CMD 用于指定在容器启动时所要执行的命令 , 而 RUN 用于指定镜像构建时所要执行的命令。

# 格式有三种:
CMD ["executable","param1","param2"]
CMD ["param1","param2"]
CMD command param1 param2

每个 Dockerfile 只能有一条 CMD 命令。如果指定了多条命令,只有最后一条会被执行。

如果用户启动容器时候指定了运行的命令,则会覆盖掉 CMD 指定的命令。

# 什么是启动容器时指定运行的命令?
docker run -d -p 80:80 镜像名 运行的命令

4. EXPOSE

EXPOSE 指令用于指定容器在运行时监听的端口

# 格式:EXPOSE <port> [<port>...]
EXPOSE 80 3306 8080

上述运行的端口还需要使用 docker run 运行容器时通过 -p 参数映射到宿主机的端口.

5. ENV

ENV指令用于指定一个环境变量

# 格式:ENV <key> <value> 或者 ENV <key>=<value>
ENV JAVA_HOME /usr/local/jdkxxxx/

6. ADD

ADD指令用于把宿主机上的文件拷贝到镜像中

ADD <src> <dest>
# <src>可以是一个本地文件或本地压缩文件,还可以是一个url,
# 如果把<src>写成一个url,那么ADD就类似于wget命令
# dest>路径的填写可以是容器内的绝对路径,也可以是相对于工作目录的相对路径

7. COPY

COPY 指令与 ADD 指令类似 , 但 COPY 的源文件只能是本地文件

COPY <src> <dest>

8. ENTRYPOINT

ENTRYPOINTCMD非常类似

相同点: 一个Dockerfile只写一条,如果写了多条,那么只有最后一条生效 都是容器启动时才运行

不同点: 如果用户启动容器时候指定了运行的命令,ENTRYPOINT不会被运行的命令覆盖,而CMD则会被覆盖

# 格式有两种:
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2

9. VOLUME

VOLUME指令用于把宿主机里的目录与容器里的目录映射.

只指定挂载点 , docker 宿主机映射的目录为自动生成的。

VOLUME ["<mountpoint>"]

10. USER

USER指令设置启动容器的用户 ( 像 hadoop 需要 hadoop 用户操作 , oracle 需要 oracle 用户操作 ) , 可以是用户名或 UID

USER daemon
USER 1001

注意:如果设置了容器以 daemon 用户去运行,那么 RUN , CMD 和 ENTRYPOINT 都会以这个用户去运行 镜像构建完成后,通过 docker run 运行容器时 , 可以通过 -u 参数来覆盖所指定的用户

11. WORKDIR

WORKDIR指令设置工作目录 , 类似于cd命令不建议使用RUN cd /root ,建议使用WORKDIR

WORKDIR /root

四: Dockerfile 生成镜像步骤

Dokcerfile:

  • From ... : 指定了生成新容器镜像的时候 , 基础镜像是什么

  • RUN yum-y install wget : 容器镜像中包含的工具

  • ADD./data : 将宿主主机中的文件添加到容器/根下的 data 中去

  • CMD ['/bin/bash","run.sh"] : 通过容器镜像启动容器所要执行的命令

Dockerfile:

  • centos:latest 容器首先作为基本层

  • 把容器镜像中包含的工具/软件, 提交为镜像的一层

  • 基于下面两层所生成的容器镜像添加一层 , 在这一层中把当前目录的文件复制到容器中的/data 根下的 data 目录中

  • 把下面三层生成一个容器镜像 , 然后启动容器 , 执行命令

每一次生成都是不可变的 , 在云原生领域中 docker 是不可变的基础设施

DockerContainer:

  • 使用docker run 生成容器镜像

  • 生成的镜像中就包含了工具 , 文件 , 以及指令

五: Dockerfile生成容器镜像步骤

第一步: 创建一个文件夹 ( 目录 )

第二步 : 在文件夹 ( 目录 ) 中创建Dockerfile 文件 ( 并编写 ) 及其他文件

第三步 : 使用docker build 命令构建镜像

第四步 : 使用构建的镜像启动容器

六: Dockerfile生成Nginx镜像

  1. 创建一个文件夹 ( 目录 )

# 1.创建目录并进入口
mkdir NginxDocker
cd NginxDocker

# 2.创建index.html
echo "Nginx Docker is running" >> index.html

# 3.测试内容是否添加
cat index.html
  1. 创建 Dockjerfile 文件

vim Dockerfile

# 指定基础镜像
FROM centos:centos7
# 执行维护者
MAINTAINER "Sakura<sakurasss.top"
# 安装wget
RUN yum -y install wget
# 通过wget下载epel
RUN wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
# 安装Nginx
RUN yum -y install nginx
# 把index.html添加到对应目录
ADD index.html /usr/share/nginx/html/
# 把Nginx守护进程模式关掉,这样就可以在前台运行了
RUN echo "daemon off;" >> /etc/nginx/nginx.conf
# 指定要暴露的端口
EXPOSE 80
# 启动容器再启动Nginx太麻烦,直接设置自动启动
CMD /usr/sbin/nginx
  1. docker build 构建镜像

# . 表示当前目录下的Dockerfile文件
docker build -t centos7-nginx:v1 .
# 如果想要指定文件,则加 -f
  1. docker run 启动镜像

docker run -d -p 8081:80 centos7-nginx:v1
  1. docker inspect 查看 IPAddress

# 查看IPAddress
docker inspect 70 | grep "IPAddress"
            "SecondaryIPAddresses": null,
            "IPAddress": "172.17.0.2",
                    "IPAddress": "172.17.0.2",
  1. 通过curl 访问

curl http://172.17.0.2
curl http://localhost:8081

七: Dockerfile容器生成优化

1. 减少镜像分层

Dockerfile 中包含多种指令,如果涉及到部署最多使用的算是 RUN 命令了,使用 RUN 命令时,不建议每次安装都使用一条单独的 RUN 命令,可以把能够合并安装指令合并为一条,这样就可以减少镜像分层

  • 优化前

FROM centos:latest
MAINTAINER www.kubemsb.com
RUN yum install epel-release -y 
RUN yum install -y gcc gcc-c++ make -y
RUN wget http://docs.php.net/distributions/php-5.6.36.tar.gz
RUN tar zxf php-5.6.36.tar.gz
RUN cd php-5.6.36
RUN ./configure --prefix=/usr/local/php 
RUN make -j 4 
RUN make install
EXPOSE 9000
CMD ["php-fpm"]
  • 优化后

FROM centos:latest
MAINTAINER www.kubemsb.com
RUN yum install epel-release -y && \
    yum install -y gcc gcc-c++ make

RUN wget http://docs.php.net/distributions/php-5.6.36.tar.gz && \
    tar zxf php-5.6.36.tar.gz && \
    cd php-5.6.36 && \
    ./configure --prefix=/usr/local/php && \
    make -j 4 && make install
EXPOSE 9000
CMD ["php-fpm"]

2. 清理无用数据

  • 一次RUN形成新的一层,如果没有在同一层删除,无论文件是否最后删除,都会带到下一层,所以要在每一层清理对应的残留数据,减小镜像大小。

  • 把生成容器镜像过程中部署的应用软件包做删除处理

FROM centos:latest
MAINTAINER www.kubemsb.com
RUN yum install epel-release -y && \
    yum install -y gcc gcc-c++ make gd-devel libxml2-devel \
    libcurl-devel libjpeg-devel libpng-devel openssl-devel \
    libmcrypt-devel libxslt-devel libtidy-devel autoconf \
    iproute net-tools telnet wget curl && \
    yum clean all && \
    rm -rf /var/cache/yum/*

RUN wget http://docs.php.net/distributions/php-5.6.36.tar.gz && \
    tar zxf php-5.6.36.tar.gz && \
    cd php-5.6.36 && \
    ./configure --prefix=/usr/local/php \
    make -j 4 && make install && \
    cd / && rm -rf php*

3. 多阶段构建镜像

  • 项目容器镜像有两种,一种直接把项目代码复制到容器镜像中,下次使用容器镜像时即可直接启动;另一种把需要对项目源码进行编译,再复制到容器镜像中使用

  • 不论是哪种方法都会让制作镜像复杂了些,并也会让容器镜像比较大,建议采用分阶段构建镜像的方法实现

$ git clone https://github.com/kubemsb/tomcat-java-demo
$ cd tomcat-java-demo
$ vi Dockerfile
FROM maven AS build
ADD ./pom.xml pom.xml
ADD ./src src/
RUN mvn clean package

FROM kubemsb/tomcat
RUN rm -rf /usr/local/tomcat/webapps/ROOT
COPY --from=build target/*.war /usr/local/tomcat/webapps/ROOT.war

$ docker build -t demo:v1 .
$ docker container run -d -v demo:v1
第一个 FROM 后边多了个 AS 关键字,可以给这个阶段起个名字
第二个 FROM 使用上面构建的 Tomcat 镜像,COPY 关键字增加了 —from 参数,用于拷贝某个阶段的文件到当前阶段。

0

评论区