Docker镜像构建
**作者:行癫(盗版必究)**
------
## 一:创建自己的镜像
#### 1.将容器的文件系统打包成tar包
将容器的文件系统打包成tar文件,也就是把正在运行的容器直接导出为tar包的镜像文件
导出:
```shell
export
Export a container's filesystem as a tar archive
有两种方式(elated_lovelace为容器名):
第一种:
[root@xingdian ~]# docker export -o elated_lovelace.tar elated_lovelace
第二种:
[root@xingdian ~]# docker export 容器名称 > 镜像.tar
```
导入:
```shell
导入镜像归档文件到其他宿主机:
import
Import the contents from a tarball to create a filesystem image
[root@xingdian ~]# docker import elated_lovelace.tar elated_lovelace:v1
```
注意:
如果导入镜像时没有起名字,随后可以单独起名字(没有名字和tag),可以手动加tag
```shell
[root@xingdian ~]# docker tag 镜像ID mycentos:7
```
#### 2.镜像迁移
保存一台宿主机上的镜像为tar文件,然后可以导入到其他的宿主机上
```shell
save
Save an image(s) to a tar archive
将镜像打包,与下面的load命令相对应
[root@xingdian ~]# docker save -o nginx.tar nginx
load
Load an image from a tar archive or STDIN
与上面的save命令相对应,将上面sava命令打包的镜像通过load命令导入
[root@xingdian ~]# docker load < nginx.tar
```
注:
tar文件的名称和保存的镜像名称没有关系
导入的镜像如果没有名称,自己打tag起名字
扩展:export和save的区别
export:相当于容器快照,容器快照文件将丢弃所有的历史记录和元数据信息
save:没有这个现象,就是完整的
#### 3.通过容器创建本地镜像
背景:
容器运行起来后,又在里面做了一些操作,并且要把操作结果保存到镜像里
方案:
使用 docker commit 指令,把一个正在运行的容器,直接提交为一个镜像。commit 是提交的意思,类似我要生成一个新的版本
例子:
在容器内部新建了一个文件
```shell
[root@xingdian ~]# docker exec -it 4ddf4638572d /bin/sh
root@4ddf4638572d:/app# touch test.txt
root@4ddf4638572d:/app# exit
# 将这个新建的文件提交到镜像中保存
[root@xingdian ~]# docker commit 4ddf4638572d xingdian/helloworld:v2
```
例子:
```shell
[root@xingdian ~]# docker commit -m "my images version1" -a "xingdian" 108a85b1ed99 daocloud.io/ubuntu:v2
sha256:ffa8a185ee526a9b0d8772740231448a25855031f25c61c1b63077220469b057
-m 添加注释
-a 作者
108a85b1ed99 容器环境id
daocloud.io/ubuntu:v2 镜像名称:hub的名称/镜像名称:tag
-p,–pause=true 提交时暂停容器运行
```
## 二:利用Dockerfile创建镜像
通过Dockerfile创建镜像,虽然可以自己制作 rootfs(根文件系统),但Docker 提供了一种更便捷的方式,叫作 Dockerfile
docker build命令用于根据给定的Dockerfile和上下文以构建Docker镜像
docker build语法:
```shell
[root@xingdian ~]# docker build [OPTIONS]
```
#### 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 | -说明
给出命令执行的上下文
上下文可以是构建执行所在的本地路径,也可以是远程URL,如Git库、tarball或文本文件等。如果是Git库,如https://github.com/docker/rootfs.git#container:docker,则隐含先执行git clone --depth 1 --recursive,到本地临时目录;然后再将该临时目录发送给构建进程
构建镜像的进程中,可以通过ADD命令将上下文中的任何文件(注意文件必须在上下文中)加入到镜像中
-表示通过STDIN给出Dockerfile或上下文
示例:
```shell
[root@xingdian ~]# docker build - < Dockerfile
```
说明:该构建过程只有Dockerfile,没有上下文
```shell
[root@xingdian ~]# docker build - < context.tar.gz
```
说明:其中Dockerfile位于context.tar.gz的根路径
```shell
[root@xingdian ~]# docker build -t champagne/bbauto:latest -t champagne/bbauto:v2.1 .
[root@xingdian ~]# docker build -f dockerfiles/Dockerfile.debug -t myapp_debug .
```
#### 3. 创建镜像所在的文件夹和Dockerfile文件
```shell
mkdir sinatra
cd sinatra
touch Dockerfile
```
在Dockerfile文件中写入指令,每一条指令都会更新镜像的信息
```shell
# This is a comment
FROM daocloud.io/library/ubuntu
MAINTAINER xingdian xingdian@localhost.localdomain
RUN apt-get update && apt-get install -y ruby ruby-dev
```
格式说明:
每行命令都是以 INSTRUCTION statement 形式,就是命令+ 清单的模式。命令要大写,"#"是注解
FROM 命令是告诉docker 我们的镜像什么
MAINTAINER 是描述 镜像的创建人
RUN 命令是在镜像内部执行。就是说他后面的命令应该是针对镜像可以运行的命令
#### 4.创建镜像
命令:
```shell
docker build -t xingdian/sinatra:v2 .
```
docker build 是docker创建镜像的命令
-t 是标识新建的镜像
sinatra是仓库的名称
:v2 是tag
"."是用来指明 我们的使用的Dockerfile文件当前目录
详细执行过程:
```shell
[root@master sinatra]# docker build -t xingdian/sinatra:v2 .
Sending build context to Docker daemon 2.048 kB
Step 1 : FROM daocloud.io/ubuntu:14.04
Trying to pull repository daocloud.io/ubuntu ...
14.04: Pulling from daocloud.io/ubuntu
f3ead5e8856b: Pull complete
Digest: sha256:ea2b82924b078d9c8b5d3f0db585297a5cd5b9c2f7b60258cdbf9d3b9181d828
---> 2ff3b426bbaa
Step 2 : MAINTAINER xingdian xingdian@localhost.localdomain
---> Running in 948396c9edaa
---> 227da301bad8
Removing intermediate container 948396c9edaa
Step 3 : RUN apt-get update && apt-get install -y ruby ruby-dev
...
Step 4 : RUN gem install sinatra
---> Running in 89234cb493d9
```
#### 5.创建完成后,从镜像创建容器
```shell
[root@xingdian ~]# docker run -t -i xingdian/sinatra:v2 /bin/bash
```
## 三:企业级Dockerfile文件构建容器
#### 1.Dockerfile文件构建nginx
```shell
[root@xingdian ~]# cat 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
```shell
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"]
#cat /run.sh
#!/usr/bin/bash
#2018/10/24
#行癫
cd /opt/redis/src/
./redis-server /opt/redis/conf/redis.conf & #这一个要放在后台运行,不然下面的启动不了
./redis-sentinel /opt/redis/conf/sentinel.conf
```
#### 3.Dockerfile文件构建jenkins
```shell
行癫(亲测)
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"]
```