【编者的话】Docker 自开源以来受到了各大公司的广泛关注,或许现在互联网公司的运维体系不承载在 Docker(或 Pouch 等)之上都不好意思说自己的互联网公司。
本文会简单介绍下 Docker 的基础概念,入门级使用方式和一些使用 Docker 能大大提升效率的场景。
对 Docker 最简单并且带有一定错误的认知就是 “Docker 是一种性能非常好的虚拟机”。
正如上面所说,这是有一定错误的说法。Docker 相比于传统虚拟机的技术来说先进了不少,具体表现在 Docker 不是在宿主机上虚拟出一套硬件后再虚拟出一个操作系统,而是让 Docker 容器里面的进程直接运行在宿主机上(Docker 会做文件、网络等的隔离),这样一来 Docker 会 “体积更轻、跑的更快、同宿主机下可创建的个数更多”。
Docker 中有三个核心概念:Image、Container、Repository。
Docker 的安装是非常便捷的,在 macOS、ubuntu 等下面都有一键式安装工具或者脚本。更多可以参考 Docker 官方教程 。
安装后 Terminal 中敲下 docker,有使用说明出来的话大多情况下说明已经安装成功了。
DockerHub 等网站都提供了众多镜像,一般情况下我们都会从它那找个镜像作为基础镜像,然后再进行我们的后续操作。
这里我们以 Ubuntu 基础镜像为例,配置一个 node 环境。
因为 “链路太长” 的原因,国内访问 Docker Hub 可能会比较慢,可以使用国内众多厂商提供的镜像加速器
利用 docker pull 命令即可从相关 hub 网站上拉取镜像到本地。同时在拉的过程中就能看到是按照多个 “层” 去拉镜像的。
> docker pull ubuntu:18.04 18.04: Pulling from library/ubuntu c448d9b1e62f: Pull complete 0277fe36251d: Pull complete 6591defe1cd9: Pull complete 2c321da2a3ae: Pull complete 08d8a7c0ac3c: Pull complete Digest: sha256:2152a8e6c0d13634c14aef08b6cc74cbc0ad10e4293e53d2118550a52f3064d1 Status: Downloaded newer image for ubuntu:18.04
执行 docker images 即可看到本地所有的镜像。
> docker images REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu 18.04 58c12a55082a 44 hours ago 79MB
docker create 命令通过镜像去创建一个容器,同时吐出容器 ID。
> docker create --name ubuntuContainer ubuntu:18.04 0da83bc6515ea1df100c32cccaddc070199b72263663437b8fe424aadccf4778
用 docker start 即可运行改容器。
> docker start ubuntuContainer
用 docker ps 即可查看运行中的 container。
> docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 9298a27262da ubuntu:18.04 "/bin/bash" 4 minutes ago Up About a minute ubuntuContainer
用 docker exec 即可进入该 container。
> docker exec -it 9298 root@9298a27262da:/# ls bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var root@9298a27262da:/# exit
用 docker run 可以一步到位创建并运行一个容器,然后进入该容器。
> docker run -it --name runUbuntuContainer ubuntu:18.04 /bin/bash root@57cdd61d4383:/# ls bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var root@57cdd61d4383:/#
> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
57cdd61d4383 ubuntu:18.04 "/bin/bash" 9 seconds ago Up 8 seconds runUbuntuContainer
9298a27262da ubuntu:18.04 "/bin/bash" 9 minutes ago Up 6 minutes ubuntuContainer
进入容器之后一切操作和普通环境一致,我们安装个简单的 node 环境。
> apt-get update > apt-get install wget > wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.8/install.sh | bash
> nvm install 8.0.0
> node -v
和 Ghost 装 Windows 一样,很多时候,我们期望能定制自己的镜像,在里面安装一些基础环境(比如上文中的 node),然后制作出自己要的基础镜像。这个时候 docker commit 就派上用场了。
> docker commit --author "rccoder" --message "curl+node" 9298 rccoder/myworkspace:v1 sha256:68e83119eefa0bfdc8e523ab4d16c8cf76770dbb08bad1e32af1c872735e6f71
>docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
rccoder/myworkspace v1 e0d73563fae8 20 seconds ago 196MB
接着,试一下我们新创建的镜像?
> docker run -it --name newWorkSpace rccoder/myworkspace:v1 /bin/bash root@9109f6985735:/# node -v 8.0.0
看起来没问题。
镜像制作好了,怎么共享出去让别人使用呢?这里以 push 到 docker hub 为例。
第一步是先去 docker hub 注册一个账号,然后在终端上登录账号,进行 push。
> docker login > docker push rccoder/myworkspace:v1 The push refers to repository [docker.io/rccoder/myworkspace] c0913fec0e19: Pushing [=> ] 2.783MB/116.7MB bb1eed35aacf: Mounted from library/ubuntu 5fc1dce434ba: Mounted from library/ubuntu c4f90a44515b: Mounted from library/ubuntu a792400561d8: Mounted from library/ubuntu 6a4e481d02df: Waiting
用 Docker 进行持续集成?相比在了解 Docker 之前肯定听过这个事情,那就意外着需要从某个地方拷贝代码,然后执行(对,听上去有点 travis-ci 的那种感觉)。
是时候该 Dockerfile 出场了!
Dockerfile 是一个由一堆命令+参数构成的脚本,使用 docker build 即可执行脚本构建镜像,自动的去做一些事(同类似于travis-ci 中的 .travis.yml)。
Dockerfile 的格式统统为:
# Comment INSTRUCTION arguments
必须以 FROM BASE_IMAGE 开头指定基础镜像。
更详细的规范与说明请参考 Dockerfile reference 。这里我们以基于上面的 rccoder/myworkspace:v1 作为基础镜像,然后在根目录创建 a 目录为例。
Dockerfile 如下:
FROM rccoder/myworkspace:v1 RUN mkdir a
然后执行:
> docker build -t newfiledocker:v1 . Sending build context to Docker daemon 3.584kB Step 1/2 : FROM rccoder/myworkspace:v1 ---> 68e83119eefa Step 2/2 : RUN mkdir a ---> Running in 1127aff5fbd3 Removing intermediate container 1127aff5fbd3 ---> 25a8a5418af0 Successfully built 25a8a5418af0 Successfully tagged newfiledocker:v1
> docker docker run -it newfiledocker:v1 /bin/bash
root@e3bd8ca19ffc:/# ls
a bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
借助 Dockerfile 的能力,Docker 留下了无限的可能。
说了这么一堆,那实际生产环境中 Docker 能做什么呢?常用的可能有下面这些(欢迎在评论中补充)
业务开发中往往需要区分开发环境与线上环境,利用 Docker 能原封不动的将开发环境中的 代码与环境原封不动无污染的 迁移到线上环境,配合一定的自动化流程即可实现自动的发布。
因为 node_modules 的蛋疼问题,同一个仓库下不同人开发往往会遇到不同的人使用不同的 包版本 且自己根本不知道与别人不一样,最终导致发布之后产生线上问题。利用 Docker 可以在云端新建容器,远程 无污染、低成本 构建代码,实现 不同人用的一定是同一个版本 。
某些场景下可能会配一些超级复杂的环境(比如:大一同学配 Java 环境),这个时候可以利用 Docker 对环境配置做封装,直接生成镜像,让大家低成本使用。
类似于 travis-ci 这种
比如这个项目依赖 node 6,那个项目依赖 node 8(只是举例子,硬盘够大的话还是建议通过 nodeinstall 解决);同一台服务器上跑了 100 个 wordpress 程序(可以用 Docker 建立隔离开,防止互相污染)。
嗯,低成本安全超售(大雾)。
链接: https://juejin.im/post/5ad3172c5188257ddb10109a ,作者:rccoder