本文目录一览:
- 1、docker是怎么生成镜像的
- 2、docker怎么将宿主机系统生成镜像
- 3、docker 能将本地环境做成镜像吗
- 4、Docker如何创建镜像
- 5、如何使用docker来制作我现在正在使用的系统的镜像
- 6、docker基础镜像是什么意思
docker是怎么生成镜像的
1.用别人的镜像创建。
1.1、先下载一个容器
命令: docker pull training/sinatra
1.2、然后用容器启动这个镜像
命令:docker run -t -i training/sinatra /bin/bash
1.3、接下来就是给使用中的容器,添加自己需要的工具等,来组装自己的运行环境。
1.4、将上一步组装好的环境copy一份镜像。
命令:
docker commit -m “Added json gem” -a “KateSmith” \
0b2616b0e5a8 ouruser/sinatra:v2
说明:此处命令和git的命令svn的命令有些类似。 docker commit 是提交的意思,类似告诉svn服务器我要生成一个新的版本。
-m 就是添加注释,-a是作者。
“\” 后面跟的是 1.2的容器环境id 要生成的镜像的名称
容器的id:就是你每次输入命令行@后面的字符
例如:root@0b2616b0e5a8
镜像名称:hub的名称/镜像名称:tag
1.5、docker images命令查看自己创建的镜像。
1.6、使用新建立的镜像
命令:docker run -t -i 要生成的镜像的名称 /bin/bash
docker怎么将宿主机系统生成镜像
初次安装部署好docker后,大多数镜像可以从DockerHub 提取,但是大多数人都希望自己可以完全自定义一个镜像,那么这里需要一个第三方工具 febootstrap
epel6的源提供febootstrap的RPM包
yum install docker-io febootstrap -y
service docker start
chkconfig docker --level35 on
复制代码
制作CentOS6.6镜像目录
febootstrap -i yum -i iputils -i iproute -i bash -i vim-minimal -i coreutils -i tar -i net-tools centos6 base a href="" target="_blank";/a -u a href="" target="_blank";/a
复制代码
-i 表示镜像里面安装的RPM包(包括一些人为有必要的软件包)
centos6 表示镜像的版本说明
base 表示生成的镜像目录
后面之后了系统安装源和更新源为USTC
安装执行后,会开始一系列的RPM包下载安装,过程与yum类似,安装完成后当前目录会多了base目录,里面就是一个镜像的系统文件
进入base目录等于进入镜像的根目录
[root@image ~]# cd base/
[root@image base]# ls
bin boot dev etc home lib lib64 media mnt opt proc root sbin selinux srv sys tmp usr var
复制代码
可以像一般的系统文件一样先做一些修改配置,例如配置第三方yum源等等
把base目录把所有文件打包成二进制文件后导入docker创建为镜像
cd ~/root/base/ tar -c . | docker import - centos6:base
复制代码
docker images 可以查看镜像的信息
一个基本centos镜像创建完毕,下面再利用Dokcerfile制作mysql镜像
cat Dockerfile
FROM centos6:base
MAINTAINER Lion "lioncui@163.com"
VOLUME /var/lib/mysql
RUN yum install mysql-server mysql -y
RUN echo -ne "NETWORKING=yes\\nHOSTNAME=mysql" /etc/sysconfig/network
RUN echo -ne "bind-address = 0.0.0.0\\ndefault-storage-engine=innodb\\ninnodb_file_per_table\\n\
collation-server=utf8_general_ci\\ninit-connect='SET NAMES utf8'\\ncharacter-set-server = utf8" insert
RUN sed -i "/user=mysql/r insert" /etc/my.cnf rm -f insert
RUN echo -ne "/usr/bin/mysql_install_db\\n/usr/bin/mysqld_safe" /opt/mysql_start
RUN chmod 777 /opt/mysql_start
ENV PATH /usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:
WORKDIR /opt
EXPOSE 3306
CMD /bin/sh -c mysql_start
复制代码
FROM 声明以centos:base镜像为基础
MAINTAINER 声明镜像的维护者信息
VOLUME 挂载本地目录到容器里/var/lib/mysql目录(这是mysql默认的数据保存目录)
由于我希望数据可以持久化防止因为容器误删除而丢失,所以映射到宿主本地目录
RUN 在镜像中执行安装mysql
在新镜像中写入HOSTNAME信息,因为mysql启动过程需要network文件
在my.cnf配置文件插入一些修改配置
创建启动脚本
声明环境变量
制定默认工作目录
EXPOSE 声明容器需要暴露的端口号
CMD 是指镜像生成容器后自动执行的命令,类似docker exec,这里是自动启动mysql服务
根据Dockerfile创建mysql服务镜像
docker build --rm=true -t mysql:frist .
查看镜像的树状关系可以发现,mysql:frist是以centos:base为父镜像
docker 能将本地环境做成镜像吗
当想让一个容器做两件事情,或者使一个Docker镜像包含来自两个不同镜像的依赖库时,就需要知道每个镜像的Dockerfile。本文介绍了如何通过docker history命令来对Docker镜像进行反向工程,得到它们的Dockerfile,并组织到一个Dockerfile里然后build,从而实现想做的事情。
常言道,“不要重复发明轮子!”
在使用Docker时,构建自己的镜像之前,最好在Docker Hub寻找一些可以直接使用的镜像做练习。把软件架构分布到一系列容器中,每一个容器只做一件事情,这样的效果非常好。构建分布式应用的最好的基石是使用来自Docker Hub的官方镜像,因为可以信任它们的质量。
在某些情况下,可能想让一个容器做两件不同的事情。而在另外一些情况下,可能想让一个Docker镜像包含来自两个不同镜像的依赖库。如果有每个镜像的Dockerfile,这是非常简单的。将它们组织到一个Dockerfile里然后build就行。
然而,大多数时间都在使用Docker Hub上准备好的镜像,不会有它们的源Dockerfile。我花时间找一个可以合并(或flatten)两个不同Docker镜像的工具,当然没有它们的Dockerfile。也就是说在找一个能做下面这件事的东西:
image 1 --
\
--- merged_image_12
/
image 2 --
此前在GitHub上有两个相关的讨论(1、2),尽管它们都被关闭了。
这可能吗?
那么,是否存在工具能够像这样做吗:docker merge image2 image2 merged_image?
没有!
你甚至不可以用下面的方式来构建Dockerfile:
FROM image1
FROM image2
简而言之,在一个Dockerfile里不能有多个基础镜像。
但是我需要这个功能!
唯一的解决办法是取得这些镜像的Dockerfile,然后把它们组织到一个文件中,再进行构建。那么,我能在Docker Hub上获得一个镜像的Dockerfile吗? 幸运的是可以。它不能离线获取(译注:原文是online,但显然online时对于来自GitHub的自动构建镜像是可以直接获取的),但是你可以使用docker history命令,通过反向工程获取。
怎么来使用?
在你的机器上使用docker pull从Docker Hub下载镜像。
docker pull image1
docker pull image2
然后使用docker history来取得构建这两个容器时运行的命令。
docker history --no-trunc=true image image1-dockerfile
docker history --no-trunc=true image2 image2-dockerfile
接下来打开这两个文件,你可以看到每个镜像的命令堆栈。这是因为Docker镜像通过层(阅读更多)的方式来构建。即你在Dockerfile中键入的每一个命令所构建的新镜像,都是在之前的命令产生的镜像之上。所以你可以对镜像进行逆向工程。
限制
不能对镜像进行反向工程的唯一场景,是镜像的维护者在他的Dockerfile中使用了ADD或COPY命令。你会看到这样一行:
ADD file:1ac56373f7983caf22
或 ADD dir:cf6fe659e9d21535844
这是因为不知道维护者在他自己的机器上,包括镜像里使用了什么本地文件。
-
Docker如何创建镜像
如何通过dockerhistory命令来对docker镜像进行反向工程推测它们的Dockerfile,从而在对不同的Docker镜像反向工程获取Dockerfile之后合并成一个。常言道,“不要重复发明轮子!”在使用docker时,最好在构建你自己的镜像前上DockerHub寻找一些直接可以用的。把你的软件架构分布到一系列容器中,每一个容器只做一件事情是非常有用的。构建分布式应用的最好的基石是使用来自DockerHub的官方镜像,因为你可以信任它们的质量。在某些情况下,你可能想让一个容器做两件不同的事情。在另一些情况下,你可能想让一个Docker镜像包含来自两个不同镜像的依赖。如果你有每个镜像的Dockerfile,这是非常简单的。将它们组织到一个Dockerfile里然后build即可。但是,如果大多数时间你都在使用DockerHub上准备好的镜像,你将没有它们的源Dockerfile。我花了一些时间来找这样一个工具,它可以合并(或flatten)两个不同的我没有它们的Dockerfile的Docker镜像。即我在找一个能做下面这件事的东西:image1--\---merged_image_12/image2--尽管这个问题在之前的两个进程中被关闭了(1,2),当你想这么做时,这个问题仍然会产生。
如何使用docker来制作我现在正在使用的系统的镜像
在使用Docker的过程中,我们除了从Docker Hub上下载已经做好的镜像,很多时候需要我们自己制作镜像。下面想在这个文章中说明一下镜像的制作方法。
制作镜像的方式主要有两种:
通过docker commit 制作镜像
通过docker build 制作镜像
这两种方式都是通过改进已有的镜像来达到自己的目的。制作基础镜像,会在另外一篇文章“从零开始制作基础镜像”中介绍。
docker commit
docker commit 是往版本控制系统里提交一次变更。使用这种方式制作镜像,本质上是运行一个基础镜像,然后在基础镜像上进行软件安装和修改。最后再将改动提交到版本系统中。
选择基础镜像
基础镜像的选择要结合自己的需求。可以选择已有的应用镜像来改造,也可以选择Ubuntu,Debian,OpenSuse这类基础系统镜像
我们以ubuntu为例子来说明
步骤1:运行ubuntu 镜像
docker run -i -t ubuntu /bin/bash
步骤2:安装软件并修改软件配置, 比如:安装apache2
apt-get -yqq update
apt-get -y install apache2
安装完成后,对apache2进行配置和修改
步骤3:退出docker并保存镜像
使用“exit”命令退出容器
运行docker comit 命令, 进行保存
docker commit 61412230ae46 own-apache2
docker commit 命令参数说明
命令格式
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
OPTIONS:
-a, --author= 提交的镜像作者
-c, --change=[] Apply Dockerfile instruction to the created image, 没用过
-m, --message= 提交时的说明文字
-p, --pause=true 在commit时,将container 暂停
CONTAINER:
可以使用container 的名字或者ID
REPOSITORY
指定镜像仓库,上述例子中,指定的是本地存储
可以指定远程镜像仓库,如docker hub。也可自建仓库来存放image
TAG:
镜像TAG
docker build
使用docker build创建镜像需要编写Dockerfile.
步骤:
编写自己的Dcokerfile
运行docker build 命令打包镜像
仍然以apache打包为例子。以下是Dockerfile的例子
FROM ubuntu:latest
MAINTAINER sky
#Add 163 mirror for apt
ADD sources.list /etc/apt/sources.listADD .bashrc /root/.bashrcENV DEBIAN_FRONTEND noninteractive# PackagesRUN rm -rf /var/lib/apt/listsRUN apt-get update -q --fix-missingRUN apt-get -y upgrade#ubuntu wwwRUN apt-get install -y apache2 curl libapache2-mod-php5 php5-curl php5-gd php5-mysql rsync mysql-client -qqRUN apt-get autocleanRUN rm -rf /var/lib/apt/lists/*# Setup environmnt for apache's init scriptENV APACHE_CONFDIR /etc/apache2ENV APACHE_ENVVARS $APACHE_CONFDIR/envvarsENV APACHE_RUN_USER www-dataENV APACHE_RUN_GROUP www-dataENV APACHE_RUN_DIR /var/run/apache2ENV APACHE_PID_FILE $APACHE_RUN_DIR/apache2.pidENV APACHE_LOCK_DIR /var/lock/apache2ENV APACHE_LOG_DIR /var/log/apache2ENV LANG CRUN mkdir -p $APACHE_RUN_DIR $APACHE_LOCK_DIR $APACHE_LOG_DIRRUN find "$APACHE_CONFDIR" -type f -exec sed -ri ' \ s!^(\s*CustomLog)\s+\S+!\1 /proc/self/fd/1!g; \ s!^(\s*ErrorLog)\s+\S+!\1 /proc/self/fd/2!g; \' '{}' ';'EXPOSE 80CMD ["apache2", "-DFOREGROUND"]
编辑完成后,在与Dockerfile同一目录下运行docker build 命令
docker build -t apache-img .
如果没有命令出错,docker build会持续运行直到镜像创建完成
而创建的过程本质上是运行一个镜像,然后在镜像中按序执行在Dockerfile中的命令,直到执行结束。
如果中间有命令执行失败,镜像创建会停止。这时就需要看log,并修改Dockerfile,然后再次执行docker build
注:两种镜像创建方式的对比:
docker commit
docker build
难度相对容易,适合新手和对Linux不熟悉的用户相对难,要求有一定的linux和脚本基础知识
文档化
文档化在通过其他文件来实现
Dockerfile本身就是比较好的文档,可读和可理解性比较强。也可配合其他文档带来详细说明
升级,维护
后续升级和维护麻烦,需要再次运行镜像并对内部软件进行升级或者安装新软件增加特性
后续升级和维护会相对简单,可以直接在dockerfile中更改并增加新特性
具体选择哪种方式来制作镜像需要结合实际情况来选择
Dockerfile 关键字详解
FROM
FROM用来指定基础包。在上面的例子中,基础包用的是ubuntu。
MAINTAINER
镜像作者信息,或者维护人员信息
ADD
将文件拷贝到Container内文件系统对应的路径
格式 ADD src file dst file
所有拷贝到Container中的文件和文件夹权限为0755,uid和gid为0
如果需要修改owner用户或者权限,需要使用RUN进行修改
ADD文件,文件路径要在docker buildPATH中指定的PATH下
RUN
创建镜像时执行
ENV
用来设置环境变量
EXPOSE
Container内部服务开启的端口
主机上如果要使用,还需要在启动Container时,做host-container的商品映射
使用EXPOSE后,一些自动化布署工具可以直接读取这个信息,自动进行端口映射
EXPOSE可以有多条,指定多个端口
WORKDIR
切换工作目录,可进行多次切换(相当于cd命令)
切换目录对RUN,CMD,ENTRYPOINT有效
USER
执行container的用户,如未指定,则默认使用root用户
ENTRYPOINT
Container启动时执行的命令,一个Dockerfile中只能有一条ENTRYPOINT
ENTRYPOINT没有CMD的可替换特性
CMD
Container 启动时执行的命令,一个Dockerfile 中只能有一条CMD命令,如果有多条则只执行最后一条CMD
如果有多条命令希望在启动后执行,可以考虑使用shell 脚本
与ENTRYPOINT的区别
CMD的主要用途是为可执行的container提供默认命令
CMD在运行时是可替换的,比如
在ubuntu中,CMD指定的是/bin/bash。默认情况下运行ubuntu,container中的/bin/bash会被执行
如果使用docker run指定运行命令,那CMD会被替换掉
如:docker run ubuntu /bin/echo "this is a echo". 这时,container 启动后会执行echo 而不是/bin/bash了
ENTRYPOINT是不会替换的,如果在ubuntu镜像中加入ENTRYPOINT,那ENTRYPOINT在启动后会先被执行
CMD可以为ENTRYPOINT来提供参数
例子:
FROM ubuntu:14.10
ENTRYPOINT ["top", "-b"]
CMD ["-c"]
VOLUME
语法:VOLUME [PATH]
VOLUME指令用来设置一个挂载点,可以用来让其他容器挂载以实现数据共享或对容器数据的备份、恢复或迁移
可以将本地文件夹或者其他Container的文件夹挂载到Container中
docker基础镜像是什么意思
镜像是 Docker 运行容器的前提,Docker 镜像可以看作是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。
对于docker镜像,官方的定义如下: An image is a read-only template with instructions for creating a Docker container. Often, an image is based on another image, with some additional customization. For example, you may build an image which is based on the ubuntu image, but installs the Apache web server and your application, as well as the configuration details needed to make your application run.‘ 映像是一个只读模板,带有创建Docker容器的指令。通常,一个映像是基于另一个映像的,还需要进行一些额外的定制。例如,您可以构建一个基于ubuntu映像的映像,但是安装Apache web服务器和您的应用程序,以及使您的应用程序运行所需的配置细节。