OSX环境Docker折腾

我的运行环境是macOS High Sierra 10.13.3,以前在MAC上安装Docker用的是toolbox,这次就直接用boot2docker来玩,但是brew安装真是超级慢,就直接在github上下载pkg安装文件

链接:https://github.com/boot2docker/osx-installer/releases/download/v1.8.0/Boot2Docker-1.8.0.pkg

下载下来之后安装的时候这里要注意一下

可以看到除了必选的Docker相关之外,VirtualBox也在里面,Docker的实现依赖Linux namespace,cgroup等,也就是十分依赖Linux内核,而OSX毕竟不是Linux,因此这里实际上的玩法还是安装VirtualBox,起一个Linux虚拟机,然后再来起Docker,但是这里可以不用勾选,因为现在OSX的版本已经原生支持docker,不用起虚拟机

安装完通过boot2docker init启动的时候,报了一大波错误

✘ lihui@MacBook  ~  boot2docker init
failed MSpanList_Insert 0x5ab000 0x188234f47528b 0x0
fatal error: MSpanList_Insert

runtime stack:
runtime.throw(0x51c1ab)
	/usr/src/go/src/runtime/panic.go:491 +0xad fp=0x7ffeefbff600 sp=0x7ffeefbff5d0
runtime.MSpanList_Insert(0x542d28, 0x5ab000)
	/usr/src/go/src/runtime/mheap.c:692 +0x8f fp=0x7ffeefbff628 sp=0x7ffeefbff600
MHeap_FreeSpanLocked(0x53f920, 0x5ab000, 0x100)
	/usr/src/go/src/runtime/mheap.c:583 +0x163 fp=0x7ffeefbff668 sp=0x7ffeefbff628
MHeap_Grow(0x53f920, 0x8, 0x0)
	/usr/src/go/src/runtime/mheap.c:420 +0x1a8 fp=0x7ffeefbff6a8 sp=0x7ffeefbff668
MHeap_AllocSpanLocked(0x53f920, 0x1, 0x0)
	/usr/src/go/src/runtime/mheap.c:298 +0x365 fp=0x7ffeefbff6e8 sp=0x7ffeefbff6a8
mheap_alloc(0x53f920, 0x1, 0x12, 0x0)
	/usr/src/go/src/runtime/mheap.c:190 +0x121 fp=0x7ffeefbff710 sp=0x7ffeefbff6e8
runtime.MHeap_Alloc(0x53f920, 0x1, 0x10000000012, 0x1eaa9)
	/usr/src/go/src/runtime/mheap.c:240 +0x66 fp=0x7ffeefbff748 sp=0x7ffeefbff710
MCentral_Grow(0x547698, 0x0)
	/usr/src/go/src/runtime/mcentral.c:197 +0x8b fp=0x7ffeefbff7b0 sp=0x7ffeefbff748
runtime.MCentral_CacheSpan(0x547698, 0x0)
	/usr/src/go/src/runtime/mcentral.c:85 +0x167 fp=0x7ffeefbff7e8 sp=0x7ffeefbff7b0
runtime.MCache_Refill(0x5a7000, 0x12, 0x0)
	/usr/src/go/src/runtime/mcache.c:90 +0xa0 fp=0x7ffeefbff810 sp=0x7ffeefbff7e8
runtime.mcacheRefill_m()
	/usr/src/go/src/runtime/malloc.c:368 +0x57 fp=0x7ffeefbff830 sp=0x7ffeefbff810
runtime.onM(0x428178)
	/usr/src/go/src/runtime/asm_amd64.s:273 +0x9a fp=0x7ffeefbff838 sp=0x7ffeefbff830
runtime.mallocgc(0x120, 0x36f5e0, 0x0, 0x0)
	/usr/src/go/src/runtime/malloc.go:178 +0x849 fp=0x7ffeefbff8e8 sp=0x7ffeefbff838
runtime.newobject(0x36f5e0, 0x5a7000)
	/usr/src/go/src/runtime/malloc.go:353 +0x49 fp=0x7ffeefbff910 sp=0x7ffeefbff8e8
runtime.newG(0x37bda)
	/usr/src/go/src/runtime/proc.go:233 +0x2a fp=0x7ffeefbff928 sp=0x7ffeefbff910
allocg(0x530000)
	/usr/src/go/src/runtime/proc.c:925 +0x1f fp=0x7ffeefbff938 sp=0x7ffeefbff928
runtime.malg(0x8000, 0x5301c0)
	/usr/src/go/src/runtime/proc.c:2106 +0x1f fp=0x7ffeefbff968 sp=0x7ffeefbff938
runtime.mpreinit(0x530940)
	/usr/src/go/src/runtime/os_darwin.c:137 +0x27 fp=0x7ffeefbff980 sp=0x7ffeefbff968
