未加星标

从零开始构建docker基础镜像的方法

字体大小 | |
[运维安全 所属分类 运维安全 | 发布者 店小二05 | 时间 | 作者 红领巾 ] 0人收藏点击收藏

段子

今年基本已经结束了,我问了很多朋友今年挣钱了没?大多朋友都有挣,而且挣得五花八门:有挣个屁的,有挣个锤子的,有挣个毛的,更有甚者挣个妹的,奢侈之极!最恐怖的是挣个鬼的!有的还可以,挣个球,下午我碰见一朋友,问今年挣了吗?他望着天空喃喃自语:挣个鸟!看吧,只要肯努力,什么都能挣到。

年末将至,忽然发现,从创建开始到现在,整整一年时间,没有写过多少东西。为了留下一点痕迹,也是为了整理一下自己的收获,为17年画上一笔浓郁的色彩。

最近在看一本入门级机器学习的书,里面的案例基本上是python实现的,所以想搭建python相关的环境,然后又想偷懒,有一个运行环境,可以轻松安装和编写使用,也可以在其他地方使用,编写工具首选jupyter notebook,当然,在大多数的书中也是比较推荐这个工具,自己之前也使用过,觉得不错。还有个问题就是想在其他地方使用python环境和这个工具,不需要重复安装,此刻,我想到的是docker。之前对docker只是简单的理解,为此,特意学习了一下docker,现做分享。

从零开始构建docker基础镜像的方法

上图就是docker的图标,这个图标对docker的含义阐释的还是比较全面:小鲸鱼代表的是船,船上的就是集装箱,所有的东西不管是什么,只要装在集装箱中,就可以方便的运输。docker公司的口号是Build,Ship,and Run Any App,Anywhere。docker的本意是码头工人,而在这里说是集装箱的话,比较贴切。所有需要运行的环境和程序,装入docker,然后需要运行的时候,就运行这个特定的docker容器,提供特定的服务。

docker的通俗解析:点击这里

刚开始的时候,搞不清楚docker和虚拟机有什么区别,总感觉docker能干的事虚拟机也能,并且在使用的时候,总按照虚拟机的操作思路去做。那docker为什么会出现?

我在docker的官方网站找到了两张关于虚拟机和容器的区别:

容器 VS 虚拟机

从零开始构建docker基础镜像的方法
从零开始构建docker基础镜像的方法

容器和虚拟机具有相似的资源隔离和分配优势,但功能有所不同,因为容器虚拟化的是操作系统,而不是硬件,因此容器更容易移植,效率也更高。

关于容器:点击这里

对于docker做了简单的了解之后,就需要实际去体验一下安装和构建容器,本例使用centos6.5:

1.安装docker相关软件

[[email protected] ubuntu-16.04]# rpm -ivh http://dl.Fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
Retrieving http://dl.Fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
warning: /var/tmp/rpm-tmp.KYucBm: Header V3 RSA/SHA256 Signature, key ID 0608b895: NOKEY
Preparing... ########################################### [100%]
1:epel-release ########################################### [100%]
[[email protected] ubuntu-16.04]# yum -y install docker-io
Loaded plugins: fastestmirror, refresh-packagekit, security
Loading mirror speeds from cached hostfile
...
Complete!
[[email protected] ubuntu-16.04]# service docker start
Starting cgconfig service: [ OK ]
Starting docker: [ OK ]
[[email protected] ubuntu-16.04]# chkconfig docker on
[[email protected] ubuntu-16.04]#

使用service docker status查看docker服务状态的时候,发现没有启动docker dead but pid file exists,执行docker相关命令(如docker ps)的时候会出现Cannot connect to the Docker daemon. Is 'docker -d' running on this host?,需要解决这个问题,如下:

[[email protected] ubuntu-16.04]# service docker status
docker dead but pid file exists
[[email protected] ubuntu-16.04]#yum-config-manager --enable public_ol6_latest
Loaded plugins: fastestmirror, refresh-packagekit
[[email protected] ubuntu-16.04]# yum install -y device-mapper-event-libs
Loaded plugins: fastestmirror, refresh-packagekit, security
...

