Docker入门

一、前言

两年前就听过Docker这个高大上的东东,当时还专门听了同事的讲解,不过一直没有使用过。前段时间安装某款软件的时候又接触了一下Docker,感觉用着挺方便,也只是照葫芦画瓢的用了用。

之前有关注CloudMan的公众号,每周一三五会推送一篇有关Docker的技术博客(我大概是在其推送OpenStack的时候关注的)。昨天推送的是Docker Machine的相关内容,就简单看了一下。不看不知道,一看就不得了。第一是博客写的好(这一点早就知道,因为前面一直在学习博主的OpenStack相关教程);第二是Docker确实好用,功能很强大;第三有了OpenStack的基础,再来看Docker发现很多东西都是一致的,触类旁通,我现在的学习环境就是先在物理机中部署OpenStack,创建虚拟机,在虚拟机中安装Docker,整个下来体验还不错。

我建议有时间有兴趣的读者可以直接去CloudMan的公众号中学习其教程。本文仅是一个简单的介绍以及一些简单的操作,为的是帮助自己总结一下两天学下来的感受以及帮助没有时间的同胞对Docker有一个大概的了解。

二、Docker简介

什么是Docker?Docker可以类比成集装箱,我们可以看到现在的运输业都是靠集装箱来装货,这样的话不仅可以在运输工具中将货堆的整整齐齐还能保证集装箱中货物的独立性,不至于乱堆乱放,最后根本无法区分。那么Docker其实功能与之相比是一致的,只是Docker把软件放到一个“集装箱”里,不同的“集装箱”相互独立。其实Docker的功能与虚拟机很相似,但是虚拟机的体量比较大,耗费的资源多,而Docker容器共用底层的宿主机内核,是轻量级的。可以说虚拟机也是个“集装箱”,但是这个“集装箱”里装了很多没有用的或者说是重复装了很多公共的货物,而Docker这个“集装箱”基本装的都是有用的东西。并且当把我们需要的东西打包成“集装箱”之后,在任意宿主机上运行该“集装箱”,便可直接运行其内软件,而不需要再重新安装这些软件。设想一下之前我们给客户部署软件的时候都需要到实地去一点点安装,搞不好就会有版本冲突等等很多未知问题,有了Docker之后,我们只需要在开发环境中调试好,将其打包成“集装箱”,到客户那里直接运行此“集装箱”就好。

由上便知我们为什么要用Docker,就是为了在保证运行的软件独立性的前提下又是轻量级的不会给宿主机增加过多的负担。所以Docker具有易用、易部署、轻量等等一系列特点,值得拥有!

三、Docker安装

如果你已经有些心动,那么就可以先安装Docker试试了。Docker有收费版和免费版,分别为Docker CE和Docker EE,我们一般装Docker CE即可。按一下步骤操作即可:

  1. 安装包,允许 apt 命令 HTTPS 访问 Docker 源
$ sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    software-properties-common
  1. 添加 Docker 官方的 GPG
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
  1. 将 Docker 的源添加到/etc/apt/sources.list
$ sudo add-apt-repository \
  "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) \
  stable"
  1. 安装 Docker
$ sudo apt-get update
$ sudo apt-get install docker-ce

四、Docker使用

知道了什么是Docker以及安装成功了Docker,接下来的问题便是怎么使用Docker。

4.1 运行Docker容器

其实对于普通用户来说用的最多的场景应该是将别人打包好的符合自己功能或者业务需求的Docker镜像(上述“集装箱”的概念)下载到本地运行即可。执行命令为:

docker run -d -p 80:80 <image>

其中<image>表示你想下载安装的镜像。我们以httpd镜像为例,该镜像很简单,只是安装了一个httpd服务来对外提供http服务。

$ docker run -d -p 80:80 httpd


Unable to find image 'httpd:latest' locally
latest: Pulling from library/httpd
ad74af05f5a2: Pull complete 
3d839585b9c7: Pull complete 
cf157792586a: Pull complete 
c620105f0566: Pull complete 
830b826a2e13: Pull complete 
ec2eb5743536: Pull complete 
eb53f3c09897: Pull complete 
Digest: sha256:5b35d13089db73df620f4c198f5a4bfa56b8fe45a0364f343df9a26d874fef6c
Status: Downloaded newer image for httpd:latest
f8a24cd170439663b9238a846e939760449e3d2cdde3b21f14d8c31c7473d757

执行完之后,我们就能在浏览器中输入该宿主机的IP地址来打开运行在该Docker镜像中的httpd服务。其中-d表示后台运行该镜像,-p 80:80表示将镜像中的80端口映射到外部80端口,这样才能实现访问外部80端口即跳转到镜像内80端口。

大部分应用场景都是这样,因为在Docker HUB上已经存在了大量的镜像,我们只需要选择适合自己的就可以了。

