如何在mac中使用docker
Docker可以很轻松的运行、管理应用程序。docker一般运行在linux环境中,也可以运行在max和windows环境中
Docker的工作原理
Docker是一个CS模型。Docker的服务端是一个守护进程,进行各种繁杂的操作:包括编译、下载镜像,启动、停止容器等。它也有rest接口以供远程操控。
Docker客户端是一个命令行工具,它通过rest风格的api来和服务端交互。我们通过客户端来向服务端发送命令。
Docker服务端运行在我们的服务器(或者个人电脑)上,称之为host,因为docker默认运行在linux上,所以我们的服务器操作系统一般为linux(或者更精确的说法,linux内核的操作系统)。
Linux上的Docker
比如我们在笔记本电脑上运行Docker,docker的工作原理如下:
这台笔记本同时运行着服务端和客户端,很简单的模型。
Mac上的Docker
OS X的问题是:它不是linux。它没有运行原生docker的内核。
boot2docker是一个可以运行Docker容器的轻量级linux分支。意思是:我们要在Mac电脑的虚拟机中运行boot2docker。
我们在OS X系统运行原生的Docker客户端,但是Docker服务端运行在boot2docker上,也就是说boot2docker才是上面讲的host,而不是OS X.
安装
- 安装VirtualBox
点击这里进行安装,不再赘述。 - 安装Docker & boot2docker
有两种安装方式:官方的安装包或者使用homebrew,这里使用homebrew为例:brew update brew install docker brew install boot2docker
- 初始化 & 启动boot2docker
首先,需要初始化boot2docker(只需要初始化一次):> boot2docker init 2014/08/21 13:49:33 Downloading boot2docker ISO image... [ ... ] 2014/08/21 13:49:50 Done. Type `boot2docker up` to start the VM.
然后,启动:
> boot2docker up 2014/08/21 13:51:29 Waiting for VM to be started... ....... 2014/08/21 13:51:50 Started. 2014/08/21 13:51:51 Trying to get IP one more time 2014/08/21 13:51:51 To connect the Docker client to the Docker daemon, please set: 2014/08/21 13:51:51 export DOCKER_HOST=tcp://192.168.59.103:2375 export DOCKER_CERT_PATH=/Users/kongkong/.boot2docker/certs/boot2docker-vm
export DOCKER_TLS_VERIFY=1
- 设置环境变量
docker客户端默认服务端是本机。我们需要设置DOCKER_HOST环境变量:export DOCKER_HOST=TCP://192,168.59.103:2375
你自己的虚拟机可能是其他的ip地址,这个IP地址,在执行boot2docker up
时会输出出来。
- 查看信息
让我们来查看一下docker的信息:> docker info Containers: 0 Images: 0 Storage Driver: aufs Root Dir: /mnt/sda1/var/lib/docker/aufs Dirs: 0 Execution Driver: native-0.2 Kernel Version: 3.15.3-tinycore64 Debug mode (server): true Debug mode (client): false Fds: 10 Goroutines: 10 EventsListeners: 0 Init Path: /usr/local/bin/docker Sockets: [unix:///var/run/docker.sock tcp://0.0.0.0:2375]
docker安装成功。
常见问题
我们安装了docker,下面来看一看常见的问题
问题1:端口代理
Docker在容器和host之间代理端口,这里的host是指boot2docker,而不是OS X.
启动一个nginx:
> docker run -d -P --name web nginx
Unable to find image 'nginx' locally
Pulling repository nginx
[ ... ]
0092c03e1eba5da5ccf9f858cf825af307aa24431978e75c1df431e22e03b4c3
这条命令已守护进程的方式启动了一个容器[-d],自动代理端口[-P],将容器命名为”web”[–name web],使用的是nginx镜像。这个容器的唯一id是0092c03e1eba...
。
检查一下容器是否在运行:
> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0092c03e1eba nginx:latest nginx 44 seconds ago Up 41 seconds 0.0.0.0:49153->80/tcp web
如上输出,我们的容器监听的是80端口,Docker将80端口的请求代理到host上的一个随机端口上,49153。
curl发送请求:
> curl localhost:49153
curl: (7) Failed connect to localhost:49153; Connection refused
请求失败,为什么呢?
Docker将容器80端口的请求,转发到host的49153端口上。如果是linux,host的ip地址就是localhost,但是在mac上,host不是localhost,而是boot2docker。
解决办法: 使用虚拟机的ip地址
boot2docker使用一条命令就可以获取到虚拟机的ip地址:
> boot2docker ip
The VM’s Host only interface IP address is: 192.168.59.103
再试一下curl请求:
> curl $(boot2docker ip):49153
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
[ ... ]
也可以在浏览器中请求:
成功了,下面可以停止、删除这个容器:
docker stop web
docker rm web
问题2: 挂载Volumes
问题描述:Docker从boot2docker中挂载Volumes,而非OS X
Docker支持Volumes:我们可以将host机器上的一个目录挂载到容器里。Volumes是容器方位host机器资源的一种方式。比如我们可以启动一个nginx容器,它可以访问host机器上的资源文件。
首先,创建一个目录,新建index.html
文件:
> cd /Users/Chris
> mkdir web
> cd web
> echo 'yay!' > index.html
在你自己的机器上,记得使用自己的路径。
然后,我们启动另外一个nginx容器,这一次把上面新建的目录挂载到nginx中:
> docker run -d -P -v /Users/Chris/web:/usr/local/nginx/html --name web nginx
485386b95ee49556b2cf669ea785dffff2ef3eb7f94d93982926579414eec278
配置端口:
> docker port web 80
0.0.0.0:49154
curl一下:
> curl dockerhost:49154
<html>
<head><title>403 Forbidden</title></head>
<body bgcolor="white">
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.7.1</center>
</body>
</html>
问题出现了,Docker尝试去挂载host机器的/Users/Chris/web
路径到容器中,但是在mac上host机器是boot2docker
, 不是OS X. boot2docker
不会访问MS X的资源。
解决方法: 将OS X的/Usres
目录挂载到虚拟机中。
把/Users
路径挂载到虚拟机中,boot2docker
就能访问/Users
中的资源了。
boot2docker不支持VirtualBox挂载文件,我们需要安装特定的boot2docker。
首先,删除容器,关掉虚拟机:
> docker stop web
> docker rm web
> boot2docker down
然后,下载特定的boot2docker:
> curl http://static.dockerfiles.io/boot2docker-v1.2.0-virtualbox-guest-additions-v4.3.14.iso > ~/.boot2docker/boot2docker.iso
最后,挂载目录,启动虚拟机:
> VBoxManage sharedfolder add boot2docker-vm -name home -hostpath /Users
> boot2docker up
更换boot2docker镜像,不会造成数据丢失,不要担心。
再试一下:
> docker run -d -P -v /Users/Chris/web:/usr/local/nginx/html --name web nginx
0d208064a1ac3c475415c247ea90772d5c60985841e809ec372eba14a4beea3a
> docker port web 80
0.0.0.0:49153
> curl dockerhost:49153
yay!
如果你修改了index.html文件,但是curl的时候,没有效果。那是因为nginx默认打开了sendfile
,这个命令在VirtualBox中兼容的不是很好。结果办法是在nginx配置文件中关闭sendfile
。
问题3:进入容器内部
问题: 如何进入到容器内部?
如何通过shell进入到容器内容呢。
解决方法:Linux Magic
使用nsenter. nsenter允许你在内核空间中执行命令。由于docker容器就是运行在它自己的内核空间中的一个程序,所以我们也可以在docker容器中打开一个shell。
下面的命令会运行在不同的shell下,这些环境用下面的符号表示:
- > 表示OS X环境
- $ 表示boot2docker虚拟机环境
- % 表示Docker容器内部环境
首先,我们进入到boot2docker虚拟机中:
> boot2docker ssh
然后,安装nsenter
:
$ docker run --rm -v /var/lib/boot2docker:/target jpetazzo/nsenter
最后,把/var/lib/boot2docker
加入到虚拟机的环境变量中:
$ echo 'export PATH=/var/lib/boot2docker:$PATH' >> ~/.profile
$ source ~/.profile
我们可以使用nsenter了:
$ which nsenter
/var/lib/boot2docker/nsenter
启动nginx容器,来看一下是否生效(注意,此时仍旧在虚拟机的ssh中):
$ docker run -d -P --name web nginx
f4c1b9530fefaf2ac4fedac15fd56aa4e26a1a01fe418bbf25b2a4509a32957f
想要进入到容器内部,nsenter需要知道容器的pid:
$ PID=$(docker inspect --format '{{ .State.Pid }}' web)
最终:
$ sudo nsenter -m -u -n -i -p -t $PID
% hostname
f4c1b9530fef
当前就是在容器内部了。来确认下,我们在容器内部,通过ps来查看当前的进程(当然需要先安装ps)
% apt-get update
% apt-get install -y procps
% ps -A
PID TTY TIME CMD
1 ? 00:00:00 nginx
8 ? 00:00:00 nginx
29 ? 00:00:00 bash
237 ? 00:00:00 ps
% exit
还可以这样用:
$ sudo docker-enter web ps -A
PID TTY TIME CMD
1 ? 00:00:00 nginx
8 ? 00:00:00 nginx
245 ? 00:00:00 ps
ok,现在进入到容器内部已经完全没有问题了,但是我们想更方便一下,如何在OS X中直接在容器中执行命令。这个也是支持的,不过要一段bash脚本:
#!/bin/bash
set -e
# Check for nsenter. If not found, install it
boot2docker ssh '[ -f /var/lib/boot2docker/nsenter ] || docker run --rm -v /var/lib/boot2docker/:/target jpetazzo/nsenter'
# Use bash if no command is specified
args=$@
if [[ $# = 1 ]]; then
args+=(/bin/bash)
fi
boot2docker ssh -t sudo /var/lib/boot2docker/docker-enter "${args[@]}"
将这段脚本保存成shell文件,加到环境变量中,就可以如下执行:
> docker-enter web
% hostname
f4c1b9530fef
版权声明
本站文章、图片、视频等(除转载外),均采用知识共享署名 4.0 国际许可协议(CC BY-NC-SA 4.0),转载请注明出处、非商业性使用、并且以相同协议共享。
© 空空博客,本文链接:https://www.yeetrack.com/?p=1170
近期评论