Mac OS X 下安装使用 Docker (新)

两年前的一篇 Mac OS X 下安装使用 Docker 安装时还是用的 boot2docker, 如今进化到了在 Mac OS X 下用 Docker Toolbox, 而且命令也由 boot2docker 换成了 docker-machine. 当然由于是非 Linux 系统, 所以 Mac OS X 仍然需要借助于 VirtualBox 中的 Linux 虚拟机作为桥梁, Docker Toolbox 创建的虚拟机名是 default (boot2docker 创建的虚拟机名是 boot2docker-vm) 就是这一桥梁, 我们称之为 DOCKER_HOST. 文中的 default 虚拟机指的就是这个 DOCKER_HOST.

现在来看下安装步骤及体验, 因为我系统中已安装好了 VirtualBox, 所以这一步骤等会就省略了.

一. 安装 docker 和  docker-machine

官方的指南是通过下载  DockerToolbox 来安装 docker, docker-machine 和其他辅助工具. 但如果你偏于极客, 并不习惯于图形界面来安装的话, 那么安装 docker 和 docker-machine 就只要下面两个指令

brew install docker
brew install docker-machine

如果你已选择了使用上面的两条命令来安装 docker, docker-machine 的话, 那么请跳到下一步.

如果你热爱图形界面来安装应用的话, 可以到页面 https://www.docker.com/products/docker-toolbox 中下载 Mac 的版本的 DockerToolbox-1.10.3.pkg, 当前版本是 1.10.3

Docker Toolbox Installer   Docker Toolbox includings

可以看到 Docker Toolbox 包含了以下五个组件

. Docker Client docker binary  ----  docker 命令
. Docker Machine docker-machine binary  ---- docker-machine 命令
. Docker Compose docker-compose binary
. Kitematic - Desktop GUI for Docker
. Docker Quickstart Terminal app

然后就 Continue, 选择安装路径, 按提示输入 sudo 密码, 由于 Docker Toolbox 检测到我已安装了 Virtual Box, 所以不曾提示我去下载安装 Virtual Box.

Docker Get Started

将要完成之际你要选择使用 Docker Quickstart Terminal 还是 Kitematic (Beta) 来开始使用 Docker. 这两个东西都可以在第一次启动的时候自动创建 Virtual Box 的  default 虚拟机.

二. 初始化 Virtual Box 的 default 虚拟机

如果你是使用的 brew install 来安装的 docker 和 docker-machine 的话, 可以用命令

docker-machine create --driver virtualbox default

来手动创建 default 虚拟机. 创建过程与下面使用 Docker quickstart Terminal 是一样的.

如果安装的是 Docker Toolbox 的话, 可以执行 Docker Quickstart Terminal 来创建 default 虚拟机. 我在 Launchpad 中点击 Docker Quickstart Terminal 后没什么效果, 所以是直接执行相应的命令文件 

/Applications/Docker/Docker\ Quickstart\ Terminal.app/Contents/Resources/Scripts/start.sh

Docker Quickstart Init

或者打开 Docker Toolbox 中的 Kitematic 工具, 创建 default 虚拟机也是自动完成的. Kitematic 还有更为丰富的功能, 省去了记忆那些 docker-machine 和  docker 命令, 不过极客们可不这么想.

虽然我们新的虚拟机名称变成了 default, 但安装的镜像依旧是 boot2docker.iso. 由于我以前安装过 boo2docker, 所以上面直接从缓存的 boot2docker.iso 创建了 default 虚拟机. 再看看在  Virtual Box 中的样子

boot2docker-default

三. 初始化环境变量

docker-machine env default    显示宿主机需要为 default 虚拟机设置的环境变量的指令
eval (docker-machine env default)  将在宿主机中设置相应的环境变量 -- 我的机器的 shell 是 fish, 如果 bash 将是 eval $(docker-machine env default)

docker-machine-env

env 显示宿主机的环境变量

不设置好环境变量将无法使用 docker 命令, 比如执行 docker images 时会看到 Cannot connect to the Docker daemon. Is the docker daemon running on this host? 错误, 因为 docker 无法与 default 虚拟机连接起来. 为了每次都有效还必须把 eval (docker-machine env default) 加到 ~/.config/fish/config.fish 文件中. 使用 bash 则加一行 eval $(docker-machine env default) 到 ~/.bash_profile 中.

四. 最简单的使用 Docker

[I] ➜  ~ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
[I] ➜  ~ docker run -it busybox /bin/sh
Unable to find image 'busybox:latest' locally
latest: Pulling from library/busybox
385e281300cc: Pull complete
a3ed95caeb02: Pull complete
Digest: sha256:4a887a2326ec9e0fa90cce7b4764b0e627b5d6afcb81a3f73c85dc29cea00048
Status: Downloaded newer image for busybox:latest
/ # uname -a
Linux 5427a4ee9eaa 4.1.19-boot2docker #1 SMP Mon Mar 7 17:44:33 UTC 2016 x86_64 GNU/Linux
/ # exit
[I] ➜  ~ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
busybox             latest              47bcc53f74dc        9 days ago          1.113 MB
[I] ➜  ~ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
5427a4ee9eaa        busybox             "/bin/sh"           20 seconds ago      Exited (0) 8 seconds ago                       grave_kowalevski

