段子

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

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

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

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

  docker的通俗解析:点击这里

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

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

容器 VS 虚拟机

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

  关于容器:点击这里

  

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

1.安装docker相关软件

[root@bogon 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... ########################################### [%]
:epel-release ########################################### [%]
[root@bogon ubuntu-16.04]# yum -y install docker-io
Loaded plugins: fastestmirror, refresh-packagekit, security
Loading mirror speeds from cached hostfile
... Complete!
[root@bogon ubuntu-16.04]# service docker start
Starting cgconfig service: [ OK ]
Starting docker: [ OK ]
[root@bogon ubuntu-16.04]# chkconfig docker on
[root@bogon 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?,需要解决这个问题,如下:

[root@bogon ubuntu-16.04]# service docker status
docker dead but pid file exists
[root@bogon ubuntu-16.04]#yum-config-manager --enable public_ol6_latest
Loaded plugins: fastestmirror, refresh-packagekit
[root@bogon 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中涉及的命令就这几个,其他等以后遇到再进行说明。解释完毕,开始构建:

[root@bogon ubuntu-16.04]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@bogon ubuntu-16.04]# docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
[root@bogon ubuntu-16.04]# pwd
/home/ml/ubuntu-16.04
[root@bogon ubuntu-16.04]# ll -h
total 40M
-rw-rw-r--. ml ml .8K Dec : Dockerfile
-rw-rw-r--. ml ml 40M Dec : ubuntu-xenial-core-cloudimg-amd64-root.tar.gz
[root@bogon ubuntu-16.04]#
[root@bogon 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 : FROM scratch
--->
Step : ADD ubuntu-xenial-core-cloudimg-amd64-root.tar.gz /
---> 537c2f6dd023
Removing intermediate container dee7679a7ee2
Step : 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
+ 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 / /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 : 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
[root@bogon ubuntu-16.04]# docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
ubuntu 16.04 77e565a65647 33 seconds ago 110.5 MB
[root@bogon ubuntu-16.04]#

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

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

3.运行镜像

  使用docker run命令运行:

[root@bogon ubuntu-16.04]# docker run -it ubuntu:16.04
root@5ea0b95e8641:/# cat /etc/issue
Ubuntu 16.04. LTS \n \l root@5ea0b95e8641:/# ps -ef
UID PID PPID C STIME TTY TIME CMD
root : ? :: /bin/bash
root : ? :: ps -ef
root@5ea0b95e8641:/#

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

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

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

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

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

  

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

从零开始构建docker基础镜像的更多相关文章

  1. 中标麒麟龙芯平台--docker基础镜像制作

    Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从Apache2.0协议开源.Docker 的出现为开发人员和运维人员带来了极大的便利.Docker在X86下常见的发行版Linux如Ub ...

  2. linux 创建docker基础镜像

    通过Dockerfile创建镜像时,一般都是基于 Docker Hub 提供的官方镜像.以下分别介绍在ubuntu16和centos7 两个系统上创建个人私有基础镜像的方法.  一.ubuntu16创 ...

  3. 庐山真面目之九微服务架构 NetCore 基于 Docker 基础镜像和挂载文件部署

    庐山真面目之九微服务架构 NetCore 基于 Docker 基础镜像和挂载文件部署 一.简介      我们在上一篇文章<庐山真面目之八微服务架构 NetCore 基于 Dockerfile ...

  4. howto:在构建基于debian的docker基础镜像时,更换国内包源

    debian经常被用作构建应用镜像的基础镜像,如微软在构建linux下的dotnetcore基础镜像时,提供了基于debian 8(jessie)和debian 9(stretch)的镜像. 由于这些 ...

  5. 测试环境docker化(一)—基于ndp部署模式的docker基础镜像制作

    本文来自网易云社区 作者:孙婷婷 背景 我所在测试项目组目前的测试环境只有一套,在项目版本迭代过程中,开发或产品偶尔会在测试环境进行数据校验,QA人数在不断增加,各个人员在负责不同模块工作时也会产生脏 ...

  6. 尝试自己建立以alpine 为基础的docker基础镜像和组件镜像

    安装ubuntu14.04 然后 #获取root权限 sudo su #安装docker apt-get install docker #准备基础镜像 docker pull alpine docke ...

  7. Docker 基础 : 镜像

    目录 获取镜像 查看镜像信息 搜索镜像 删除镜像 创建镜像 导出和导入镜像 上传镜像 总结 镜像是 Docker 的三大核心概念之一.Docker 运行容器前需要本地存在对应的镜像,如果本地没有对应的 ...

  8. 使用Nexus3构建Docker私有镜像仓库

    一.安装Nexus3 Nexus3是Sonatype提供的仓库管理平台,Nuexus Repository OSS3能够支持Maven.npm.Docker.YUM.Helm等格式数据的存储和发布:并 ...

  9. 构建docker基本镜像

    1.准备: 创建一个目录oldboy-hello 2.编写Dockerfile 内容如下,只有三行 FROM scratch ADD hello / CMD ["/hello"] ...

随机推荐

  1. FPM定制RPM包实践

    1.1 快速部署方案 ✔ 问题:当领导给你 100 台已经安装好系统的服务器,然后让优化,让你提出一个快速部署方案. 解答: 1.tar 打包 先编译安装 打包-->分发-->解包(比如 ...

  2. Android 开发笔记___FrameLayout

    xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:la ...

  3. 利用HTML5新特性改变浏览器地址后不刷新页面

    原文:http://www.cnblogs.com/xuchengzone/archive/2013/04/18/html5-history-pushstate.html   作为一个程序员,上Git ...

  4. body.clientHeight与documentElement.clientHeight

    body上的clientHeight会对着内容区域的高度变化而变化,当内容只有100px,则body上只有100px被撑起,返回的clientHeight为100: documentElement.c ...

  5. 完善tab页面定位

    当我们用锚点定位到页面某个元素时,接下来按tab的话是想进入到目前元素( id="content")的下一个连接 <a href="#content"&g ...

  6. ueditor精简插件和减少初次加载文件的方法

    ueditor初次使用的时候加载的文件大小大概有1MB还要多,这个页面的打开速度相对来说是很慢很慢的. 其实通常我们并不需要ueditor的全部功能,通过chromedev工具发现初次加载的时候就调用 ...

  7. jQuery插件实现瀑布留布局masonry + infinitescroll 图片高度处理

    jQuery插件实现瀑布留布局masonry + infinitescroll . 使用官方的示例代码实际测试发现,当上传到服务器的时候,由于图片下载速度问题,导致图片高度不能被正确识别,从而造成层的 ...

  8. 使用python3的typing模块提高代码健壮性

    前言:很多人在写完代码一段时间后回过头看代码,很可能忘记了自己写的函数需要传什么参数,返回什么类型的结果,就不得不去阅读代码的具体内容,降低了阅读的速度,加上Python本身就是一门弱类型的语言,这种 ...

  9. Java _分页Jdbc 版

    人生得意须尽欢,莫使金樽空对月. 先天下之忧而忧,后天下之乐而乐. 大东北的天气已经渐入佳境了,在夜深人静的时候,随着鼠标的移动,键盘清脆的声音,开启了今天的睡前代码工程!今天聊聊JDBC版本的分页, ...

  10. 2017年当下最值得你关注的前端开发框架,不知道你就OUT了!

    近几年随着 jQuery.Ext 以及 CSS3 的发展,以 Bootstrap 为代表的前端开发框架如雨后春笋般挤入视野,可谓应接不暇. 在这篇分享中,我将总结2017年当下最值得你关注的前端开发框 ...