以前學習docker是直接docker pull命令直接拉取Linux中已有鏡像,並創建容器,添加應用程序,但是docker鏡像一開始是怎么來的呢?下面將從零開始介紹整個docker鏡像的制作過程(初始鏡像以Ubuntu16.04為例)。
一、制作ubuntu的基礎鏡像
方法一:
(1)拉取Docker中的ubuntu鏡像,docker pull ubuntu:16.04;
(2)創建Docker容器,docker run --priviledge --name=huangyu --net=host -it unbuntu:16.04
(3)將pull下來的鏡像提交到本地,docker commit <容器ID> <鏡像名稱>:<Tag>
由於公司使用內網工作,使用docker pull命令失敗,下面將介紹另一種通用方式
方法二:
(1)下載Ubuntun16.04初始鏡像ubuntu-xenial-core-cloudimg-amd64-root.tar.gz到服務器Z:/mydocker中。
下載地址:http://cloud-images.ubuntu.com/minimal/releases/xenial/release/
鏡像文件下載地址為:https://github.com/tianon/docker-brew-ubuntu-core/blob/857debd4347496c541f9806c084710dace49cd27/xenial/Dockerfile
(2)創建初始ubuntu鏡像
a.切換到mydocker目錄 cd mydocker
b.將ubuntu-xenial-core-cloudimg-amd64-root.tar.gz拷貝至mydocker目錄下,解壓 tar -zxvf ubuntu-xenial-core-cloudimg-amd64-root.tar.gz
c.因公司屏蔽外網源,這里需要修改apt-get為公司的源,找到/etc/apt/sources.list文件並更新為公司的源
d.創建Dockerfile文件,注意文件名只能為Dockerfile,使用命令touch Dockerfile;(這里與Dockfile相關的知識會在下一篇博文中介紹)
FROM scratch ADD ubuntu-xenial-core-cloudimg-amd64-root / # a few minor docker-specific tweaks # see https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap RUN set -xe \ \ # https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L40-L48 && echo '#!/bin/sh' > /usr/sbin/policy-rc.d \ && echo 'exit 101' >> /usr/sbin/policy-rc.d \ && chmod +x /usr/sbin/policy-rc.d \ \ # https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L54-L56 && dpkg-divert --local --rename --add /sbin/initctl \ && cp -a /usr/sbin/policy-rc.d /sbin/initctl \ && sed -i 's/^exit.*/exit 0/' /sbin/initctl \ \ # https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L71-L78 && echo 'force-unsafe-io' > /etc/dpkg/dpkg.cfg.d/docker-apt-speedup \ \ # https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L85-L105 && echo 'DPkg::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; };' > /etc/apt/apt.conf.d/docker-clean \ && echo 'APT::Update::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; };' >> /etc/apt/apt.conf.d/docker-clean \ && echo 'Dir::Cache::pkgcache ""; Dir::Cache::srcpkgcache "";' >> /etc/apt/apt.conf.d/docker-clean \ \ # https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L109-L115 && echo 'Acquire::Languages "none";' > /etc/apt/apt.conf.d/docker-no-languages \ \ # https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L118-L130 && echo 'Acquire::GzipIndexes "true"; Acquire::CompressionTypes::Order:: "gz";' > /etc/apt/apt.conf.d/docker-gzip-indexes \ \ # https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L134-L151 && echo 'Apt::AutoRemove::SuggestsImportant "false";' > /etc/apt/apt.conf.d/docker-autoremove-suggests # delete all the apt list files since they're big and get stale quickly RUN rm -rf /var/lib/apt/lists/* # this forces "apt-get update" in dependent images, which is also good # enable the universe RUN sed -i 's/^#\s*\(deb.*universe\)$/\1/g' /etc/apt/sources.list # make systemd-detect-virt return "docker" # See: https://github.com/systemd/systemd/blob/aa0c34279ee40bce2f9681b496922dedbadfca19/src/basic/virt.c#L434 RUN mkdir -p /run/systemd && echo 'docker' > /run/systemd/container # overwrite this with 'CMD []' in a dependent Dockerfile CMD ["/bin/bash"]
e.創建docker鏡像 docker build -t un:un .(注意這里的.代表會在當前目錄下自動尋找Dockerfile文件)
. 表示上下文路徑,是指docker在構建鏡像,有時候想要使用到本機的文件(比如復制),docker build命令得知這個路徑后,會將路徑下的所有內容打包。
d.因公司屏蔽外網源,這里需要修改apt-get為公司的源,具體步驟如下
(1)創建容器,docker run --privileged --name=huangyu --net=host -v ~:share ubuntu:16:04
(2)下載vim,apt install vim
(3)修改源文件,vim /etc/apt/sources.list后保存
(4)Crtl+D退出docker,docke ps -a|grep huangyu 查看容器ID
(5)推送新鏡像,docker commit -a "huangyu" -m "ubuntu" ID un:un
f.以un:un鏡像為基礎,創建unbuntu+python3的鏡像;
(1)進入mydocker目錄,cd mydocker
(2)創建新文件夾,mkdir pythonfile
(3)下載python的tar.xz文件,並拷貝至pythonfile文件夾下
(4)切換至pythonfile目錄下並創建新文件,cd pythonfile, touch Dockerfile
From un:un
ADD Python-3.7.6.tar.xz /
#卸載並且刪除python相關配置
RUN apt-get purge -y python.*
#第一個RUN解決apt源更新失敗問題
RUN set -ex \
&& chmod 777 /tmp \
&& rm -rf /var/lib/apt/lists/* \
&& apt-get clean \
&& apt-get autoremove \
&& apt-get autoclean \
#&& apt-get update --allow-unauthenticated\
&& apt-get update \
&& apt-get install -y build-essential checkinstall libssl-dev libreadline-dev libffi-dev libsqlite3-dev tk-dev libgdbm-dev libbz2-dev libncurses5-dev liblzma-dev uuid-dev
RUN set -ex \
#&& wget https://www.python.org/ftp/python/3.7.6/Python-3.7.6.tgz \ (內網下載很慢,需要先在下載)
#&& tar -xf Python-3.7.6.tar.xz \
&& cd Python-3.7.6 \
#編譯
&& ./configure prefix=/usr/local/python3 \
#安裝
&& make \
&& make install \
#清除make命令產生的object文件(后綴為".o"的文件)及可執行文件
&& make clean \
&& cd .. \
&& rm -rf /Python-3.7.6* \
#&& apt install -y epel-release \
&& apt install -y python-pip
CMD ["hello.py"]
(5)創建docker鏡像 docker build -t ubuntu:python .
(6)使用docker images,查看有無ubuntu:python的鏡像
需要注意的幾點
1.RUN set -ex \
的作用
set -ex
作用就是,當下面的命令執行出錯后,就退出執行,不在繼續往下執行。
ADD
和
COPY
的區別:
ADD
可以實現從遠程的某個指定的url上下載文件,然后添加到容器的系統文件目錄中。
ADD
可以將本地可識別的壓縮文件解壓到容器的指定路徑上(但是URL下載和解壓不能同時進行,任何通過遠程URL下載的壓縮文件,都只能拷貝到容器中,不會自動解壓)
ADD
的一個簡化版本,它只會復制文件到容器中