mcommoninit(0x530940)
	/usr/src/go/src/runtime/proc.c:201 +0xc9 fp=0x7ffeefbff9a8 sp=0x7ffeefbff980
runtime.schedinit()
	/usr/src/go/src/runtime/proc.c:138 +0x55 fp=0x7ffeefbff9d0 sp=0x7ffeefbff9a8
runtime.rt0_go(0x7ffeefbffa00, 0x2, 0x7ffeefbffa00, 0x0, 0x2, 0x7ffeefbffb78, 0x7ffeefbffb84, 0x0, 0x7ffeefbffb89, 0x7ffeefbffbc5, ...)
	/usr/src/go/src/runtime/asm_amd64.s:95 +0x116 fp=0x7ffeefbff9d8 sp=0x7ffeefbff9d0

看这样子好像是go依赖库的问题,八成是go版本的问题,更新到1.10版本,再试了下,还是如此,搜了半天网上的解决方案都没效果,但是有人这个版本的确pkg程序安装的启动成功了,暂时没找到原因在哪里,再次回到Release链接看了看,有这样一个备注

Deprecated

This project (the boot2docker OS X Installer) is officially deprecated in favor of the new Docker Toolbox.

汗了,这个意思是这个启动程序废弃了?还是要用Toolbox?

下载链接:https://download.docker.com/mac/stable/DockerToolbox.pkg

具体参考文档:https://docs.docker.com/toolbox/toolbox_install_mac/ 

它这里提示不要修改default,那么VBox就还是勾上

By default, the standard Docker Toolbox installation:

  • installs binaries for the Docker tools in /usr/local/bin
  • makes these binaries available to all users
  • updates any existing Virtual Box installation

For now, don’t change any of the defaults.

 但是安装完之后,docker quickstart terminal启动有误

“iTerm”遇到一个错误:No profile exists named 'Default'

不明觉厉啥玩意,看下这个可执行程序docker quickstart terminal的启动脚本,目录在:/Applications/Docker/Docker\ Quickstart\ Terminal.app/Contents/Resources/Scripts/start.sh

#!/bin/bash

VM=default
DOCKER_MACHINE=/usr/local/bin/docker-machine
VBOXMANAGE=/Applications/VirtualBox.app/Contents/MacOS/VBoxManage

BLUE='\033[0;34m'
GREEN='\033[0;32m'
NC='\033[0m'

unset DYLD_LIBRARY_PATH
unset LD_LIBRARY_PATH

#clear all_proxy if not socks address
if [[ $ALL_PROXY != socks* ]]; then
unset ALL_PROXY
fi
if [[ $all_proxy != socks* ]]; then
unset all_proxy
fi

clear

if [ ! -f "${DOCKER_MACHINE}" ]; then
echo "Docker Machine is not installed. Please re-run the Toolbox Installer and try again."
exit 1
fi

if [ ! -f "${VBOXMANAGE}" ]; then
echo "VirtualBox is not installed. Please re-run the Toolbox Installer and try again."
exit 1
fi

"${VBOXMANAGE}" list vms | grep \""${VM}"\" &> /dev/null
VM_EXISTS_CODE=$?

if [ $VM_EXISTS_CODE -eq 1 ]; then
"${DOCKER_MACHINE}" rm -f "${VM}" &> /dev/null
rm -rf ~/.docker/machine/machines/"${VM}"
#set proxy variables if they exists
if [ "${HTTP_PROXY}" ]; then
PROXY_ENV="$PROXY_ENV --engine-env HTTP_PROXY=$HTTP_PROXY"
fi
if [ "${HTTPS_PROXY}" ]; then
PROXY_ENV="$PROXY_ENV --engine-env HTTPS_PROXY=$HTTPS_PROXY"
fi
if [ "${NO_PROXY}" ]; then
PROXY_ENV="$PROXY_ENV --engine-env NO_PROXY=$NO_PROXY"
fi
"${DOCKER_MACHINE}" create -d virtualbox $PROXY_ENV --virtualbox-memory 2048 --virtualbox-disk-size 204800 "${VM}"
fi

VM_STATUS="$( set +e ; ${DOCKER_MACHINE} status ${VM} )"
if [ "${VM_STATUS}" != "Running" ]; then
"${DOCKER_MACHINE}" start "${VM}"
yes | "${DOCKER_MACHINE}" regenerate-certs "${VM}"
fi

eval "$(${DOCKER_MACHINE} env --shell=bash --no-proxy ${VM})"

clear
cat << EOF