2.构建基础镜像

在使用docker的时候后,可以通过命令docker pull <镜像名称>从镜像库中获取,但是有时候会出现网络问题或是其他原因,导致无法拉取,在docker中国官网介绍使用通过 Docker 官方镜像加速来解决无法拉取:

您可以使用以下命令直接从该镜像加速地址进行拉取:

$ docker pull registry.docker-cn.com/myname/myrepo:mytag

例如:

$ docker pull registry.docker-cn.com/library/ubuntu:16.04

原文如下:点击这里

而在本文中,我使用Dockerfile来构建基础镜像ubuntu 16.04(xenial),其对应的Dockerfile的Github地址为:点击这里,搜索方式为在hub.docker.com中搜索ubuntu,即可看见对应的镜像信息。Dockerfile内容如下:

FROM scratch
ADD ubuntu-xenial-core-cloudimg-amd64-root.tar.gz /
# 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"]

现在对Dockerfile中的相关命令解释一下:

FROM 指的是依赖的基础镜像,如scratch表示的是空白的,从零开始的。依赖的镜像可以是本地的,也可以是远程库的
ADD 指的是添加本地文件到镜像中,如果遇到linux可解压格式文件,会自动解压,这就是为什么整个文件中没有对tar.gz进行显式解压
RUN 运行命令,如安装软件的相关命令
CMD 设置启动Container时默认执行的命令,这个可以在启动容器时覆盖

目前,这个Dockerfile中涉及的命令就这几个,其他等以后遇到再进行说明。解释完毕,开始构建:

