更新日志
- 2017.02.13:Mac 下新版 Docker 客户端已自带了 Linux 内核,不再需要 docker-machine,不用再安装 virtualbox 和 Boot2Docker。
Docker 简介
Docker是一个开源的容器引擎,也是一个轻量的 Linux 虚拟化工具。 在以往的部署方式中,比如要上线一个新的 Node 应用(参考Node 应用从申请到部署上线全流程总结),开发同学需要联系 SCM 和 PE 同学,告知他们应用需要一个 Node 环境,可能还要他们帮忙安装vipserver(否则不能连接线上 DB)等,PE 同学一般也比较忙,沟通成本很高。
而现在,有了 Docker,开发人员只需要把之前要跟 PE 说的“帮我装个 XXX”编写到Dockerfile
中,想装什么自己定,让应用的部署配置有章可循。
Docker 的优点和介绍网上一大堆这里就不啰嗦了,下面主要是实践:在 Mac 上搭建一个 Docker 环境,并把自己的应用部署上去。
Docker 的安装(OS X 环境)
可以参照 Docker 官网的安装方式:Install Docker and run hello-world
1.下载安装并打开 mac docker 客户端:地址,装好之后docker info
看一下,正常会有信息打印出来。 2.国内访问 docker 官方镜像会特别慢,可以使用阿里云的源来加速。参照加速器:登录访问https://cr.console.aliyun.com/#/accelerator,获取到你专属的加速器地址,形如https://1234oslp.mirror.aliyuncs.com
,然后配置到 Mac 的 Docker 客户端里:
更新:新版 mac docker 客户端已内置了 Linux 内核,执行docker info
可以看到:
所以不再需要 docker-machine,不用再安装 virtualbox 和 Boot2Docker。但为什么一定要有一个 Linux 内核,原理必须要清楚:
因为Docker 进程使用的是 Linux 内核特性,Docker 使用的是宿主机的 kernel,所以不能在 mac OS X 或 windows 系统中直接安装 Docker,你必须启动了一个虚拟 linux kernel,所有的 docker 容器都将跑在这个 kernel 上。
以前需要用 Boot2Docker 启动这个 linux kernel,现在新版 mac docker 客户端已帮我们集成好了。
按照阿里云给的指示步骤,创建装有 Docker 环境的 Linux 虚拟机。注:
mac 上需要事先安装好 virtualbox,否则下一步会报错。安装加速器的过程中会卡在这一步:Default Boot2Docker ISO is out-of-date, downloading the latest release...
,这是由于被墙所导致。别等了,直接去它给出的地址用浏览器下载,下载好之后移动到~/.docker/machine/cache/
下,然后重新执行加速器安装命令。
3.加速器配置完成后,执行
docker pull reg.docker.alibaba-inc.com/busybox
就会下载一个 busybox 的镜像,busybox 是一个微型 linux 系统。 附集团内部镜像列表:http://docker.alibaba-inc.com/#/imageSearch,可以 pull 这里的镜像。 查看当前机器所有的镜像:
docker images
4.基于 busybox 镜像创建一个容器,输出 hello world:
docker run busybox echo "hello docker"
解释:
- Docker 在容器内运行应用程序。在一个容器内运行一个应用程序需要一个命令:
docker run 镜像名 要在镜像中运行的命令
- docker 容器可以理解为在沙盒中运行的进程。这个沙盒包含了该进程运行所必须的资源,包括文件系统、系统类库、shell 环境等等。但这个沙盒默认是不会运行任何程序的。你需要在沙盒中运行一个进程来启动某一个容器。这个进程是该容器的唯一进程,所以当该进程结束的时候,容器也会完全的停止。
- 镜像和容器是 Docker 两个重要的概念:镜像(image)是只读的、没有状态的,不会改变的。容器(container)是一个镜像的运行实例。
一个交互式的容器
在这里我们继续用 docker run 命令,运行一个新的可交互的容器。
docker run -t -i busybox /bin/sh
-t
表示在新容器内指定一个伪终端或终端,-i
表示允许我们对容器内的 STDIN 进行交互。
执行以下命令可以看到当前运行中的所有容器和他们对应的容器 id:
docker ps
注意,每次执行 docker run 都会用指定的镜像新生成一个容器。如果你只是想在已有的容器里执行命令,应该使用dockr exec
命令而不是docker run
。docker exec
命令会在运行的容器执行一个新进程。
比如想要进入一个运行中的容器,可以执行
docker exec -it ${容器id} /bin/bash
守护进程 Hello world
创建并启动容器:
docker run -d busybox /bin/sh -c "while true; do echo hello world; sleep 1; done"
查看容器的历史输出:
docker logs ${容器id(前几位就可以)}
停止容器:
docker stop ${容器id(前几位就可以)}
还可以试一下 midway 提供的一个镜像:使用 midway-petstore docker 镜像,其中的启动命令:
docker run -d -p 6001:6001 --name petstore-container reg.docker.alibaba-inc.com/midway-petstore /usr/bin/midway-petstore-start
-d
表示可以让容器在 docker run
命令完成之后继续在后台运行;
-p
会将容器的端口暴露给主机,这样你就可以从你的 Mac 上访问它。
修改并提交新镜像
1.首先在一个 image 的基础上创建一个容器,docker run -it busybox /bin/sh
2.对容器里的文件进行修改,改好之后 exit 退出 3.使用docker commit
命令提交:
docker commit -m "Added files" -a "${作者}" ${容器id(前几位就可以)} ${名称}:${版本号}
2.然后可以使用docker images
命令看到刚刚保存的镜像
使用 Dockerfile 创建镜像
使用上面的docker commit
命令比较麻烦,在一个团队中不容易共享它的开发过程,不如使用配置文件的形式,用一组指令来创建我们新的镜像。
-
创建并编辑 Dockerfile 文件, Dockerfile 语法参考
-
到 Dockerfile 所在目录下,运行命令来构建镜像。
-t
参数给镜像添加标签,为了让我们在docker images
命令更容易查找到它。
docker build -t <namespace>/myapp .
3.构建成功后,可以基于自己的新镜像 run 一个容器试试啦
把镜像发布到内网阿里云平台上
1.创建镜像仓库,创建链接 2.点击管理,按照给定有步骤走完即可。
Q&A
- container1 和 container2 之间有资源隔离,但是它们之间是如何共享/抢占资源的呢?比如 container1 把 cpu 占满了,container2 是不是也就挂了?
- docker 容器启动为什么这么快?
- 答:在启动一个容器的时候,它只是调用 Kernel 的 Cgroups 提供的资源隔离的方法,在创建进程的方法上做了一层资源隔离的扩展而已。隔离包括了硬盘空间隔离、网络隔离、进程通信隔离等。所以并不需要类似 Linux 从 BIOS 到 Runlevel 的启动流程。这也是为什么 Docker 对 Linux 内核版本有要求,需要 64 位 Linux 系统,并且要大于 3.10 版本。uname -r 命令可以查看当前内核版本,2017 年 2 月 8 日最新稳定版本是4.9.8。
其他常用命令
- 删除所有 docker 容器(只能删除 stop 的容器):
docker rm `docker ps -a -q`
- 删除所有 docker 镜像(需要先删除所有关联容器):
docker rmi `docker images -q`
- 查看某个容器的 ip:
docker inspect --format='' $CONTAINER_ID
好文
- 一篇不一样的 docker 原理解析
- 解答了两个问题:Docker 容器有自己的 kernel 吗?docker 的 kernel version 由镜像确定还是由宿主机确定?
- 一篇不一样的 docker 原理解析 提高篇
- 大白话 Docker 入门(二)
- 阿里人,请用 AliDocker
- Docker 技术实践
- Docker 中文教程