Docker之從零開始制作docker鏡像


以前學習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是shell的一個命令,因為shell的執行的過程中,如果有某個出錯了,也會繼續往下執行, set -ex作用就是,當下面的命令執行出錯后,就退出執行,不在繼續往下執行。
2.Dockerfile 的 ADD 和 COPY 的區別:
ADD 可以實現從遠程的某個指定的url上下載文件,然后添加到容器的系統文件目錄中。
ADD可以將本地可識別的壓縮文件解壓到容器的指定路徑上(但是URL下載和解壓不能同時進行,任何通過遠程URL下載的壓縮文件,都只能拷貝到容器中,不會自動解壓)
COPY它是 ADD的一個簡化版本,它只會復制文件到容器中
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM