315 lines
11 KiB
Markdown
315 lines
11 KiB
Markdown
|
<h2><center>Docker 镜像构建</center></h2>
|
|||
|
|
|||
|
------
|
|||
|
|
|||
|
## 一:创建镜像
|
|||
|
|
|||
|
### 1. 容器文件系统打包
|
|||
|
|
|||
|
将容器的文件系统打包成tar文件,也就是把正在运行的容器直接导出为tar包的镜像文件。
|
|||
|
|
|||
|
**导出**
|
|||
|
|
|||
|
```bash
|
|||
|
export
|
|||
|
Export a container's filesystem as a tar archive
|
|||
|
有两种方式(elated_lovelace为容器名):
|
|||
|
第一种:
|
|||
|
[root@docker ~]# docker export -o elated_lovelace.tar elated_lovelace
|
|||
|
第二种:
|
|||
|
[root@docker ~]# docker export 容器名称 > 镜像.tar
|
|||
|
```
|
|||
|
|
|||
|
**导入**
|
|||
|
|
|||
|
```bash
|
|||
|
导入镜像归档文件到其他宿主机:
|
|||
|
import
|
|||
|
Import the contents from a tarball to create a filesystem image
|
|||
|
[root@docker ~]# docker import elated_lovelace.tar elated_lovelace:v1
|
|||
|
```
|
|||
|
|
|||
|
**注意:**
|
|||
|
|
|||
|
如果导入镜像时没有起名字,随后可以单独起名字(没有名字和tag),可以手动加tag。
|
|||
|
|
|||
|
```bash
|
|||
|
[root@docker ~]# docker tag 镜像ID mycentos:7
|
|||
|
```
|
|||
|
|
|||
|
### 2. 通过容器创建本地镜像
|
|||
|
|
|||
|
容器运行起来后,又在里面做了一些操作,并且要把操作结果保存到镜像里。
|
|||
|
|
|||
|
**方案:**
|
|||
|
|
|||
|
使用`docker commit`指令,把一个正在运行的容器,直接提交为一个镜像。`commit`是提交的意思,类似告诉`svn`服务器我要生成一个新的版本。
|
|||
|
|
|||
|
例:在容器内部新建了一个文件
|
|||
|
|
|||
|
```bash
|
|||
|
[root@docker ~]# docker exec -it 4ddf4638572d /bin/sh
|
|||
|
[root@4ddf4638572d \]# touch test.txt
|
|||
|
[root@4ddf4638572d \]# exit
|
|||
|
将这个新建的文件提交到镜像中保存
|
|||
|
[root@docker ~]# docker commit 4ddf4638572d wing/helloworld:v2
|
|||
|
```
|
|||
|
|
|||
|
例:
|
|||
|
|
|||
|
```bash
|
|||
|
[root@docker ~]# docker commit -m "my images version1" -a "wing" 108a85b1ed99 daocloud.io/ubuntu:v2
|
|||
|
sha256:ffa8a185ee526a9b0d8772740231448a25855031f25c61c1b63077220469b057
|
|||
|
-m 添加注释
|
|||
|
-a 作者author
|
|||
|
108a85b1ed99 容器环境id
|
|||
|
daocloud.io/ubuntu:v2 镜像名称:hub的名称/镜像名称:tag
|
|||
|
-p,–pause=true 提交时暂停容器运行
|
|||
|
```
|
|||
|
|
|||
|
`Init`层的存在,是为了避免执行`docker commit 时`,把`Docker`自己对 `/etc/hosts`等文件做的修改,也一起提交掉。
|
|||
|
|
|||
|
### 3. 镜像迁移
|
|||
|
|
|||
|
保存一台宿主机上的镜像为`tar`文件,然后可以导入到其他的宿主机上。
|
|||
|
|
|||
|
```bash
|
|||
|
save
|
|||
|
Save an image(s) to a tar archive
|
|||
|
将镜像打包,与下面的load命令相对应
|
|||
|
[root@docker ~]# docker save -o nginx.tar nginx
|
|||
|
load
|
|||
|
Load an image from a tar archive or STDIN
|
|||
|
与上面的save命令相对应,将上面sava命令打包的镜像通过load命令导入
|
|||
|
[root@docker ~]# docker load < nginx.tar
|
|||
|
```
|
|||
|
|
|||
|
**注意:**
|
|||
|
|
|||
|
- `tar`文件的名称和保存的镜像名称没有关系
|
|||
|
- 导入的镜像如果没有名称,自己打`tag`起名字
|
|||
|
|
|||
|
**扩展:**export和save的区别
|
|||
|
|
|||
|
- **export:**相当于容器快照,容器快照文件将丢弃所有的历史记录和元数据信息。
|
|||
|
- **save:**没有这个现象,就是完整的。
|
|||
|
|
|||
|
## 二:利用 Dockerfile 创建镜像
|
|||
|
|
|||
|
`docker build`命令用于根据给定的`Dockerfile`和上下文以构建`Docker`镜像。
|
|||
|
|
|||
|
**docker build语法:**
|
|||
|
|
|||
|
```bash
|
|||
|
docker build [OPTIONS] <PATH | URL | ->
|
|||
|
```
|
|||
|
|
|||
|
### 1. 常用选项
|
|||
|
|
|||
|
```shell
|
|||
|
--build-arg:设置构建时的变量
|
|||
|
--no-cache:默认false。设置该选项,将不使用Build Cache构建镜像
|
|||
|
--pull:默认false。设置该选项,总是尝试pull镜像的最新版本
|
|||
|
--compress:默认false。设置该选项,将使用gzip压缩构建的上下文
|
|||
|
--disable-content-trust:默认true。设置该选项,将对镜像进行验证
|
|||
|
--file, -f:Dockerfile的完整路径,默认值为‘PATH/Dockerfile’
|
|||
|
--isolation:默认--isolation="default",即Linux命名空间;其他还有process或hyperv
|
|||
|
--label:为生成的镜像设置metadata
|
|||
|
--squash:默认false。设置该选项,将新构建出的多个层压缩为一个新层,但是将无法在多个镜像之间共享新层;设置该选项,实际上是创建了新image,同时保留原有image。
|
|||
|
--tag, -t:镜像的名字及tag,通常name:tag或者name格式;可以在一次构建中为一个镜像设置多个tag
|
|||
|
--network:默认default。设置该选项,Set the networking mode for the RUN instructions during build
|
|||
|
--quiet, -q:默认false。设置该选项,Suppress the build output and print image ID on success
|
|||
|
--force-rm:默认false。设置该选项,总是删除掉中间环节的容器
|
|||
|
--rm:默认--rm=true,即整个构建过程成功后删除中间环节的容器
|
|||
|
```
|
|||
|
|
|||
|
### 2. PATH | URL | - 说明
|
|||
|
|
|||
|
给出命令执行的上下文。
|
|||
|
|
|||
|
`docker build`需要的各种文件必须放到上下文目录中
|
|||
|
|
|||
|
上下文可以是构建执行所在的本地路径,也可以是远程`URL`,如`Git`库、tar包或文本文件等。如果是Git库,如https://github.com/docker/rootfs.git#container:docker,则隐含先执行`git clone --depth 1 --recursive`,到本地临时目录;然后再将该临时目录发送给构建进程。
|
|||
|
|
|||
|
构建镜像的进程中,可以通过`ADD`命令将上下文中的任何文件加入到镜像中。
|
|||
|
|
|||
|
`-`表示通过`STDIN`给出`Dockerfile`或上下文。
|
|||
|
|
|||
|
**示例:**
|
|||
|
|
|||
|
```shell
|
|||
|
docker build - < Dockerfile
|
|||
|
```
|
|||
|
|
|||
|
**说明:**该构建过程只有`Dockerfile`,没有上下文
|
|||
|
|
|||
|
```shell
|
|||
|
docker build - < context.tar.gz
|
|||
|
```
|
|||
|
|
|||
|
**说明:**其中Dockerfile位于context.tar.gz的根路径
|
|||
|
|
|||
|
```bash
|
|||
|
[root@docker ~]# docker build -t champagne/bbauto:latest -t champagne/bbauto:v2.1 .
|
|||
|
[root@docker ~]# docker build -f dockerfiles/Dockerfile.debug -t myapp_debug .
|
|||
|
```
|
|||
|
|
|||
|
### 3. 创建镜像所在的文件夹和 Dockerfile 文件
|
|||
|
|
|||
|
```shell
|
|||
|
[root@docker ~]# mkdir dockerfile-test
|
|||
|
[root@docker ~]# cd dockerfile-test
|
|||
|
[root@docker dockerfile-test]# touch Dockerfile
|
|||
|
```
|
|||
|
|
|||
|
在Dockerfile文件中写入指令,每一条指令都会更新镜像的信息例如:
|
|||
|
|
|||
|
```bash
|
|||
|
[root@docker dockerfile-test]# vim Dockerfile
|
|||
|
# This is a comment
|
|||
|
FROM daocloud.io/library/centos:7
|
|||
|
MAINTAINER wing wing@qfedu.com
|
|||
|
RUN 命令1;命令2;命令3
|
|||
|
RUN 命令
|
|||
|
```
|
|||
|
|
|||
|
**格式说明:**
|
|||
|
|
|||
|
- 每行命令都是以`INSTRUCTION statement`形式,就是命令`+`清单的模式。命令要大写,`#`是注解
|
|||
|
- `FROM`命令是告诉`docker`我们的镜像什么
|
|||
|
- `MAINTAINER`是描述 镜像的创建人
|
|||
|
- `RUN`命令是在镜像内部执行。就是说他后面的命令应该是针对镜像可以运行的命令
|
|||
|
|
|||
|
### 4. 创建镜像
|
|||
|
|
|||
|
**命令:**
|
|||
|
|
|||
|
```shell
|
|||
|
[root@docker ~]# docker build -t centos:v2 .
|
|||
|
|
|||
|
docker build 是docker创建镜像的命令
|
|||
|
-t 是标识新建的镜像
|
|||
|
centos 仓库名称
|
|||
|
:v2 tag
|
|||
|
. 上下文目录,如果不用-f指定Dockerfile文件的位置和名称,默认会从上下文目录也就是这里指定的当前目录查找
|
|||
|
```
|
|||
|
|
|||
|
**详细执行过程:**
|
|||
|
|
|||
|
```bash
|
|||
|
[root@docker dockerfile-test]# docker build -t wxin/centos:v1 .
|
|||
|
[+] Building 0.4s (6/6) FINISHED docker:default
|
|||
|
=> [internal] load build definition from Dockerfile 0.0s
|
|||
|
=> => transferring dockerfile: 201B 0.0s
|
|||
|
=> [internal] load metadata for docker.io/library/centos:latest 0.0s
|
|||
|
=> [internal] load .dockerignore 0.0s
|
|||
|
=> => transferring context: 2B 0.0s
|
|||
|
=> [1/2] FROM docker.io/library/centos:latest 0.0s
|
|||
|
=> [2/2] RUN touch test.txt && echo 1234567890 > test.txt 0.3s
|
|||
|
=> exporting to image 0.0s
|
|||
|
=> => exporting layers 0.0s
|
|||
|
=> => writing image sha256:fe13d78ff4131453ad82cec521f82ee79ba44fda5e 0.0s
|
|||
|
=> => naming to docker.io/wxin/centos:v1
|
|||
|
```
|
|||
|
|
|||
|
### 5. 创建完成后,从镜像创建容器
|
|||
|
|
|||
|
```bash
|
|||
|
[root@docker dockerfile-test]# docker run -it -d --name="centos-v1" wxin/centos:v1 /bin/bash
|
|||
|
```
|
|||
|
|
|||
|
## 三:Dockerfile文件构建容器
|
|||
|
|
|||
|
### 1. Dockerfile 文件构建 nginx
|
|||
|
|
|||
|
```bash
|
|||
|
[root@docker ~]# vim Dockerfile
|
|||
|
FROM centos:7.2.1511
|
|||
|
ENV TZ=Asia/Shanghai
|
|||
|
ENV LANG=en_US.UTF-8
|
|||
|
ENV LANGUAGE=en_US:en
|
|||
|
ENV LC_ALL=en_US.UTF-8
|
|||
|
RUN yum -y install gcc openssl openssl-devel pcre-devel zlib-devel make
|
|||
|
ADD nginx-1.14.0.tar.gz /opt/
|
|||
|
WORKDIR /opt/nginx-1.14.0
|
|||
|
RUN ./configure --prefix=/opt/nginx
|
|||
|
RUN make && make install
|
|||
|
WORKDIR /opt/nginx
|
|||
|
RUN rm -rf /opt/nginx-1.14.0
|
|||
|
ENV NGINX_HOME=/opt/nginx
|
|||
|
ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/nginx/sbin
|
|||
|
EXPOSE 80 443
|
|||
|
CMD ["nginx", "-g", "daemon off;"]
|
|||
|
|
|||
|
注意:
|
|||
|
Nginx的docker仓库原文说明如下:
|
|||
|
If you add a custom CMD in the Dockerfile, be sure to include -g daemon off; in the CMD in order fornginx to stay in the foreground, so that Docker can track the process properly (otherwise your container will stop immediately after starting)!
|
|||
|
Running nginx in debug mode
|
|||
|
Images since version 1.9.8 come with nginx-debug binary that produces verbose output when using higher log levels. It can be used with simple CMD substitution:
|
|||
|
$ docker run --name my-nginx -v /host/path/nginx.conf:/etc/nginx/nginx.conf:ro -d nginx nginx -g 'daemon off;'
|
|||
|
Similar configuration in docker-compose.yml may look like this:
|
|||
|
|
|||
|
web:
|
|||
|
image: nginx
|
|||
|
volumes:
|
|||
|
- ./nginx.conf:/etc/nginx/nginx.conf:ro
|
|||
|
command: [nginx, '-g', 'daemon off;']
|
|||
|
```
|
|||
|
|
|||
|
### 2. Dockerfile 文件构建 redis
|
|||
|
|
|||
|
```bash
|
|||
|
[root@docker ~]# vim Dockerfile
|
|||
|
FROM centos:7.2.1511
|
|||
|
MAINTAINER qf
|
|||
|
ENV TZ=Asia/Shanghai
|
|||
|
ENV LANG=en_US.UTF-8
|
|||
|
ENV LANGUAGE=en_US:en
|
|||
|
ENV LC_ALL=en_US.UTF-8
|
|||
|
RUN yum -y install gcc make
|
|||
|
ADD redis-4.0.9.tar.gz /opt/
|
|||
|
RUN cd /opt/ && mv redis-4.0.9 redis && cd /opt/redis && make && make install
|
|||
|
RUN mkdir -p /opt/redis/logs && mkdir -p /opt/redis/data && mkdir -p /opt/redis/conf && cp /opt/redis/redis.conf /opt/redis/conf/ && cp /opt/redis/src/redis-trib.rb /usr/local/bin/
|
|||
|
EXPOSE 6379
|
|||
|
CMD ["redis-server","/opt/redis/conf/redis.conf"]
|
|||
|
基于哨兵模式的redis镜像
|
|||
|
FROM centos:7.2.1511
|
|||
|
MAINTAINER redis4 jichujingxiang
|
|||
|
ENV TZ=Asia/Shanghai
|
|||
|
ENV LANG=en_US.UTF-8
|
|||
|
ENV LANGUAGE=en_US:en
|
|||
|
ENV LC_ALL=en_US.UTF-8
|
|||
|
RUN yum -y install gcc make
|
|||
|
ADD redis-4.0.9.tar.gz /opt/
|
|||
|
ADD run.sh /
|
|||
|
RUN cd /opt/ && mv redis-4.0.9 redis && cd /opt/redis && make && make install
|
|||
|
RUN mkdir -p /opt/redis/logs && mkdir -p /opt/redis/data && mkdir -p /opt/redis/conf && cp /opt/redis/redis.conf /opt/redis/conf/ && cp /opt/redis/src/redis-trib.rb /usr/local/bin/ && cp /opt/redis/sentinel.conf /opt/redis/conf/ && chmod 777 /run.sh
|
|||
|
EXPOSE 6379
|
|||
|
CMD ["./run.sh"]
|
|||
|
|
|||
|
[root@docker ~]# vim run.sh
|
|||
|
#!/usr/bin/bash
|
|||
|
cd /opt/redis/src/
|
|||
|
./redis-server /opt/redis/conf/redis.conf & #这一个要放在后台运行,不然下面的启动不了
|
|||
|
./redis-sentinel /opt/redis/conf/sentinel.conf
|
|||
|
```
|
|||
|
|
|||
|
3.Dockerfile 文件构建 jenkins
|
|||
|
|
|||
|
```bash
|
|||
|
[root@docker ~]# vim Dockerfile
|
|||
|
FROM local/c7-systemd
|
|||
|
ADD jdk-9.0.1_linux-x64_bin.tar.gz /usr/local/
|
|||
|
ADD apache-tomcat-9.0.14.tar.gz /usr/local/
|
|||
|
WORKDIR /usr/local/
|
|||
|
ENV JAVA_HOME=/usr/local/java
|
|||
|
ENV PATH=$JAVA_HOME/bin:$PATH
|
|||
|
ENV CATALINA_HOME=/usr/local/tomcat
|
|||
|
ENV export JAVA_HOME CATALINA_HOME PATH
|
|||
|
RUN mv jdk-9.0.1 java && mv apache-tomcat-9.0.14 tomcat
|
|||
|
COPY jenkins.war /usr/local/tomcat/webapps/
|
|||
|
EXPOSE 8080
|
|||
|
CMD ["/usr/local/tomcat/bin/catalina.sh","run"]
|
|||
|
```
|
|||
|
|