4.2 打包自己的镜像

虽然我们能从Docker HUB上找到大部分需要的镜像,但是有些可能确实无法找到,比如我们为用户开发的应用。那么这种怎么方便的为用户部署在Docker环境内呢?其实也很容易,只需要我们在开发环境以现有的Docker镜像为基础,添加上新的功能,打包成镜像即可。有两种方式:docker commit和Dockerfile。以在ubuntu base 镜像中安装vim并保存为新镜像为例。下面分别介绍:

4.2.1 docker commit

  1. 第一步, 运行容器
docker run -it ubuntu

-it 参数的作用是以交互模式进入容器,并打开终端。

  1. 安装 vim
apt-get install -y vim
  1. 保存为新镜像

执行 docker commit 命令将容器保存为镜像。

docker commit old_image new_image

以上是如何用docker commit创建新镜像。然而Docker并不建议用户通过这种方式构建镜像。原因如下:

  1. 这是一种手工创建镜像的方式,容易出错,效率低且可重复性弱。比如要在 debian base 镜像中也加入vim,还得重复前面的所有步骤。
  2. 更重要的:使用者并不知道镜像是如何创建出来的,里面是否有恶意程序。也就是说无法对镜像进行审计,存在安全隐患。所以便有了第二种方式

4.2.2 dockerfile

用 Dockerfile创建ubuntu-with-vim,其步骤为:

  1. 创建Dockerfile文件

在当前目录创建一个Dockerfile文件,内容如下:

FROM ubuntu
RUN apt-get update && apt-get install -y vim
  1. build镜像

执行

docker build -t ubuntu-with-vim .

-t表示构建的镜像的名称,也可以使用-f指定dockerfile文件位置。这样便可构建出此镜像。

4.2.3 Dockerfile常用指令

FROM指定 base 镜像。

MAINTAINER设置镜像的作者,可以是任意字符串。

COPY将文件从宿主机复制到镜像。

COPY支持两种形式:

  1. COPY src dest
  2. COPY ["src", "dest"]
    注意:src 只能指定宿主机中的文件或目录。

ADD与 COPY 类似,从宿主机复制文件到镜像。不同的是,如果src是归档文件(tar, zip, tgz, xz 等),文件会被自动解压到 dest。

ENV设置环境变量,环境变量可被后面的指令使用。例如:

ENV MY_VERSION 1.3
RUN apt-get install -y mypackage=$MY_VERSION

并且此环境变量会留在镜像内,即运行该镜像都可以直接使用此环境变量。

EXPOSE指定容器中的进程会监听某个端口,Docker可以将该端口暴露出来。

VOLUME将文件或目录声明为 volume。

WORKDIR为后面的RUN,CMD,ENTRYPOINT,ADD或COPY指令设置镜像中的当前工作目录。

RUN在容器中运行指定的命令。主要用来安装软件等。

CMD容器启动时运行指定的命令。Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效。CMD 可以被 docker run 之后的参数替换。

ENTRYPOINT设置容器启动时运行的命令。Dockerfile 中可以有多个 ENTRYPOINT 指令,但只有最后一个生效。CMD 或 docker run 之后的参数会被当做参数传递给 ENTRYPOINT。

这一块可以直接参考CloudMan的教程,我可能也会在后续详细介绍。

4.3 创建自己的镜像仓库

Docker HUB中大量的镜像,但是有时候我们需要自己的镜像仓库,比如不能访问互联网或者牵扯到商业机密等。下面介绍如何创建本地仓库。

  1. 启动 registry 容器。

其实搭建镜像仓库就是启动了一个docker容器,这个镜像是docker官方建好的,我们只需要运行他即可。

docker run -d -p 5000:5000 -v /myregistry:/var/lib/registry registry

-d 是后台启动容器。

-p 将容器的 5000 端口映射到 Host 的 5000 端口。5000 是 registry 服务端口。

-v 将容器 /var/lib/registry目录映射到宿主机的/myregistry,用于存放镜像数据。

  1. 通过 docker tag重命名镜像,使之与registry匹配。
docker tag wsf 172.12.0.16:5000/wsf:v1

给wsf镜像重命名为172.12.0.16:5000/wsf:v1,v1为版本号,前面必须要加上域名或IP地址(运行上面registry容器的地址)和端口号。

  1. 上传镜像
docker push 172.12.0.16:5000/wsf:v1
  1. 下载镜像
docker pull 172.12.0.16:5000/wsf:v1

五、总结

以上便是这两天学习Docker的小收获和Docker的简单使用方式,再次感谢CloudMan的无私奉献,互联网需要这种开源精神和无私奉献精神。以后可能会针对某些具体内容进行详细阐述。

推荐阅读更多精彩内容