[[email protected] ubuntu-16.04]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[[email protected] ubuntu-16.04]# docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
[[email protected] ubuntu-16.04]# pwd
/home/ml/ubuntu-16.04
[[email protected] ubuntu-16.04]# ll -h
total 40M
-rw-rw-r--. 1 ml ml 2.8K Dec 19 12:37 Dockerfile
-rw-rw-r--. 1 ml ml 40M Dec 19 12:39 ubuntu-xenial-core-cloudimg-amd64-root.tar.gz
[[email protected] ubuntu-16.04]#
[[email protected] ubuntu-16.04]# docker build -t ubuntu:16.04 .
Sending build context to Docker daemon 41.94 MB
Sending build context to Docker daemon
Step 0 : FROM scratch
--->
Step 1 : ADD ubuntu-xenial-core-cloudimg-amd64-root.tar.gz /
---> 537c2f6dd023
Removing intermediate container dee7679a7ee2
Step 2 : RUN set -xe && echo '#!/bin/sh' > /usr/sbin/policy-rc.d && \
echo 'exit 101' >> /usr/sbin/policy-rc.d && chmod +x /usr/sbin/policy-rc.d && \
dpkg-divert --local --rename --add /sbin/initctl && cp -a /usr/sbin/policy-rc.d /sbin/initctl && sed -i 's/^exit.*/exit 0/' /sbin/initctl && \
...---> Running in 41d719b68981
+ echo #!/bin/sh
+ echo exit 101
+ chmod +x /usr/sbin/policy-rc.d
+ dpkg-divert --local --rename --add /sbin/initctl
Adding 'local diversion of /sbin/initctl to /sbin/initctl.distrib'
+ cp -a /usr/sbin/policy-rc.d /sbin/initctl
+ sed -i s/^exit.*/exit 0/ /sbin/initctl
+ echo force-unsafe-io
+ echo DPkg::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; };
+ echo APT::Update::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; };
+ echo Dir::Cache::pkgcache ""; Dir::Cache::srcpkgcache "";
+ echo Acquire::Languages "none";
+ echo Acquire::GzipIndexes "true"; Acquire::CompressionTypes::Order:: "gz";
+ echo Apt::AutoRemove::SuggestsImportant "false";
---> c49bdbf61888
Removing intermediate container 41d719b68981
Step 3 : RUN rm -rf /var/lib/apt/lists/*
---> Running in 6389964016a2
---> 4508181f7442
Removing intermediate container 6389964016a2
Step 4 : RUN sed -i 's/^#\s*\(deb.*universe\)$/\1/g' /etc/apt/sources.list
---> Running in cbed2b28c988
---> 8eed06df8f19
Removing intermediate container cbed2b28c988
Step 5 : RUN mkdir -p /run/systemd && echo 'docker' > /run/systemd/container
---> Running in aff40dbc6e05
---> 19c96e7912a4
Removing intermediate container aff40dbc6e05
Step 6 : CMD /bin/bash
---> Running in 2469ee9d7251
---> 77e565a65647
Removing intermediate container 2469ee9d7251
Successfully built 77e565a65647
[[email protected] ubuntu-16.04]# docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
ubuntu 16.04 77e565a65647 33 seconds ago 110.5 MB
[[email protected] ubuntu-16.04]#

从构建日志可以看出,每条命令为一个step,执行完成之后会产生一个id,类似于6389964016a2,其实,这就是镜像的分层,一层层堆积在一起。

到此,一个ubuntu16.04版的docker镜像构建完成,那么接下来就是运行

3.运行镜像

使用docker run命令运行:

[[email protected] ubuntu-16.04]# docker run -it ubuntu:16.04
[email protected]:/# cat /etc/issue
Ubuntu 16.04.3 LTS \n \l
[email protected]:/# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 22:47 ? 00:00:00 /bin/bash
root 11 1 0 22:47 ? 00:00:00 ps -ef
[email protected]:/#

其中5ea0b95e8641为当前容器的ID,进入容器查看所有进程,pid为1的时bash,linux不应该时init吗?其实,这就是容器与虚拟机的差别,容器的init进程就是主机上docker服务进程,每个容器只是一个进程而已。其中的参数-it指的是前端打开并分配一个终端,-d为在后台运行,我们试试当前这个可不可以使用-d:

[[email protected] ~]# docker run -d ubuntu:16.04
43ae7ded8e6920b55b8e744b52ffce37b89b25182fcacdc10a5414e6621abff3
[[email protected] ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[[email protected] ~]# docker run -d ubuntu:16.04 /bin/bash
77f3ec2ebfb3f154772683eeea8ca7e2ba3b7756b1488f5f09818af424e0298e
[[email protected] ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

可以明显的开出来,使用-d后,docker ps查不到任何运行的容器,如果使用-it的话,在别的shell下使用docker ps查看:

[[email protected] ml]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8341a332c788 ubuntu:16.04 "/bin/bash" 18 seconds ago Up 18 seconds drunk_cori

可以看到,有容器在运行,因为我们没有退出。由此可以看出,容器其实以进程方式运行,执行完成/bin/bash之后,进程消亡,所以容器也就不存在,如果容器里面是一个tomcat服务,则是另外一种情况了。

基础镜像基本构建完成,后面的环境搭建,都将基于这个镜像构建。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。


您可能感兴趣的文章:详解docker国内镜像拉取和镜像加速registry-mirrors配置修改详解如何修改docker pull镜像源Docker中镜像构建文件Dockerfile与相关命令的详细介绍Docker常用的清除容器镜像命令小结如何给Docker配置官方国内加速镜像Docker创建镜像两种方法详解Docker创建镜像、怎么修改、上传镜像等详细介绍Docker push镜像失败解决方法简单谈谈Docker镜像的使用方法

本文运维安全相关术语:linux服务器代维 linux服务器搭建 运维管理 运维工程师 企业安全文章 企业安全管理 cf安全系统检测到游戏数据异常

主题: DockerUbuntu虚拟化Git其实UA集装RYTIHead
tags: docker,apt,gt,ubuntu,root,bogon,echo,sbin,镜像,var,bin,容器,cache
分页:12
转载请注明
本文标题:从零开始构建docker基础镜像的方法
本站链接:http://www.codesec.net/view/573597.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 运维安全 | 评论(0) | 阅读(219)