0x07 - Docker小鲸鱼的使用笔记 [1] 从无到有

Docker 小鲸鱼

Docker? Docker!

Docker,码头工人,搬运工,承运者,可爱的小鲸鱼。

简单来说 Docker 是一个开源的应用容器引擎。
开发者把应用,软件还有相应依赖通过 Docker 打包成一个轻量级、可移植的容器,
只要目标机器拥有 Docker 的运行环境,不用关心内部的依赖即可方便完成应用分发和发布工作,
非常适用于集群环境,既节约开销,也方便部署。

它如何工作?

对于 Docker 来说,其整体的框架结构像这样:

首先,我们将应用打包为一个又一个的 IMAGE;
然后,在需要运行时,我们将这些镜像提取出来,创建一个对应的 CONTAINER 来运行它;
而这个打包好的 IMAGE 存储的地方,就叫做 REGISTRY。

因此运行的流程可以概括如下:

  1. 从 REGISTRY 获取 IMAGE
  2. 创建一个 CONTAINER。
  3. 将 IMAGE 放入 CONTAINER 运行。

同一个 IMAGE 可以创建千千万万个 CONTAINER。
同一个 REGISTRY 可以存放许许多多的 IMAGE。
而一个 CONTAINER 一次尽量只运行一个 IMAGE。

似乎会有人将 CONTAINER 当作是虚拟机来理解,
但是在这里,CONTAINER 更像是一个独立的进程,而非是一个虚拟机。

因此如果需要多容器运行,请使用 docker-compose 工具进行管理。

如何开始

Reference:
当然,Docker 的项目网址还有文档其实非常清晰明了。
如果对英文比较苦手,一些成品文档,例如 runoob 也是不错的去处。

这里只是拾人牙慧,总结了一些自己在 Docker 使用过程中的经验。

那么,让我们开始吧——

0x00 安装

Linux

广大的 Linux 用户只需要运行以下内容:

1
$ curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun      # 当然,Aliyun 是可选的

等待着一切安装完成——
然后让我们来看看成果:

1
$ docker -v

Ok,你已经准备好下一步了。

Windows

Windows 下的 Docker 可以在 这里 找到。
像是一般软件一样点击下一步安装完成后,小鲸鱼会出现在你的通知栏。

这样,你就可以在 Windows 下使用 Docker 了。

PS. 小鲸鱼偏好 Linux,在 Windows 下运行会额外消耗资源,且需要安装 WSL (Windows Subsystem for Linux)来承载运行。

MacOS

MacOS 我们可以使用 Homebrew 来安装 Docker。

1
$ brew install --cask --appdir=/Applications docker

和 Windows 一样,安装完成后小鲸鱼会出现在你的状态栏。

Enjoy ~

0x01 Hello World

DockerHello World 分为两步:

  1. 将应用打包为 Docker Image
  2. Docker Image 放入 Docker Container 运行

1. 打包

首先,让我们建立一个简单的应用。

假设我们的应用如下:
我们希望运行 Docker后,在屏幕上打印下 Hello World

那么实际操作的流程如下

运行

1
2
3
$ mkdir helloWorld
$ cd helloWorld
$ vi run.sh

并保存以下命令

1
$ echo "Hello world"

在当前文件夹下新建一个 Dockerfile
注意!很多关于镜像的设置都基于 Dockerfile ,这里先简单略过。
关于 Dockerfile 的编写,请看这里

1
$ vi Dockerfile

然后让我们在 Dockerfile 里添加如下的信息:

1
2
3
4
5
6
7
8
9
FROM ubuntu                                         # 这是告诉 Docker, 这个镜像基于什么构建,所有的 Docker 镜像都需要这么一行命令
# 不同的应用基于不同的镜像,这里由于我们只用了一些基础命令,所以 ubuntu 镜像即可
MAINTAINER Shigure_Hotaru # 维护人,也就是作者

