327 lines
11 KiB
Markdown
327 lines
11 KiB
Markdown
<h1><center>Docker镜像构建</center></h1>
|
||
|
||
**作者:行癫(盗版必究)**
|
||
|
||
------
|
||
|
||
## 一:创建自己的镜像
|
||
|
||
#### 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] <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 | -说明
|
||
|
||
给出命令执行的上下文
|
||
|
||
上下文可以是构建执行所在的本地路径,也可以是远程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"]
|
||
```
|