Docker之从零开始制作docker镜像

Posted yuhuang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 
    && echoexit 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 
    && echoDir::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文件)

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的一个简化版本,它只会复制文件到容器中

以上是关于Docker之从零开始制作docker镜像的主要内容,如果未能解决你的问题,请参考以下文章

Docker 运维 - 从零开始学习

Docker 运维 - 从零开始学习

云原生 | 从零开始学Docker六如何写出自己的镜像——Docker file

docker教程之从一头雾水到不一头雾水

手把手·从零开始撸Docker 系列一

从零开始构建一个centos+jdk7+tomcat7的docker镜像文件