ADD . /code # 将文件夹内的东西 Copy 到 镜像中 /code 文件夹内
WORKDIR /code # 相当于 cd /code

RUN echo "Echo Before Running The Docker Image" # RUN 修饰的命令表示在 "构建镜像" 时运行的命令
CMD sh run.sh # CMD 修饰的命令表示在 "运行镜像" 时运行的命令

准备就绪以后这样运行:

1
$ sudo docker build -t hw:v1.0 . # -t 表示 tag,可以理解为是版本号,在 hw 冒号后的就是版本信息了,最后的 . 表示当前文件夹

Docker 会把你在 Dockerfile 里写入的步骤,一步步执行。

我们关注一下第 5 步:

1
2
3
4
Step 5/6 : RUN echo "Echo Before Running The Docker Image"
---> Running in b0446bd5ad97
Echo Before Running The Docker Image
Removing intermediate container b0446bd5ad97

这一步就相当于是运行 RUN 后的命令。
假如有需要安装依赖,或者在运行前进行的准备工作,都可以用 RUN 修饰完成。

在完成了镜像构建以后,让我们看看我们的新镜像:

1
2
3
4
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hw v1.0.0 54c64c094be8 7 minutes ago 72.7MB
ubuntu latest 7e0aa2d69a15 4 weeks ago 72.7MB

可以看到我们的镜像除了 hw 以外,还有一个 ubuntu 镜像,这个就是我们 hw 基于的原始镜像了。

如果要移除镜像:
1
2
$ sudo docker rmi hw:v1.0.0
$ sudo docker rmi 54c64c094be8 # 使用镜像 ID 也可删除镜像

2. 运行

其实 Docker 的运行十分简单:

1
2
$ sudo docker run hw:v1.0.0         # 在新容器中运行 hw:v1.0.0 的镜像
Hello World

在这里我们没有用上各种各样的额外设置,下表总结了一些可能会用上的选项,更全的列表 请看这里

1
2
3
4
5
6
7
docker run [OPTIONS] IMAGE [COMMAND] [ARGS...]
-d 后台运行该镜像
-i 以交互模式运行容器,一般与 -t 一起使用
-t 分配一个伪输入端口,一般与 -i 一起使用
-p 指定端口映射,格式:主机(宿主)端口:容器端口
例如: docker run -p 1234:5000 hw:v1.0.0 将暴露容器的 5000 端口,并将主机的 1234 端口映射到上面
...

在执行时,Docker 会给这个镜像分配一个容器,我们可以通过下面的命令来查看正在运行的容器:

1
2
3
$ sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0c7d9897897d hw:v1.0.0 "/bin/sh -c 'sh run.…" 20 seconds ago Exited (0) 19 seconds ago kind_ardinghelli

可以看到这个容器已经执行结束,假如我们需要知道执行过程中的日志信息,我们需要这样做:

1
2
$ sudo docker logs 0c7d9897897d
Hello World

如果要把容器移除的话,需要这样执行:

1
2
$ sudo docker rm 0c7d9897897d
0c7d9897897d

以上,你已经学会如何正确驾驶小鲸鱼了;
现在,开始你最伟大的远航吧 ~

之后的事

事实上,如果要把一个镜像从无到有,从代码到镜像,放入容器,最后再从外部访问这个服务,
中间涉及到的过程十分复杂,不仅需要搭配合适的网关网口,还需要注意各种端口转发和服务框架。

最后涉及到业务的逻辑,还有一些部署时的杂事,也让人十分头疼。

小鲸鱼虽然脾气不大,但是运送小鲸鱼的人可是十足的难缠。

从搭建环境开始,到上传至云上的 Repository ,再到最后的部署落地,
不仅命令繁多,其中的过程也称不上简单。

那么该如何将这一切处理成流水线,成为 Docker 达人呢?

其实社区已经给出了不错的答案,
下一次让我们来尝试一下,Jenkins x Docker 的解决方案。