docker比一般多一点的初学者介绍

因为最近想搭一个phabricator用来做看板和任务管理,一开始了解这个是Easy大大有在微博推荐过,后来苏洋也在群里和博客里说到了,看上去还不错的样子,因为主角是docker所以就不介绍太多,后面有机会写一下。

docker最开始是之前在某位大佬的博客看到的,看上去有点神奇,感觉是一种轻量级的虚拟机,但是能做的事情好像差不多,那时候是在Ubuntu系统的vps里起一个Ubuntu的docker,然后在里面装个nginx,配置端口映射就可以访问了,后来也草草写过一篇使用docker搭建mysql集群,但是最近看了下好像是因为装docker的大佬做了一些别名还是什么操作,导致里面用的操作都不具有普遍性,而且主要是把搭的过程写了下,属于囫囵吞枣,没理解docker是干啥的,为啥用docker,就是操作了下,这几天借着搭phabricator的过程,把一些原来不理解,或者原来理解错误的地方重新理一下。

之前写的 mysql 集群,一主二备,这种架构在很多小型应用里都是这么配置的,而且一般是直接在三台 vps 里启动三个 mysql 实例,但是如果换成 docker 会有什么好处呢,其实就是方便部署,比如其中一台备库挂了,我要加一台,或者说备库的 qps 太高了,需要再加一个,如果要在 vps 上搭建的话,首先要买一台机器,等初始化,然后在上面修改源,更新,装 mysql ,然后配置主从,可能还要处理防火墙等等,如果把这些打包成一个 docker 镜像,并且放在自己的 docker registry,那就直接run 一下就可以了;还有比如在公司要给一个新同学整一套开发测试环境,以 Java 开发为例,要装 git,maven,jdk,配置 maven settings 和各种 rc,整合在一个镜像里的话,就会很方便了;再比如微服务的水平扩展。

但是为啥 docker 会有这种优势,听起来好像虚拟机也可以干这个事,但是虚拟机动辄上 G,而且需要 VMware,virtual box 等支持,不适合在Linux服务器环境使用,而且占用资源也会非常大。说得这么好,那么 docker 是啥呢

docker 主要使用 Linux 中已经存在的两种技术的一个整合升级,一个是 namespace,一个是cgroups,相比于虚拟机需要完整虚拟出一个操作系统运行基础,docker 基于宿主机内核,通过 namespace 和 cgroups 分隔进程,理念就是提供一个隔离的最小化运行依赖,这样子相对于虚拟机就有了巨大的便利性,具体的 namespace 和 cgroups 就先不展开讲,可以参考耗子叔的文章

安装

那么我们先安装下 docker,参考官方的教程,安装,我的系统是 ubuntu 的,就贴了 ubuntu 的链接,用其他系统的可以找到对应的系统文档安装,安装完了的话看看 docker 的信息

1
sudo docker info

输出以下信息

简单运行

然后再来运行个 hello world 呗,

1
sudo docker run hello-world

输出了这些

看看这个运行命令是怎么用的,一般都会看到这样子的,sudo docker run -it ubuntu bash, 前面的 docker run 反正就是运行一个容器的意思,-it是啥呢,还有这个什么 ubuntu bash,来看看docker run`的命令帮助信息

1
-i, --interactive                    Keep STDIN open even if not attached

就是要有输入,我们运行的时候能输入

1
-t, --tty                            Allocate a pseudo-TTY

要有个虚拟终端,

1
2
3
Usage:	docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

Run a command in a new container

镜像

上面说的-it 就是这里的 options,后面那个 ubuntu 就是 image 辣,image 是啥呢

Docker 把应用程序及其依赖,打包在 image 文件里面,可以把它理解成为类似于虚拟机的镜像或者运行一个进程的代码,跑起来了的叫docker 容器或者进程,比如我们将要运行的docker run -it ubuntu bash的ubuntu 就是个 ubuntu 容器的镜像,将这个镜像运行起来后,我们可以进入容器像使用 ubuntu 一样使用它,来看下我们的镜像,使用sudo docker image ls就能列出我们宿主机上的 docker 镜像了

一个 ubuntu 镜像才 64MB,非常小巧,然后是后面的bash,我通过交互式启动了一个 ubuntu 容器,然后在这个启动的容器里运行了 bash 命令,这样就可以在容器里玩一下了

在容器里看下进程,

只有刚才运行容器的 bash 进程和我刚执行的 ps,这里有个可以注意下的,bash 这个进程的 pid 是 1,其实这里就用到了 linux 中的PID Namespace,容器会隔离出一个 pid 的名字空间,这里面的进程跟外部的 pid 命名独立

查看宿主机上的容器

1
sudo docker ps -a

如何进入一个正在运行中的 docker 容器

这个应该是比较常用的,因为比如是一个微服务容器,有时候就像看下运行状态,日志啥的

1
sudo docker exec -it [containerID] bash

查看日志

1
sudo docker logs [containerID]

我在运行容器的终端里胡乱输入点啥,然后通过上面的命令就可以看到啦