## .
## ## ## ==
## ## ## ## ## ===
/"""""""""""""""""\___/ ===
~~~ {~~ ~~~~ ~~~ ~~~~ ~~~ ~ / ===- ~~~
\______ o __/
\ \ __/
\____\_______/


EOF
echo -e "${BLUE}docker${NC} is configured to use the ${GREEN}${VM}${NC} machine with IP ${GREEN}$(${DOCKER_MACHINE} ip ${VM})${NC}"
echo "For help getting started, check out the docs at https://docs.docker.com"
echo

USER_SHELL="$(dscl /Search -read /Users/${USER} UserShell | awk '{print $2}' | head -n 1)"
if [[ "${USER_SHELL}" == *"/bash"* ]] || [[ "${USER_SHELL}" == *"/zsh"* ]] || [[ "${USER_SHELL}" == *"/sh"* ]]; then
"${USER_SHELL}" --login
else
"${USER_SHELL}"
fi

捋一捋,也就是说这个启动脚本实际上是通过terminal来启动一个default虚拟机,而这个虚拟机没有,用命令行查一下,的确没有

lihui@MacBook  ~  docker-machine ls
NAME   ACTIVE   DRIVER   STATE   URL   SWARM   DOCKER   ERRORS

那么问题来了,出现这种情况有两种可能,要么我用的Iterm2的问题导致这个脚本根本没执行,导致应用程序启动失败,要么这个脚本执行了,中间出错退出

既然有思路了,那就测试一把,很好说,手动执行以下这个start.sh脚本,如果出错退出那就看哪一行报错;如果正常执行,那就是Iterm2的锅,手动执行一次shell脚本即可

lihui@MacBook  /Applications/Docker/Docker Quickstart Terminal.app/Contents/Resources/Scripts  sh start.sh
Running pre-create checks...
(default) Default Boot2Docker ISO is out-of-date, downloading the latest release...
(default) Latest release for github.com/boot2docker/boot2docker is v17.12.1-ce
(default) Downloading /Users/lihui/.docker/machine/cache/boot2docker.iso from https://github.com/boot2docker/boot2docker/releases/download/v17.12.1-ce/boot2docker.iso...
(default) 0%....10%....20%....30%....40%....50%....60%....70%....80%....90%....100%
Creating machine...
(default) Copying /Users/lihui/.docker/machine/cache/boot2docker.iso to /Users/lihui/.docker/machine/machines/default/boot2docker.iso...
(default) Creating VirtualBox VM...
(default) Creating SSH key...
(default) Starting the VM...
(default) Check network to re-create if needed...
(default) Waiting for an IP...
Waiting for machine to be running, this may take a few minutes...
Detecting operating system of created instance...
Waiting for SSH to be available...
Detecting the provisioner...
Provisioning with boot2docker...
Copying certs to the local machine directory...
Copying certs to the remote machine...
Setting Docker configuration on the remote daemon...
Checking connection to Docker...
Docker is up and running!
To see how to connect your Docker Client to the Docker Engine running on this virtual machine, run: /usr/local/bin/docker-machine env default


                        ##         .
                  ## ## ##        ==
               ## ## ## ## ##    ===
           /"""""""""""""""""\___/ ===
      ~~~ {~~ ~~~~ ~~~ ~~~~ ~~~ ~ /  ===- ~~~
           \______ o           __/
             \    \         __/
              \____\_______/


-e docker is configured to use the default machine with IP 192.168.99.100
For help getting started, check out the docs at https://docs.docker.com

完美,看样子启动脚本无误,从过程中也可以看到有创建default虚拟机,不确定的话再查一下

lihui@MacBook  ~  docker-machine ls
NAME      ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER        ERRORS
default   -        virtualbox   Running   tcp://192.168.99.100:2376           v17.12.1-ce

如此一来就确认了问题是终端也就是Iterm2导致的,应该是两者版本兼容性问题导致应用程序里的一个启动脚本无法调用

接着看能否ssh到docker所在的宿主机上,也就是default虚拟机

lihui@MacBook  ~  docker-machine ssh default
                        ##         .
                  ## ## ##        ==
               ## ## ## ## ##    ===
           /"""""""""""""""""\___/ ===
      ~~~ {~~ ~~~~ ~~~ ~~~~ ~~~ ~ /  ===- ~~~
           \______ o           __/
             \    \         __/
              \____\_______/
 _                 _   ____     _            _
| |__   ___   ___ | |_|___ \ __| | ___   ___| | _____ _ __
| '_ \ / _ \ / _ \| __| __) / _` |/ _ \ / __| |/ / _ \ '__|
| |_) | (_) | (_) | |_ / __/ (_| | (_) | (__|   <  __/ |
|_.__/ \___/ \___/ \__|_____\__,_|\___/ \___|_|\_\___|_|
Boot2Docker version 17.12.1-ce, build HEAD : 42357fc - Wed Feb 28 17:52:00 UTC 2018
Docker version 17.12.1-ce, build 7390fc6
docker@default:~$

查看一下是啥Linux系统

docker@default:~$ cat /etc/issue
Core Linux

随便拉一个镜像

docker@default:~$ sudo docker pull ubuntu:17.04
17.04: Pulling from library/ubuntu
c2ca09a1934b: Pull complete
d6c3619d2153: Pull complete
0efe07335a04: Pull complete
6b1bb01b3a3b: Pull complete
43a98c187399: Pull complete
Digest: sha256:5d41c289942008211c2964bca72800f5c9d5ea5aa4057528da617fb36463d4ab
Status: Downloaded newer image for ubuntu:17.04

进入容器

docker@default:~$ docker run -t -i ubuntu:17.04 /bin/bash
root@87d254a9fa83:/# cat /etc/issue
Ubuntu 17.04 \n \l

可惜里面连ip,ifconfig都没有,好像也没法装,不清楚网络啥样的,还是退回到宿主机看看网络

docker@default:~$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: dummy0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 9e:14:32:55:a3:40 brd ff:ff:ff:ff:ff:ff
3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:6d:08:22 brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:fe6d:822/64 scope link
       valid_lft forever preferred_lft forever
4: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:05:71:b9 brd ff:ff:ff:ff:ff:ff
    inet 192.168.99.100/24 brd 192.168.99.255 scope global eth1
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:fe05:71b9/64 scope link
       valid_lft forever preferred_lft forever
6: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
    link/ether 02:42:2a:58:79:17 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:2aff:fe58:7917/64 scope link
       valid_lft forever preferred_lft forever

因为容器里暂时看不到网络,可能和镜像有关,就没法看网桥的连接了,宿主机上直接ping外网,居然直接通了

docker@default:~$ ping 114.114.114.114
PING 114.114.114.114 (114.114.114.114): 56 data bytes
64 bytes from 114.114.114.114: seq=0 ttl=63 time=19.826 ms
64 bytes from 114.114.114.114: seq=1 ttl=63 time=15.110 ms
64 bytes from 114.114.114.114: seq=2 ttl=63 time=18.973 ms
64 bytes from 114.114.114.114: seq=3 ttl=63 time=17.182 ms
64 bytes from 114.114.114.114: seq=4 ttl=63 time=16.056 ms
64 bytes from 114.114.114.114: seq=5 ttl=63 time=16.814 ms

根据路由表可以看到走的默认路由,下一跳10.0.2.2,这个网段肯定就是VBox做NAT的网段

docker@default:~$ ip r
default via 10.0.2.2 dev eth0  metric 1
10.0.2.0/24 dev eth0  proto kernel  scope link  src 10.0.2.15
127.0.0.1 dev lo  scope link
172.17.0.0/16 dev docker0  proto kernel  scope link  src 172.17.0.1
192.168.99.0/24 dev eth1  proto kernel  scope link  src 192.168.99.100

但MAC上可以抓到ICMP包

lihui@MacBook  ~  sudo tshark icmp
Capturing on 'Wi-Fi'
    1   0.000000 192.168.100.7 → 114.114.114.114 ICMP 98 Echo (ping) request  id=0x7b15, seq=8/2048, ttl=63
    2   0.013605 114.114.114.114 → 192.168.100.7 ICMP 98 Echo (ping) reply    id=0x7b15, seq=8/2048, ttl=88 (request in 1)
    3   1.000911 192.168.100.7 → 114.114.114.114 ICMP 98 Echo (ping) request  id=0x7b15, seq=9/2304, ttl=63
    4   1.015851 114.114.114.114 → 192.168.100.7 ICMP 98 Echo (ping) reply    id=0x7b15, seq=9/2304, ttl=95 (request in 3)
    5   2.001226 192.168.100.7 → 114.114.114.114 ICMP 98 Echo (ping) request  id=0x7b15, seq=10/2560, ttl=63
    6   2.015803 114.114.114.114 → 192.168.100.7 ICMP 98 Echo (ping) reply    id=0x7b15, seq=10/2560, ttl=65 (request in 5)
    7   3.001417 192.168.100.7 → 114.114.114.114 ICMP 98 Echo (ping) request  id=0x7b15, seq=11/2816, ttl=63
    8   3.021323 114.114.114.114 → 192.168.100.7 ICMP 98 Echo (ping) reply    id=0x7b15, seq=11/2816, ttl=65 (request in 7)
    9   4.002379 192.168.100.7 → 114.114.114.114 ICMP 98 Echo (ping) request  id=0x7b15, seq=12/3072, ttl=63

当然最终还是从MAC的物理网卡出去的

下次换个镜像再研究下网络,bridge

至于卸载,刚扫了一眼,docker,virtualbox以及各种镜像残留很多,如果需要full uninstall,可参考这个链接:https://therealmarv.com/how-to-fully-uninstall-the-offical-docker-os-x-installation/

发表回复