docker 镜像制作
基于已有的容器制作镜像:
~$ docker commit 1a297846df5b runsisi:hust
sha256:2c7b5d9d87c755179a003a90aecbd94539151921efbf9af6846cc701677fee9f
~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
runsisi hust 2c7b5d9d87c7 4 seconds ago 201 MB
ubuntu 14.04 f17b6a61de28 2 weeks ago 188 MB
ubuntu trusty-20180420 8cef1fa16c77 7 months ago 223 MB
然后基于制作的新镜像创建容器:
~$ docker run -it runsisi:hust /bin/bash
root@35f682c836e9:/#
此外,基于 Dockerfile 制作容器镜像时一种更为常见的的方式,下面分别以制作 Ubuntu 14.04 和 CentOS 7 两个镜像为例进行说明。
Dockerfile 中的每一个 RUN 命令都会形成一层镜像,因此如果 RUN 命令执行的结果包含临时文件,最好在同一个 RUN 命令中进行清理,否则临时文件会极大的增加镜像的大小(这也是几乎所有的 Dockerfile 都会用 &&
连接所有命令的原因)。
制作 Ubuntu 容器镜像
~$ ls
Dockerfile supervisord.conf
Dockerfile
FROM ubuntu:14.04.3
MAINTAINER runsisi <runsisi@hust.edu.cn>
# Note: The space before semicolon is important in Dockerfile, useless in normal shell script though
# for dpkg-divert, please refer to https://bugs.launchpad.net/ubuntu/+source/systemd/+bug/1325142
# for DEBIAN_FRONTEND, please refer to https://github.com/docker/docker/issues/4032
# for HOME, please refer to https://github.com/docker/docker/issues/2968
RUN dpkg-divert --local --add /etc/init.d/systemd-logind && ln -s /bin/true /etc/init.d/systemd-logind && \
apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y openssh-server supervisor \
language-pack-en language-pack-zh-hans \
lsb-release dpkg-dev debhelper git vim-nox \
sshpass tree lsof tcpdump \
build-essential autoconf automake libtool pkg-config \
python python-argparse python-pip python-virtualenv && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
RUN echo 'root:123456' | chpasswd && \
useradd -m -s '/bin/bash' runsisi && \
echo 'runsisi:123456' | chpasswd && \
echo 'runsisi ALL=(ALL:ALL) NOPASSWD: ALL' > /etc/sudoers.d/runsisi && \
mkdir -p /var/run/sshd /var/log/supervisor && \
sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/g' /etc/ssh/sshd_config && \
sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/g' /etc/ssh/sshd_config && \
sed -i 's/#GSSAPIAuthentication no/GSSAPIAuthentication no/g' /etc/ssh/sshd_config && \
sed -i '$aUseDNS no' /etc/ssh/sshd_config && \
sed -i '$aalias sudo="sudo -E"' /etc/bash.bashrc && \
sed -i '$aalias vi="vim"' /etc/bash.bashrc
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
EXPOSE 22
ENV HOME /home/runsisi
ENV LC_ALL en_US.UTF-8
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/supervisord.conf"]
supervisord.conf
[supervisord]
nodaemon=true
[program:sshd]
command=/usr/sbin/sshd -D
然后在 Dockerfile 所在目录执行 docker build:
~$ docker build --build-arg http_proxy=http://10.120.155.xxx:12345 --build-arg https_proxy=http://10.120.155.xxx:12345 --tag runsisi:xxx .
Sending build context to Docker daemon 4.608 kB
Step 1/9 : FROM ubuntu:14.04.3
---> 3876b81b5a81
Step 2/9 : MAINTAINER runsisi <runsisi@hust.edu.cn>
---> Using cache
---> 15ce53fdd680
Step 3/9 : RUN dpkg-divert --local --add /etc/init.d/systemd-logind && ln -s /bin/true /etc/init.d/systemd-logind && apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y openssh-server supervisor language-pack-en language-pack-zh-hans lsb-release dpkg-dev debhelper git subversion vim-nox sshpass tree lsof tcpdump build-essential autoconf automake libtool pkg-config python python-argparse python-pip python-virtualenv && apt-get clean && rm -rf /var/lib/apt/lists/*
---> Running in b45d4049fa4e
Adding 'local diversion of /etc/init.d/systemd-logind to /etc/init.d/systemd-logind.distrib'
Ign http://archive.ubuntu.com trusty InRelease
Get:1 http://archive.ubuntu.com trusty-updates InRelease [65.9 kB]
Get:2 http://archive.ubuntu.com trusty-security InRelease [65.9 kB]
Hit http://archive.ubuntu.com trusty Release.gpg
Get:3 http://archive.ubuntu.com trusty-updates/main Sources [526 kB]
Get:4 http://archive.ubuntu.com trusty-updates/restricted Sources [6449 B]
...
Step 8/9 : ENV LC_ALL en_US.UTF-8
---> Running in a62caa0125c6
---> 6ce6fce4d584
Removing intermediate container a62caa0125c6
Step 9/9 : CMD /usr/bin/supervisord -c /etc/supervisor/supervisord.conf
---> Running in 42bd3293c888
---> ce9024ce6631
Removing intermediate container 42bd3293c888
Successfully built ce9024ce6631
注意其中 --build-arg
用来指定代理等环境变量,这里的代理和前面为 docker pull 或者 docker run 设置的代理并不一样,这里的代理是构建过程中容器进程使用的代理。
生成的容器镜像如下:
~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
runsisi xxx ce9024ce6631 9 minutes ago 528 MB
...
制作 CentOS 容器镜像
~$ scp <CentOS 7.x host>:/etc/rc.d/init.d/functions .
~$ ls
Dockerfile functions supervisord.conf
Dockerfile
FROM centos:7
MAINTAINER runsisi <runsisi@hust.edu.cn>
RUN rm -f /etc/yum.repos.d/* && \
/bin/bash -c $'cat <<-EOF > /etc/yum.repos.d/hust.repo\n'\
$'[os]\n'\
$'name = os\n'\
$'gpgcheck = 0\n'\
$'baseurl = http://mirrors.hust.edu.cn/centos/7/os/x86_64\n'\
$'\n'\
$'[extras]\n'\
$'name = extras\n'\
$'gpgcheck = 0\n'\
$'baseurl = http://mirrors.hust.edu.cn/centos/7/extras/x86_64\n'\
$'\n'\
$'[updates]\n'\
$'name = updates\n'\
$'gpgcheck = 0\n'\
$'baseurl = http://mirrors.hust.edu.cn/centos/7/updates/x86_64\n'\
$'\n'\
$'[epel]\n'\
$'name = epel\n'\
$'gpgcheck = 0\n'\
$'baseurl = http://mirrors.hust.edu.cn/epel/7/x86_64\n'\
$'EOF' && \
sed -i 's/enabled=1/enabled=0/g' /etc/yum/pluginconf.d/fastestmirror.conf && \
yum install -y redhat-lsb-core sudo deltarpm openssh-server supervisor \
sshpass which tree wget lsof vim-enhanced iproute tcpdump \
git python-pip python-virtualenvwrapper \
gcc-c++ && \
yum clean all && \
rm -f /root/anaconda-ks.cfg && \
rm -f /anaconda-post.log && \
rm -rf /tmp/* && \
mv -f /etc/yum.repos.d/{hust.repo,hust.repo.bak}
RUN sed -i 's/Defaults\s\+requiretty/Defaults !requiretty/g' /etc/sudoers && \
echo 'root:123456' | chpasswd && \
useradd -m -s '/bin/bash' runsisi && \
echo 'runsisi:123456' | chpasswd && \
echo 'runsisi ALL=(ALL:ALL) NOPASSWD: ALL' > /etc/sudoers.d/runsisi && \
sed -i 's/\[ "$PS1" = "\\\\s-\\\\v\\\\\\$ " \] \&\& PS1="\[\\u@\\h \\W\]\\\\$ "/\[ "$PS1" = "\\\\s-\\\\v\\\\\\$ " \] \&\& PS1="\[\\u@\\h \\w\]\\\\$ "/g' /etc/bashrc && \
sed -i 's/#PermitRootLogin yes/PermitRootLogin yes/g' /etc/ssh/sshd_config && \
sed -i 's/GSSAPIAuthentication yes/GSSAPIAuthentication no/g' /etc/ssh/sshd_config && \
sed -i 's/#UseDNS yes/UseDNS no/g' /etc/ssh/sshd_config && \
sed -i '$aalias sudo="sudo -E"' /etc/bashrc && \
sed -i '$aalias vi="vim"' /etc/bashrc && \
mkdir -p /var/run/sshd /var/log/supervisor
COPY supervisord.conf /etc/supervisord.d/supervisord.ini
COPY functions /etc/rc.d/init.d/functions
RUN sshd-keygen
EXPOSE 22
#USER runsisi
#WORKDIR /home/runsisi
ENV HOME /home/runsisi
ENV LC_ALL en_US.UTF-8
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisord.conf"]
supervisord.conf
[supervisord]
nodaemon=true
[program:sshd]
command=/usr/sbin/sshd -D
然后在 Dockerfile 所在目录执行 docker build:
~$ docker build --build-arg http_proxy=http://10.120.155.xxx:12345 --build-arg https_proxy=10.120.155.xxx:12345 --tag runsisi:ccc .
Sending build context to Docker daemon 23.55 kB
Step 1/11 : FROM centos:7
---> 1e1148e4cc2c
Step 2/11 : MAINTAINER runsisi <runsisi@hust.edu.cn>
---> Running in 6058ef2f0ce3
---> 2507d30220fd
Removing intermediate container 6058ef2f0ce3
Step 3/11 : RUN rm -f /etc/yum.repos.d/* && /bin/bash -c $'cat <<-EOF > /etc/yum.repos.d/hust.repo\n'$'[os]\n'$'name = os\n'$'gpgcheck = 0\n'$'baseurl = http://mirrors.hust.edu.cn/centos/7/os/x86_64\n'$'\n'$'[extras]\n'$'name = extras\n'$'gpgcheck = 0\n'$'baseurl = http://mirrors.hust.edu.cn/centos/7/extras/x86_64\n'$'\n'$'[updates]\n'$'name = updates\n'$'gpgcheck = 0\n'$'baseurl = http://mirrors.hust.edu.cn/centos/7/updates/x86_64\n'$'\n'$'[epel]\n'$'name = epel\n'$'gpgcheck = 0\n'$'baseurl = http://mirrors.hust.edu.cn/epel/7/x86_64\n'$'EOF' && sed -i 's/enabled=1/enabled=0/g' /etc/yum/pluginconf.d/fastestmirror.conf && yum install -y redhat-lsb-core sudo deltarpm openssh-server supervisor sshpass which tree wget lsof vim-enhanced iproute tcpdump git python-pip python-virtualenvwrapper gcc-c++ && yum clean all && rm -f /root/anaconda-ks.cfg && rm -f /anaconda-post.log && rm -rf /tmp/* && mv -f /etc/yum.repos.d/{hust.repo,hust.repo.bak}
---> Running in 6cbe4165b12c
Loaded plugins: ovl
Resolving Dependencies
--> Running transaction check
---> Package deltarpm.x86_64 0:3.6-3.el7 will be installed
---> Package gcc-c++.x86_64 0:4.8.5-36.el7 will be installed
--> Processing Dependency: libstdc++-devel = 4.8.5-36.el7 for package: gcc-c++-4.8.5-36.el7.x86_64
...
Step 10/11 : ENV LC_ALL en_US.UTF-8
---> Running in 495e253944f2
---> 866b1069aa97
Removing intermediate container 495e253944f2
Step 11/11 : CMD /usr/bin/supervisord -c /etc/supervisord.conf
---> Running in a7cc86e4e502
---> 1de1d0c5d923
Removing intermediate container a7cc86e4e502
Successfully built 1de1d0c5d923
生成的容器镜像如下:
~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
runsisi ccc 1de1d0c5d923 About a minute ago 400 MB
...
导出、导入容器镜像
当需要在机器之间以离线的方式传递容器镜像时,可以使用如下的方式。
首先在镜像所在的机器进行 docker save,将镜像保存到一个压缩文件:
~$ docker save ubuntu:14.04 | xz -0 > ubuntu14.04.tar.xz
~/docker/14.04.3$ ll -h ubuntu14.04.tar.xz
-rw-rw-r-- 1 runsisi runsisi 52M Dec 17 10:36 ubuntu14.04.tar.xz
然后在需要导入的机器进行 docker load,将镜像从压缩文件中进行加载:
~$ docker load -i ubuntu14.04.tar.xz
Loaded image: ubuntu:14.04
加载得到的镜像如下:
~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
...
ubuntu 14.04 f17b6a61de28 3 weeks ago 188 MB
...
如果导入所在的节点 1)已存在同名(即 name:tag 相同)的镜像,2)镜像的 id 不同,且 3)只有唯一的一个 tag 引用该镜像,则会将原有的镜像重命名为 :,如下所示:
~$ docker load -i ubuntu14.04.tar.xz
The image ubuntu:14.04 already exists, renaming the old one with ID sha256:1de1d0c5d923376fe90179c7db5d1b92a2245aab0e5b21972d9cf39c245135b3 to empty string
Loaded image: ubuntu:14.04
~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 1de1d0c5d923 30 minutes ago 400 MB
...
如果有多个 tag 引用该镜像,则只是简单的删除这个重名的 tag 而已。
最后修改于 2019-09-07