段子

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

  年末将至,忽然发现,从创建开始到现在,整整一年时间,没有写过多少东西。为了留下一点痕迹,也是为了整理一下自己的收获,为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. c++学习笔记---03---从一个小程序说起2

    从一个小程序说起2 要求:编写一个程序,要求用户输入一串整数和任意数目的空格,这些整数必须位于同一行中,但允许出现在该行中的任何位置.当用户按下键盘上的"Enter"键时,数据输入 ...

  2. sass学习--在htm文件中使用

    一.导语 最近的战狼2好火爆啊,每天看战狼2的票房一路高飙,我估计比吴京还开心.看了这部戏的拍摄过程,除了敬佩就是踏实,是的,吴京是电影圈隔了这么久后能踏踏实实做电影的了,纯属个人见解,不喜请忽略.. ...

  3. ab使用命令

    ab使用-A auth-username:password    向服务器提供基本认证信息.用户名和密码之间":"分割,以base64编码形式发送.无论服务器是否需要(即是否发送了 ...

  4. CentOS6.8系统下,ecipse下进行编辑操作,意外退出

    错误情况:centos下打开eclipse软件,点击*.java或者*.pom软件卡死,命令行终端报错误信息,稍后eclipse自动退出. 错误信息: Java: cairo-misc.c:380: ...

  5. C#中的Unsafe和Fixed

    托管代码 (managed code):由公共语言运行库环境(而不是直接由操作系统)执行的代码.托管代码应用程序可以获得公共语言运行库服务,例如自动垃圾回收.运行库类型检查和安全支持等.这些服务帮助提 ...

  6. Python之mysql数据库更新表数据接口实现

    昨天,因为项目需求要添加表的更新接口,来存储预测模型训练的数据. 先码为敬~~~~~~~ # -*- coding: utf-8 -*- import pymysql import settings ...

  7. mysql数据库第一弹

    mysql(一) sql语句 sql是Structured Query Language(结构化查询语言)的缩写.SQL是专为数据库而建立的操作命令集,是一种功能齐全的数据库语言. 在使用它时,只需要 ...

  8. FPGA时序约束——理论篇

    在FPGA 设计中,很少进行细致全面的时序约束和分析,Fmax是最常见也往往是一个设计唯一的约束.这一方面是由FPGA的特殊结构决定的,另一方面也是由于缺乏好用的工具造成的.好的时序约束可以指导布局布 ...

  9. 【Java框架型项目从入门到装逼】第二节 - Spring框架 AOP的丧心病狂解说,你喜欢露娜的月下无限连吗?

    继续上一节的内容,多几个jar包: aop技术是面向切面编程思想,作为OOP的延续思想添加到企业开发中,用于弥补OOP开发过程中的缺陷而提出的编程思想.AOP底层也是面向对象:只不过面向的不是普通的O ...

  10. sql替换

    select * ,replace(NewsContent,'src=','修改后的内容') as rep from News where id=337update News set NewsCont ...