寫在前頭
(編者注: 部分摘自網絡,如有雷同那各位看官就湊活看吧哇哈哈)
docker已經逐漸成爲測試人員的基本技能了,在我們使用docker的時候,掌握一些原理,分析一些問題原因對我們能力提升有巨大的幫助。
概念篇
宿主如果和容器系統不同的話,那不是和虛擬機一樣,一層層的調用,那麼 DOCKER 和虛擬機還有什麼差別?(蝸牛語錄)
要把 Windows 和 Linux 分清楚,更要把內核(kernel)和用戶空間(userland)分清楚。
容器內的進程是直接運行於宿主內核的,這點和宿主進程一致,只是容器的 userland 不同,容器的 userland 由容器鏡像提供,也就是說鏡像提供了 rootfs。
假設宿主是 Ubuntu,容器是 CentOS。CentOS 容器中的進程會直接向 Ubuntu 宿主內核發送 syscall,而不會直接或間接的使用任何 Ubuntu 的 userland 的庫。
這點和虛擬機有本質的不同,虛擬機是虛擬環境,在現有系統上虛擬一套物理設備,然後在虛擬環境內運行一個虛擬環境的操作系統內核,在內核之上再跑完整系統,並在裏面調用進程。
還以上面的例子去考慮,虛擬機中,CentOS 的進程發送 syscall 內核調用,該請求會被虛擬機內的 CentOS 的內核接到,然後 CentOS 內核訪問虛擬硬件時,由虛擬機的服務軟件截獲,並使用宿主系統,也就是 Ubuntu 的內核及 userland 的庫去執行。
而且,Linux 和 Windows 在這點上非常不同。Linux 的進程是直接發 syscall 的,而 Windows 則把 syscall 隱藏於一層層的 DLL 服務之後,因此 Windows 的任何一個進程如果要執行,不僅僅需要 Windows 內核,還需要一羣服務來支撐,所以如果 Windows 要實現類似的機制,容器內將不會像 Linux 這樣輕量級,而是非常臃腫。看一下微軟移植的 Docker 就非常清楚了。
所以不要把 Docker 和虛擬機弄混,Docker 容器只是一個進程而已,只不過利用鏡像提供的 rootfs 提供了調用所需的 userland 庫支持,使得進程可以在受控環境下運行而已,它並沒有虛擬出一個機器出來。
具體參考: https://www.docker-cn.com/what-docker
總說看官方文檔,可是 DOCKER 官網文檔經常被牆,看不了怎麼辦?
我們可以本地運行 Docker 官方文檔的網站,以 docker 的方式:
$ docker run -d -p 80:4000 docs/docker.github.io
這樣訪問 Docker 宿主的 80 端口,如 http://localhost,就會看到官網文檔了
DOCKER 1.8 以後版本都有什麼改進麼?
1.10: https://github.com/allencloud/docker-changelog-chinese/blob/master/docker-1.10.0-changelog.md
1.11: https://github.com/allencloud/docker-changelog-chinese/blob/master/docker-1.11.0-changelog.md
1.11.1: https://github.com/allencloud/docker-changelog-chinese/blob/master/docker-1.11.1-changelog.md
1.12: https://github.com/allencloud/docker-changelog-chinese/blob/master/docker-1.12.0-changelog.md
1.13: https://blog.lab99.org/post/docker-2016-11-14-what-is-new-in-docker-1-13.html
安裝和配置問題
如何安裝,安裝哪個版本?
首先,Docker 有好幾個版本,社區版(Community Edition)、企業基礎版(Enterprise Edition Basic)、企業標準版(Enterprise Edition Standard)、企業高級版(Enterprise Edition Advanced)。對於我們一般學習使用而言,使用社區版就已足夠,所以記住CE就可以了。
其次,我們會看到一堆平臺特定的版本,Docker for Mac、Docker for Windows、Docker Toolbox、Docker for Azure、Docker for AWS 等等,還有一堆不同 Linux 的發行版。那我們應該用哪個?其實不難選擇,這都是平臺特定的東西嘛,選擇自己平臺就完了?:
macOS 就選擇 Docker for Mac; 阿里雲(未及時更新):https://mirrors.aliyun.com/docker-toolbox/mac/docker-for-mac/stable/Linux 就選擇自己平臺的 Docker 源: Ubuntu: https://docs.docker.com/engine/installation/linux/docker-ce/ubuntu/ Debian: https://docs.docker.com/engine/installation/linux/docker-ce/debian/ CentOS: https://docs.docker.com/engine/installation/linux/docker-ce/centos/ Fedora: https://docs.docker.com/engine/installation/linux/docker-ce/fedora/Windows 要麻煩些: 如果是 Windows 10 專業版、企業版、教育版,並且版本在 10586 以後,並且不打算在 Docker 運行同時再運行其它虛擬機的情況下,可以裝 Docker for Windows。 阿里雲(未及時更新):https://mirrors.aliyun.com/docker-toolbox/windows/docker-for-windows/stable/ 其它情況都裝 Docker Toolbox 阿里雲:https://mirrors.aliyun.com/docker-toolbox/windows/docker-toolbox/如果是特定雲服務平臺,可以考慮特定服務平臺的版本(當然,這不是必須): AWS:Docker for AWS Azure:Docker for Azure
最後是發佈通道,從2017年初開始,也就是從 1.13 以後,Docker 使用了新的版本號規則,將採用類似 Ubuntu 那種 <年>.<月> 的形式,比如 17.03, 17.06 等。並且,將發佈通道分爲前沿版本(Edge)和穩定版本(Stable)。前沿通道將基本每個月發佈一個版本,而穩定通道將基本每3個月發佈一個版本。這樣 Docker 的發佈將有規律可尋。對於喜歡嚐鮮的可以選擇前沿版本,對於需要穩定的,可以選擇穩定版本。
對於離線安裝docker的(比如一些機器由於內網隔離),可以從官方下載 install with prebuilt 方式來進行安裝,centos的使用rpm包安裝, ubuntu/debian使用deb安裝
DOCKER PULL 好慢啊怎麼辦?
首先,要“感謝”偉大的牆及其親屬。
然後,我們可以使用 Docker 鏡像加速器來解決這個問題,加速器就是鏡像、代理的概念。國內有不少機構提供了免費的加速器以方便大家使用,這裏列出一些常用的加速器服務:
Docker 官方的中國鏡像加速器:從2017年6月9日起,Docker 官方提供了在中國的加速器,以解決牆的問題。不用註冊,直接使用加速器地址:https://registry.docker-cn.com 即可。中國科技大學的鏡像加速器:中科大的加速器不用註冊,直接使用地址 https://docker.mirrors.ustc.edu.cn/ 配置加速器即可。進一步的信息可以訪問:http://mirrors.ustc.edu.cn/help/dockerhub.html?highlight=docker阿里雲加速器:註冊阿里雲開發賬戶(免費的)後,訪問這個鏈接就可以看到加速器地址: https://cr.console.aliyun.com/#/acceleratorDaoCloud 加速器:註冊 DaoCloud 賬戶(支持微信登錄),然後訪問: https://www.daocloud.io/mirror#accelerator-doc
Ubuntu 14.04 配置加速器(或其它使用 Upstart 的系統)
Ubuntu 14.04 是使用 upstart 進行系統初始化的,對於這類系統,可以用通過編輯配置文件的方法來配置加速器。
如果是 Ubuntu 14.04,那麼編輯 /etc/default/docker,在裏面尋找 DOCKER_OPTS 環境變量設置的這一行,在其後添加 -–registry-mirror=<加速器地址>。如果發現該行已被註釋,或者不存在該行,那麼新添一行即可。
比如,在使用官方源安裝了 docker-engine 後,會建立一個默認的 /etc/default/docker,其中相關 DOCKER_OPTS 的行是這樣的:
# Use DOCKER_OPTS to modify the daemon startup options.#DOCKER_OPTS="--dns 8.8.8.8 --dns 8.8.4.4"
假設我們的加速器地址爲 https://registry.docker-cn.com,我們添加一行配置,將其改爲
# Use DOCKER_OPTS to modify the daemon startup options.#DOCKER_OPTS="--dns 8.8.8.8 --dns 8.8.4.4"DOCKER_OPTS="--registry-mirror=https://registry.docker-cn.com"
保存文件後,重啓 Docker 引擎:
$ sudo service docker restartdocker stop/waitingdocker start/running, process 4222
重啓成功後,確認一下配置是否已經生效:
$ sudo ps -ef | grep dockerdroot 3620 1 0 04:26 ? 00:00:00 /usr/bin/dockerd --registry-mirror=https://registry.docker-cn.com --raw-logs
Ubuntu 16.04 或 CentOS 7+ 配置加速器(或其它使用 Systemd 的系統)
Ubuntu 16.04 和 CentOS 7 這類系統都已經開始使用 systemd 進行系統初始化管理了,對於使用 systemd 的系統,應該通過編輯服務配置文件 docker.service 來進行加速器的配置。
在啓用服務後
$ sudo systemctl enable docker
我們可以使用
$ service docker status
得到如下輸出:
root@iflytek-repo:~# service docker status ● docker.service - Docker Application Container Engine Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled) Active: active (running) since 四 2018-01-11 00:22:33 CST; 3 days ago Docs: https://docs.docker.com Main PID: 8558 (dockerd) Tasks: 190 Memory: 1.3G CPU: 54min 20.277s CGroup: /system.slice/docker.service ├─ 8558 /usr/bin/dockerd -H fd:// --insecure-registry harbour.iflytek.com ├─ 8565 docker-containerd --config /var/run/docker/containerd/containerd.toml ├─14069 docker-containerd-shim -namespace moby -workdir /ext/docker/containerd/d
可以看到 該docker service 加載了服務配置文件地址爲:
/lib/systemd/system/docker.service$ vim /lib/systemd/system/docker.service
在文件中找到 ExecStart= 這一行,並且在其行尾添加上所需的配置。假設我們的加速器地址爲 https://registry.docker-cn.com,那麼可以這樣配置:
ExecStart=/usr/bin/dockerd --registry-mirror=https://registry.docker-cn.com
注: Docker 1.12 之前的版本,dockerd 應該換爲 docker daemon,更早的版本則是 docker -d。不過還在用那些版本的童鞋,升級吧……?
保存退出後,重新加載配置並啓動服務:
sudo systemctl daemon-reloadsudo systemctl restart docker
如果配置成功,生效後就會在這裏看到自己所配置的加速器。
在 1.13 版本以後,可以直接 docker info 查看,如果配置成功,加速器 Registry Mirror 會在最下面列出來。
如果重啓後發現無法啓動 docker 服務,檢查一下服務日誌,看看是不是之前執行過那些加速器網站的腳本,如果有做過類似的事情,檢查一下是不是被建立了 /etc/docker/daemon.json 以配置加速器,如果是的話,刪掉這個文件,然後在重啓服務。
使用配置文件是件好事,比如修改配置不必重啓服務,只需發送 SIGHUP 信號即可。但需要注意,目前在 dockerd 中使用配置文件時,無法輸出當前生效配置,並且當 dockerd 的參數和 daemon.json 文件中的配置有所重複時,並不是一個優先級覆蓋另一個,而是會直接導致引擎啓動失敗。很多人發現配了加速器後 Docker 啓動不起來了就是這個原因。解決辦法很簡單,去掉重複項。不過在這些問題解決前,建議使用修改 docker.service 這類做法來實現配置,而不是使用配置文件 daemon.json。方便 ps -ef | grep dockerd 一眼看到實際配置情況。
docker pull 拉去我們的私有鏡像的時候 報 Error Response Https?
在公司內網我們經常會自己搭建如 harbour這樣的鏡像倉庫,爲了省事,我們一般不會去配置HTTPS,即 我們默認提供 http://harbour.dockerregistry.com 這樣域名的倉庫
當我們使用
docker pull harbour.dockerregistry.com/library/ubuntu:latest
這樣的命令時候,可能會報 Error Response Https…
這裏的原因是docker pull 默認會使用https協議去拉去鏡像倉庫的鏡像,無論你的倉庫是否開啓 https。
docker目前不建議使用非HTTPS的HTTP方式,怎麼修改?
參照上一節添加加速器的方式,我們只需要在 DOCKER_OPTS中添加:
UPSTART:
# Use DOCKER_OPTS to modify the daemon startup options.#DOCKER_OPTS="--dns 8.8.8.8 --dns 8.8.4.4"DOCKER_OPTS="--registry-mirror=https://registry.docker-cn.com --insecure-registry=harbour.dockerregistry.com"
SYSTEMD:
ExecStart=/usr/bin/dockerd --registry-mirror=https://registry.docker-cn.com --insecure-registry=harbour.dockerregistry.com
怎麼修改了 docker 服務配置後不起作用?
改動真的生效了麼?在宿主上運行一下 ps -ef | grep dockerd 看看,自己做的那些配置有麼?沒有的話就說明沒有生效,那麼就要檢查原因了。
首先,改完配置重啓服務了麼?雖然這個問題看着很小白,但是確實很多人犯了這個小白的錯誤。
Ubuntu 14.04: sudo service docker restartUbuntu 16.04, CentOS 7: sudo systemctl daemon-reload && sudo systemctl restart docker
另外,你改對了配置文件了麼?
不少人懶得看英文文檔,百度個文章就照着配,既不管百度得到的文章所講的系統,也沒注意版本,而且中文文章往往自身表達描述不清楚,很多想當然的東西,結果無數坑。這麼百度的人,很有可能壓根就改錯了文件。