第一个 docker images 时是没有一个镜像的, 用 docker run -it busybox /bin/sh 安装并启动一个交互时的 busybox 容器, 退出后 docker images 列出我们安装了一个 busybox 镜像.

六. 基于 Dockerfile 构建

当然目录下创建 Dockerfile 文件, 内容如下:

FROM ubuntu:14.04
USER root
RUN apt-get install -y apache2
EXPOSE 80

由 Dockerfile 构建镜像

$ docker builder -t ubuntu:apache2 ./

......

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu              apache2             511aaac08bc1        2 minutes ago       224 MB
ubuntu              14.04               97434d46f197        9 days ago          188 MB

加载镜像, 启动容器

docker run -P -d ubuntu:apache2 apachectl -D FOREGROUND

那么 Docker 会在 default 虚拟机上开启一个随机的端口与容器的 80 端口进行映射, 像 docker ps 可以看到

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                   NAMES
91fd870d5e18        ubuntu:apache2      "apachectl -D FOREGRO"   7 seconds ago       Up 7 seconds        0.0.0.0:32768->80/tcp   furious_borg

容器的 80 映射到了 default 虚拟机的 32768 端口. 查看到 default 虚拟机的 ip

docker-machine ip default
192.168.99.106

这时可以在 Mac 本机访问容器中的 Apache2 服务

curl -I http://192.168.99.106:32769
HTTP/1.1 200 OK
Date: Mon, 28 Mar 2016 00:49:08 GMT
Server: Apache/2.4.7 (Ubuntu)
Last-Modified: Sun, 27 Mar 2016 22:38:30 GMT
ETag: "2cf6-52f0f748d8580"
Accept-Ranges: bytes
Content-Length: 11510
Vary: Accept-Encoding
Content-Type: text/html

如果希望非本机也能访问容器中的 Apache2 服务, 则需要把 Mac 的端口映射到 default 虚拟机上去, 比如 Mac 下可以用 pf 实现, 也可以设置在 default 虚拟机上

$ VBoxManage controlvm default natpf1 "tcp-port_80,tcp,,20080,,10080"

上面的命令配置了 Mac OS X 的  20080 映射到 default 虚拟机的  10080 端口.  Mac:20080 -> default:10080

然后在启动容器时用  -p 参数指定 default 虚拟机到容器的端口映射.  default:10080 -> 容器:80

docker run -p 10080:80 -d ubuntu:apache2 apachectl -D FOREGROUND

docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                   NAMES
200f14210914        ubuntu:apache2      "apachectl -D FOREGRO"   About a minute ago   Up About a minute   0.0.0.0:10080->80/tcp   pensive_bohr

现在可以用 Mac 的  20080 端口访问到容器的  80 端口

curl -I http://localhost:20080
HTTP/1.1 200 OK
Date: Mon, 28 Mar 2016 00:49:08 GMT
Server: Apache/2.4.7 (Ubuntu)
Last-Modified: Sun, 27 Mar 2016 22:38:30 GMT
ETag: "2cf6-52f0f748d8580"
Accept-Ranges: bytes
Content-Length: 11510
Vary: Accept-Encoding
Content-Type: text/html

当然其他机器在没有防火墙的限制下也可以通过 Mac 的 IP 地址访问容器的 Apache2 服务了.


关于端口映射的配置

前面是用 VBoxMange  controlvm 添加端口映射时不需要用 docker-machine stop 停止 default 虚拟机

VBoxManage modifyvm default --natpf1 "tcp-port_80,tcp,,20080,,10080" 命令不能对运行中的虚拟机操作.

VBoxManage controlvm default natpf1 delete tcp-port_80 可以删除运行中的 default 虚拟机的端口映射规则.
VBoxManage showvminfo default --machinereadable | grep Forwarding 显示 default 虚拟机的所有端口映射规则

上面的命令必须逐个的把在 Mac OS X 与 default 虚拟机之间进行端口映射, 也有人想一了百了, 用下面那样的脚本

for i in {10000..10999}; do
  VBoxManage modifyvm "boot2docker-vm" --natpf1 "tcp-port$i,tcp,,$i,,$i";
  VBoxManage modifyvm "boot2docker-vm" --natpf1 "udp-port$i,udp,,$i,,$i";
done

这样做完全是在 Mac OS X 上无畏的启动大量监听的端口, 并与 default 虚拟机进行映射, 不仅浪费了大量的资源, 而且 EXPOSE 80 选的随机端口不一定落在 10000 -- 10999 这个区间上, 比如前面的  32768 端口.

和 boot2docker 类似, 如果你不想用 VBoxMange  命令来操作虚拟机设置的话, 也可以用 docker-machine ssh 来设置隧道转发, 如

docker-machine ssh default -L 20080:localhost:10080

#或者无需进入到 default 虚拟机的话
docker-machine ssh default -f -N -L 20080:localhost:10080

尚不知如何停止掉 docker-machine 对某个端口转发.

参考: 1. Install Docker Toolbox on Mac OS X
        2. https://docs.docker.com/engine/installation/mac/

类别: Linux/Unix. 标签: . 阅读(1,223). 订阅评论. TrackBack.

Leave a Reply

Be the First to Comment!

avatar
wpDiscuz