- 論壇徽章:
- 49
|
【編者的話】之前曾經(jīng)翻譯過很多Docker入門介紹的文章,之所以再翻譯這篇,是因為Anders的角度很獨(dú)特,思路也很調(diào)理。你也可以看下作者的演講稿《Docker, DevOps的未來》。本文介紹了Docker的一些基本概念、誘人的特性、Docker的工作原理、日常管理基本操作,以及一些Docker的問題的解決方案。
![]()
什么是Docker,你應(yīng)該知道些什么?相比很多人的解釋,我相信說Docker是一個輕量級的虛擬機(jī)更容易理解。另外一種解釋是:Docker就是操作系統(tǒng)中的chroot。如果你不知道chroot是什么的話,后一種解釋可能無法幫助你理解什么是Docker。
chroot是一種操作,能改變當(dāng)前運(yùn)行的進(jìn)程和子進(jìn)程的根目錄。 程序運(yùn)行在這樣的一個被修改的環(huán)境中,它不能訪問這個環(huán)境目錄樹之外的文件和命令,這個被修改的環(huán)境就是“chroot牢籠”。
-- Arch Linux 的 wiki 中對 chroot 的解釋 虛擬機(jī) vs. Docker下面這張圖描述了虛擬機(jī)和Docker之間的差異。 在VM中,宿主OS上是hypervisor(虛擬機(jī)監(jiān)視器), 最上層是客戶機(jī)操作系統(tǒng),而Docker則使用Docker引擎和容器。 這樣解釋你能理解嗎? Docker引擎和hypervisor之間的區(qū)別又是什么呢?你可以列出運(yùn)行在宿主OS上的進(jìn)程來理解它們的區(qū)別。
![]()
下面這個簡單的進(jìn)程樹可以看出它們的差異。雖然虛擬機(jī)中運(yùn)行了很多進(jìn)程,但是運(yùn)行虛擬機(jī)的宿主機(jī)上卻只有一個進(jìn)程。
# Running processes on Host for a VM$ pstree VM-+= /VirtualBox.app|--= coreos-vagrant
而運(yùn)行Docker引擎的主機(jī)上則可以看到所有的進(jìn)程。 容器進(jìn)程是運(yùn)行在宿主OS上的!,他們可以通過普通的ps,kill等命令進(jìn)行檢查和維護(hù)。
# Docker在主機(jī)中的進(jìn)程$ pstree docker-+= /docker|--= /bin/sh|--= node server.js|--= go run app|--= ruby server.rb...|--= /bin/bash
所有的東西都是透明的, 意味著什么呢?意味著Docker容器比虛擬機(jī)更小,更快,更容易與其它東西集成。如下圖所示。
![]()
安裝CoreOS的小型虛擬機(jī)居然有1.2GB, 而裝上busybox的小型容器只有2.5MB。最快的虛擬機(jī)啟動時間也是分鐘級的,而容器的啟動時間通常不到一秒。在同一宿主機(jī)上安裝虛擬機(jī)需要正確的設(shè)置網(wǎng)絡(luò), 而安裝Docker非常簡單。
這么來看,容器是輕量、快速并且易集成,但這并不是它的全部!
Docker 是一份合約Docker還是開發(fā)者和運(yùn)維之間的“合約”。 開發(fā)和運(yùn)維在選擇工具和環(huán)境時的姿態(tài)通常差別很大。開發(fā)者想要使用一些閃亮的新東西,比如Node.js、Rust、Go、微服務(wù)、Cassandra、Hadoop、blablabla.........而運(yùn)維則傾向于使用以往用過的工具,因為事實證明那些舊的工具很有效。
但這恰恰是Docker的亮點(diǎn), 運(yùn)維喜歡它,因為Docker讓他們只要關(guān)心一件事: 部署容器, 而開發(fā)者也一樣很開心,只要寫好代碼,然后往容器里一扔,剩下的交給運(yùn)維就完事了。
![]()
不過別急,這還沒完。運(yùn)維還能幫助開發(fā)者構(gòu)建優(yōu)化好的容器以便用于本地開發(fā)。
更好的資源利用很多年前,那時候還沒有虛擬化,當(dāng)我們需要創(chuàng)建一個新服務(wù)時,我們必須申請實際的物理機(jī)硬件。 這可能要花上數(shù)月,依賴于公司的流程。一旦服務(wù)器到位,我們創(chuàng)建好服務(wù),很多時候它并沒有像我們希望的那樣成功,因為服務(wù)器的CPU使用率只有5%。 太奢侈了。
接著,虛擬化來了。它可以在幾分鐘之內(nèi)把一臺機(jī)器運(yùn)轉(zhuǎn)起來,還可以在同一硬件上運(yùn)行多個虛擬機(jī),資源使用率就不只5%了。但是,我們還需要給每個服務(wù)分配一個虛擬機(jī),因此我們還是不能如愿的使用這臺機(jī)器。
容器化是演化進(jìn)程的下一步。容器可以在幾秒之內(nèi)創(chuàng)建起來,而且還能以比虛擬機(jī)更小的粒度進(jìn)行部署。
依賴 ![]()
Docker啟動速度真的很酷。 但是,我們?yōu)槭裁床话阉械亩挤⻊?wù)部署到同一臺機(jī)器上呢? 原因很簡單:依賴的問題。在同一臺機(jī)器上安裝多個獨(dú)立的服務(wù),不管是真是機(jī)器還是虛擬機(jī)都是一場災(zāi)難。用Docker公司的說法是:地獄一樣的矩陣依賴。
而Docker通過在容器中保留依賴關(guān)系解決了矩陣依賴的問題。
速度 ![]()
快當(dāng)然不錯,但是能快100倍就太不可思議了。速度讓很多事情成為可能,增加了更多新的可能性。比如,現(xiàn)在可以快速創(chuàng)建新的環(huán)境,如果需要從Clojure開發(fā)環(huán)境完整的切換到Go語言嗎?啟動一個容器吧。需要為集成和性能測試提供生產(chǎn)環(huán)境DB ?啟動一個容器吧! 需要從Apache切換整個生產(chǎn)環(huán)境到Nginx?啟動容器吧!
Docker是怎么工作的?Docker是一個Client-Server結(jié)構(gòu)的系統(tǒng),Docker守護(hù)進(jìn)程運(yùn)行在主機(jī)上, 然后通過Socket連接從客戶端訪問, 客戶端和守護(hù)進(jìn)程也可以運(yùn)行再同一主機(jī)上,但這不是必須的。Docker命令行客戶端也是類似的工作方式,但它通常通過Unix域套接字而不是TCP套接字連接。
守護(hù)進(jìn)程從客戶端接受命令并管理運(yùn)行在主機(jī)上的容器。
![]()
Docker 概念及相互作用- 主機(jī), 運(yùn)行容器的機(jī)器。
- 鏡像,文件的層次結(jié)構(gòu),以及包含如何運(yùn)行容器的元數(shù)據(jù)
- 容器,一個從鏡像中啟動,包含正在運(yùn)行的程序的進(jìn)程
- Registry, 鏡像倉庫
- 卷,容器外的存儲
- Dockerfile, 用于創(chuàng)建鏡像的腳本
![]()
我們可以通過Dockerfile來構(gòu)建鏡像, 還可以通過commit一個運(yùn)行的容器來創(chuàng)建一個鏡像,這個鏡像可以會被標(biāo)記,可以推到Registry或者從Registry上拉下來,可以通過創(chuàng)建或者運(yùn)行鏡像的方式來啟動容器,可以被stop,也可以通過rm來移除它。
鏡像鏡像是一種文件結(jié)構(gòu),包含如何運(yùn)行容器的元數(shù)據(jù)。Dockerfile中的每條命令都會在文件系統(tǒng)中創(chuàng)建一個新的層次結(jié)構(gòu),文件系統(tǒng)在這些層次上構(gòu)建起來,鏡像就構(gòu)建于這些聯(lián)合的文件系統(tǒng)之上。
![]()
當(dāng)容器啟動后,所有鏡像都會統(tǒng)一合并到一個進(jìn)程中。 聯(lián)合文件系統(tǒng)中的文件被刪除時, 它們只是被標(biāo)記為已刪除,但實際上仍然存在。
# Commands for interacting with images$ docker images # 查看所有鏡像.$ docker import # 從tarball創(chuàng)建鏡像$ docker build # 通過Dockerfile創(chuàng)建鏡像$ docker commit # 從容器中創(chuàng)建鏡像$ docker rmi # 刪除鏡像$ docker history # 列出鏡像的變更歷史
鏡像大小這是一些經(jīng)常使用的鏡像相關(guān)的數(shù)據(jù): - scratch - 基礎(chǔ)鏡像, 0個文件,大小為0
- busybox - 最小Unix系統(tǒng),2.5MB,10000個文件
- debian:jessie - Debian最新版, 122MB, 18000 個文件
- ubuntu:14.04 - 188MB,23000 個文件
創(chuàng)建鏡像可以通過docker commit container-id、docker import url-to-tar或者docker build -f Dockerfile .來創(chuàng)建鏡像。
先看commit的方式:
# 通過commit的方式來創(chuàng)建鏡像$ docker run -i -t debian:jessie bashroot@e6c7d21960:/# apt-get updateroot@e6c7d21960:/# apt-get install postgresqlroot@e6c7d21960:/# apt-get install noderoot@e6c7d21960:/# node --versionroot@e6c7d21960:/# curl https://iojs.org/dist/v1.2.0/iojs-v1.2.0-linux-x64.tar.gz -o iojs.tgzroot@e6c7d21960:/# tar xzf iojs.tgzroot@e6c7d21960:/# lsroot@e6c7d21960:/# cd iojs-v1.2.0-linux-x64/root@e6c7d21960:/# lsroot@e6c7d21960:/# cp -r * /usr/local/root@e6c7d21960:/# iojs --version1.2.0root@e6c7d21960:/# exit$ docker ps -l -qe6c7d21960$ docker commit e6c7d21960 postgres-iojsdaeb0b76283eac2e0c7f7504bdde2d49c721a1b03a50f750ea9982464cfccb1e
從上面可以看出,我們可以通過docker commit來創(chuàng)建鏡像,但是這種方式有點(diǎn)凌亂而且很難復(fù)制, 更好的方式是通過Dockerfile來構(gòu)建鏡像,因為它步驟清晰并且容易復(fù)制:
FROM debian:jessie# Dockerfile for postgres-iojsRUN apt-get updateRUN apt-get install postgresqlRUN curl https://iojs.org/dist/iojs-v1.2.0.tgz -o iojs.tgzRUN tar xzf iojs.tgzRUN cp -r iojs-v1.2.0-linux-x64/* /usr/local
然后用下面的命令來構(gòu)建:
$ docker build -tag postgres-iojs .
Dockerfile中的每一個命令都創(chuàng)建了新版的layer,通常把類似的命令放在一起,通過&&和續(xù)行符號把命令組合起來:
FROM debian:jessie# Dockerfile for postgres-iojsRUN apt-get update && \ apt-get install postgresql && \ curl https://iojs.org/dist/iojs-v1.2.0.tgz -o iojs.tgz && \ tar xzf iojs.tgz && \ cp -r iojs-v1.2.0-linux-x64/* /usr/local
這些行中命令的順序很重要,因為Docker為了加速鏡像的構(gòu)建,會緩存中間的鏡像。 組織Dockerfile的順序時,注意把經(jīng)常變化的行放在文件的底部,當(dāng)緩存中相關(guān)的文件改變時,鏡像會重新運(yùn)行,即使Dockerfile中的行沒有發(fā)生變化也是如此。
Dockerfile 中的命令Dockerfile 支持13個命令, 其中一些命令用于構(gòu)建鏡像,另外一些用于從鏡像中運(yùn)行容器,這是一個關(guān)于命令什么時候被用到的表格:
![]()
BUILD 命令:- FROM - 新鏡像是基于哪個鏡像的
- MAINTAINER - 鏡像維護(hù)者的姓名和郵箱地址
- COPY - 拷貝文件和目錄到鏡像中
- ADD - 同COPY一樣,但會自動處理URL和解壓tarball壓縮包
- RUN - 在容器中運(yùn)行一個命令, 比如:apt-get install
- ONBUILD - 當(dāng)構(gòu)建一個被繼承的Dockerfile時運(yùn)行命令
- .dockerignore - 不是一個命令, 但它能控制什么文件被加入到構(gòu)建的上下文中,構(gòu)建鏡像時應(yīng)該包含.git以及其它的不需要的文件。
RUN 命令:- CMD - 運(yùn)行容器時的默認(rèn)命令,可以被命令行參數(shù)覆蓋
- ENV - 設(shè)置容器內(nèi)的環(huán)境變量
- EXPOSE - 從容器中暴露出端口, 必須顯式的通過在主機(jī)上的RUN命令帶上-p或者-P來暴露端口
- VOLUME - 指定一個在文件系統(tǒng)之后的存儲目錄。如果不是通過docker run -v設(shè)置的, 那么將被創(chuàng)建為/var/lib/docker/volumes
- ENTRYPOINT - 指定一個命令不會被docker run image cmd命令覆蓋。常用于提供一個默認(rèn)的可執(zhí)行程序并使用命令作為參數(shù)。
BUILD, RUN命令都有的命令:- USER - 為RUN、CMD、ENTRYPOINT命令設(shè)置用戶
- WORKDIR - 為RUN、CMD、ENTRYPOINT、ADD、COPY命令設(shè)置工作目錄
![]()
運(yùn)行的容器容器啟動后,進(jìn)程在它可以運(yùn)行的聯(lián)合文件系統(tǒng)中獲得了新的可寫層。
從1.5版本起,它還可以讓最頂層的layer設(shè)置為只讀,強(qiáng)制我們?yōu)樗形募敵觯ㄈ缛罩尽⑴R時文件)使用卷。
# 用于與容器交互的命令$ docker create # 創(chuàng)建一個容器,但不啟動它$ docker run # 創(chuàng)建并啟動一個容器$ docker stop # 停止容器$ docker start # 啟動容器$ docker restart # 重啟容器$ docker rm # 刪除容器$ docker kill # 給容器發(fā)送kill信號$ docker attach # 連接到正在運(yùn)行的容器中$ docker wait # 阻塞直到容器停止為止$ docker exec # 在運(yùn)行的容器中執(zhí)行一條命令
docker run如上所述, docker run是用戶啟動新容器的命令, 這里是一些通用的運(yùn)行容器的方法:
![]()
# 交互式運(yùn)行容器$ docker run -it --rm ubuntu
這是一個可以讓你像普通的終端程序一樣交互式的運(yùn)行容器的方法, 如果你想把管道輸出到容器中,可以使用-t選項。
- --interactive (-i) - 將標(biāo)準(zhǔn)輸入發(fā)送給進(jìn)程
- -tty (-t) - 告訴進(jìn)程有終端連接。 這個功能會影響程序的輸出和它如何處理Ctrx-C等信號。
- --rm - 退出時刪除鏡像。
# 后臺運(yùn)行容器$ docker run -d hadoop
docker run -env# 運(yùn)行一個命名容器并給它傳一些環(huán)境變量$ docker run \--name mydb \--env MYSQL_USER=db-user \-e MYSQL_PASSWORD=secret \--env-file ./mysql.env \mysql - --name - 給容器命名, 否則它是一個隨機(jī)容器
- --env (-e)- 設(shè)置容器中的環(huán)境變量
- --env-file - 從env-file中引入所有環(huán)境變量(同Linux下的source env-file 功能)
- mysql - 指定鏡像名為 mysql:lastest
docker run -publish # 發(fā)布容器的80端口到主機(jī)上的隨機(jī)端口$ docker run -p 80 nginx# 發(fā)布容器端口80和主機(jī)上的8080端口$ docker run -p 8080:80 nginx# 發(fā)布容器80端口到主機(jī)127.0.0.0.1的8080端口$ docker run -p 127.0.0.1:8080:80 nginx# 發(fā)布所有容器中暴露的端口到主機(jī)的隨機(jī)端口上$ docker run -P nginx
nginx 鏡像,比如暴露出80和443端口。
FROM debian:wheezy MAINTAINER NGINX "docker-maint@nginx.com" EXPOSE 80 443
docker run --link # 啟動postgres容器,給它起名為mydb$ docker run --name mydb postgres# 把mydb 鏈接到 myqpp 的db$ docker run --link mydb:db myapp
連接容器需要設(shè)置容器到被連接的容器之間的網(wǎng)絡(luò),有兩件事要做:
- 通過容器的連接名,更新 /etc/hosts 。 在上面的例子中,連接名是db, 可以方便的通過名字db來訪問容器。
- 為暴露的端口設(shè)置環(huán)境變量。這個好像沒啥實際用處,你也可以通過 主機(jī)名:端口的形式訪問對應(yīng)的端口。
docker run limits還可以通過run limits來限制容器可以使用的主機(jī)資源
# 限制內(nèi)存大小$ docker run -m 256m yourapp# 限制進(jìn)程可以使用的cpu份數(shù)(cpu shares)(總CPU份數(shù)為1024)$ docker run --cpu-shares 512 mypp# 改變運(yùn)行進(jìn)程的用戶為www,而不是root(出于安全考慮)$ docker run -u=www nginx
設(shè)置CPU份數(shù)為1024中的512份并不意味著可以使用一半的CPU資源,這意味著在一個無任何限制的容器中,它最多可以使用一半的份數(shù)。比如我們有兩個有1024份的容器,和一個512份的容器(1024:1024:512) ,那么512份的那個容器,就只能得到1/5的總CPU份數(shù)
docker exec containerdocker exec 允許我們在已經(jīng)運(yùn)行的容器內(nèi)部執(zhí)行命令,這點(diǎn)在debug的時候很有用。
# 使用id 6f2c42c0在容器內(nèi)部運(yùn)行shell$ docker exec -it 6f2c42c0 sh
卷 ![]()
卷提供容器外的持久存儲。 這意味著如果你提交了新的鏡像,數(shù)據(jù)將不會被保存。
# Start a new nginx container with /var/log as a volume$ docker run -v /var/log nginx
如果目錄不存在,則會被自動創(chuàng)建為:/var/lib/docker/valumes/ec3c543bc..535
實際的目錄名可以通過命令:docker inspect container-id 找到。
# 啟動新的nginx容器,設(shè)置/var/log為卷,并映射到主機(jī)的/tmp目錄下$ docker run -v /tmp:/var/log nginx
還可以使用--valumes-from選項從別的容器中掛載卷。
# 啟動容器db$ docker run -v /var/lib/postgresql/data --name mydb postgres# 啟動backup容器,從mydb容器中掛載卷$ docker run --volumes-from mydb backup
Docker RegistryDocker Hub是Docker的官方鏡像倉庫,支持私有庫和共有庫,倉庫可以被標(biāo)記為官方倉庫,意味著它由該項目的維護(hù)者(或跟它有關(guān)的人)策劃。
Docker Hub 還支持自動化構(gòu)建來自Github和Bitbucket的項目,如果啟用自動構(gòu)建功能,那么每次你提交代碼到代碼庫都會自動構(gòu)建鏡像。
即使你不想用自動構(gòu)建,你還是可以直接docker push到Docker Hub,Docker pull則會拉取鏡像下來。docker run 一個本地不存在的鏡像,則會自動開始docker pull操作。
你也可以在任意地方托管鏡像,官方有Registry的開源項目,但是,還有很多Bug。
此外,Quay、Tutum和Google 還提供私有鏡像托管服務(wù)。
檢查容器檢查容器的命令有一大把:
$ docker ps # 顯示運(yùn)行的容器$ docker inspect # 顯示容器信息(包括ip地址)$ docker logs # 獲取容器中的日志$ docker events # 獲取容器事件$ docker port # 顯示容器的公開端口$ docker top # 顯示容器中運(yùn)行的進(jìn)程$ docker diff # 查看容器文件系統(tǒng)中改變的文件$ docker stats # 查看各種緯度數(shù)據(jù)、內(nèi)存、CPU、文件系統(tǒng)等
下面詳細(xì)講一下docker ps 和docker inspect,這兩個命令最常用了。
# 列出所有容器,包括已停止的。$ docker ps --allCONTAINER ID IMAGE COMMAND NAMES9923ad197b65 busybox:latest "sh" romantic_fermatfe7f682cf546 debian:jessie "bash" silly_bartik09c707e2ec07 scratch:latest "ls" suspicious_perlmanb15c5c553202 mongo:2.6.7 "/entrypo some-mongofbe1f24d7df8 busybox:latest "true" db_data# Inspect the container named silly_bartik# Output is shortened for brevity.$ docker inspect silly_bartik 1 [{ 2 "Args": [ 3 "-c", 4 "/usr/local/bin/confd-watch.sh" 5 ], 6 "Config": { 10 "Hostname": "3c012df7bab9", 11 "Image": "andersjanmyr/nginx-confd:development", 12 }, 13 "Id": "3c012df7bab977a194199f1", 14 "Image": "d3bd1f07cae1bd624e2e", 15 "NetworkSettings": { 16 "IPAddress": "", 18 "Ports": null 19 }, 20 "Volumes": {}, 22 }]
技巧花招獲取容器id。寫腳本時很有用。
# Get the id (-q) of the last (-l) run container# 獲取最后(-l)一個啟動的容器id(-q)$ docker ps -l -qc8044ab1a3d0
docker inspect可以帶格式化的字符串----Go語言模板作為參數(shù),詳細(xì)描述所需的數(shù)據(jù)。寫腳本時同時有用。
$ docker inspect -f '{{ .NetworkSettings.IPAddress }}' 6f2c42c05500172.17.0.11
使用docker exec來跟運(yùn)行中的容器進(jìn)行交互。
# 獲取容器環(huán)境變量$ docker exec -it 6f2c42c05500 envPATH=/usr/local/sbin:/usr...HOSTNAME=6f2c42c05500REDIS_1_PORT=tcp://172.17.0.9:6379REDIS_1_PORT_6379_TCP=tcp://172.17.0.9:6379...
通過卷來避免每次運(yùn)行時都重建鏡像, 下面是一個Dockerfile,每次構(gòu)建時,會拷貝當(dāng)前目錄到容器中。
1 FROM dockerfile/nodejs:latest 2 3 MAINTAINER Anders Janmyr "anders@janmyr.com" 4 RUN apt-get update && \ 5 apt-get install zlib1g-dev && \ 6 npm install -g pm2 && \ 7 mkdir -p /srv/app 8 9 WORKDIR /srv/app 10 COPY . /srv/app 11 12 CMD pm2 start app.js -x -i 1 && pm2 logs 13
構(gòu)建并運(yùn)行鏡像:
$ docker build -t myapp .$ docker run -it --rm myapp
為避免重建,創(chuàng)建一次性鏡像并在運(yùn)行時掛載本地目錄。
安全 ![]()
大家可能聽說過使用Docker不那么安全。這不是假話,但這不成問題。
目前Docker存在以下安全問題:
- 鏡像簽名未被正確的核準(zhǔn)。
- 如果你在容器中擁有root權(quán)限,那你潛在的擁有對真?zhèn)主機(jī)的root權(quán)限。
安全解決辦法:
- 從你的私有倉庫中使用受信任的鏡像
- 盡量不要以root運(yùn)行容器
- 把容器中的root當(dāng)作是主機(jī)上的root? 還是把容器的根目錄設(shè)置為容器內(nèi)的根目錄 ?
如果服務(wù)器上所有的容器都是你的,那你不需要擔(dān)心他們之間會有危險的交互。
“選擇”容器我給選擇兩字加了引號, 因為目前根本沒有任何別的選擇, 但是很多容器愛好者想玩玩,比如Ubuntu的LXD、微軟的Drawbridge,還有Rocket。
Rocket由CoreOS開發(fā),CoreOS是一個很大的容器平臺。 他們開發(fā)Rocket的理由是覺得Docker公司讓Docker變得臃腫,并且還和CoreOS有業(yè)務(wù)沖突。
他們在這個新的容器中,嘗試移除那些因為歷史原因而留下來的Docker瑕疵。并通過socket activation提供簡單的容器和徹底的安全構(gòu)建。
![]()
編排當(dāng)我們把應(yīng)用程序拆開到多個不同的容器中時,會產(chǎn)生一些新的問題。怎么讓不同的部分進(jìn)行通信呢? 這些容器在單個主機(jī)上怎么辦? 多個主機(jī)上又是怎么處理?
單個主機(jī)上,Docker通過連接來解決編排的問題。
為簡化容器的鏈接操作,Docker提供了一個叫docker-compose的工具。(以前它叫fig, 由另一家公司開發(fā),然后最近Docker收購了他們)
docker-compose ![]()
docker-compose在單個docker-compose.yml文件中聲明多個容器的信息。來看一個例子,管理web和redis兩個容器的配置文件:
1 web: 2 build: . 3 command: python app.py 4 ports: 5 - "5000:5000" 6 volumes: 7 - .:/code 8 links: 9 - redis 10 redis: 11 image: redis
啟動上述容器,可以使用docker-compose up命令
$ docker-compose up Pulling image orchardup/redis... Building web... Starting figtest_redis_1... Starting figtest_web_1... redis_1 | [8] 02 Jan 18:43:35.576 # Server started, Redis version 2.8.3 web_1 | * Running on http://0.0.0.0:5000/
也可以通過detached模式(detached mode)啟動: docker-compose up -d,然后可以通過docker-compose ps查看容器中跑了啥東西:
$ docker-compose up -dStarting figtest_redis_1...Starting figtest_web_1...$ docker-compose psName Command State Ports------------------------------------------------------------figtest_redis_1 /usr/local/bin/run Upfigtest_web_1 /bin/sh -c python app.py Up 5000->5000
還可以同時讓命令在一個容器或者多個容器中同時工作。
# 從web容器中獲取環(huán)境變量$ docker-compose run web env# 擴(kuò)展到多個容器中(Scale to multiple containers)$ docker-compose scale web=3 redis=2# 從所有容器中返回日志信息$ docker-compose logs
從以上命令可以看出,擴(kuò)展很容易,不過應(yīng)用程序必須寫成支持處理多個容器的方式。在容器外,不支持負(fù)載均衡。
Docker托管很多公司想做在云中托管Docker的生意,如下圖。
![]()
這些提供商嘗試解決不同的問題, 從簡單的托管到做"云操作系統(tǒng)"。其中有兩家比較有前景:
CoreOS如上圖所示,CoreOS是可以在CoreOS集群中托管多個容器的一系列服務(wù)的集合:
![]()
- CoreOS Linux發(fā)行版是裁剪的Linux,在初次啟動時使用114MB的RAM,沒有包管理器, 使用Docker或者它自己的Rocket運(yùn)行一切程序。
- CoreOS 使用Docker(或Rocket)在主機(jī)上安裝應(yīng)用。
- 使用systemd作為init服務(wù),它的性能超級好,還能很好的處理啟動依賴關(guān)系, 強(qiáng)大的日志系統(tǒng),還支持socket-activation。
- etcd 是分布式的,一致性 K-V 存儲用于配置共享和服務(wù)發(fā)現(xiàn)。
- fleet,集群管理器,是systemd的擴(kuò)展,能與多臺機(jī)器工作,采用etcd來管理配置并運(yùn)行在每一個臺CoreOS服務(wù)器上。
AWSDocker容器托管在Amazon有兩種途徑:
- Elastic Beanstalk部署Docker容器,它工作的很好,但就是太慢了, 一次全新的部署需要好幾分鐘,感覺跟一般的容器秒級啟動不大對勁。
- ECS、Elastic Container Server是Amazon上游容器集群解決方案, 目前還在預(yù)覽版3,看起來很有前途,跟Amazon其它服務(wù)一樣,通過簡單的web service調(diào)用與它交互。
總結(jié)- Docker is here to stay
- 解決了依賴問題
- 容器各方面都很快
- 有集群解決方案,但不能無縫對接
原文鏈接:A Not Very Short Introduction to Docker(翻譯:何林沖 校對:宋瑜)
=============================
譯者介紹
何林沖, 目前就職于騰訊計算機(jī)系統(tǒng)有限公司, 負(fù)責(zé)游戲自動化運(yùn)維體系架構(gòu)設(shè)計及開發(fā)工作, 熱愛開源技術(shù)。希望通過翻譯技術(shù)文章為社區(qū)貢獻(xiàn)微薄之力。
來源:http://dockone.io/article/277
|
|