一: 容器镜像的获取方法
1. 在 DockerHub 直接下载
默认会加 latest 标签
docker pull debian
2. 把操作系统中文件系统打包成为镜像
安装最小的文件系统
把操作系统中的文件系统进行打包
tar --numeric-owner --exclude=/proc --exclude=/sys -cvf centos7u6.tar /
--numeric-owner
表示打包过程中的文件属组和属主都是以数字的方式出现
--exclude=/proc --exclude=/sys
排除的两个文件夹 , 因为这两个文件夹运行时现在系统中运行的文件
-cvf
分别表示创建 , 显示过程 , 指定文件
/
对根目录进行打包
把打包后的文件加载到本地文件
# 使用 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. 把正在运行的容器打包成容器镜像 ( 基本不用 )
首先先运行一个容器
docker run -it centos7u6:v1 bash
在容器中安装软件
yum -y install httpd
把正在运行的容器打包为容器镜像
# 把正在运行的容器打包为容器镜像
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
ENTRYPOINT
与CMD
非常类似
相同点: 一个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.创建目录并进入口
mkdir NginxDocker
cd NginxDocker
# 2.创建index.html
echo "Nginx Docker is running" >> index.html
# 3.测试内容是否添加
cat index.html
创建 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
docker build
构建镜像
# . 表示当前目录下的Dockerfile文件
docker build -t centos7-nginx:v1 .
# 如果想要指定文件,则加 -f
docker run
启动镜像
docker run -d -p 8081:80 centos7-nginx:v1
docker inspect
查看 IPAddress
# 查看IPAddress
docker inspect 70 | grep "IPAddress"
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.2",
"IPAddress": "172.17.0.2",
通过
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 参数,用于拷贝某个阶段的文件到当前阶段。
评论区