如何應用Docker?簡明教程告訴你
Docker已經迅速發展了一段時間,不少同學可能都在對Docker的應用,實際的應用,解決開發和運營中的實際問題,如何應用Docker,對docker能做什麼有了更多的需求,為此,我整理了一份 Docker應用教程 ,致力提供更多的 Docker應用案例和問題解決。初學的同學還請有先按本文了解docker的基本操作。
Docker 是個容器,像個碗或者盆,其實更像個櫥櫃 帶格子的那種.
你可以把喜歡的東西放在各種各種的格子裡,然後不管櫥櫃搬到哪,就你在裡面放置的好玩意不會變。
這樣你就可以輕鬆的在ubuntu上執行一個centos
下面是老外做的一個不是很直觀也能看明白的直觀圖,對比docker和VM的不同:
這裡有映象可以下載 these slides(link is external) 都是Docker提供的(不足最近github的訪問速度是真xxx,隨意最好找找有沒有代理加快下載,如果對docker不瞭解,還是要謹慎一些,二次釋出的映象,也許會有問題).
獲取docker
docker對mac支援不是很好,可以用boot2docker(link is external)來解決.老外推薦使用CoreOs來操作Vagrant(這又是一個神器,將來會陸續在我的網站出現,請持續關注)
老外在這裡強烈推薦CoreOS,說怎麼怎麼好,我還是推薦先使用ubuntu或者在windows上裝個vbox在用ubuntu,coreos作為一個新型的伺服器級別的系統,也十分值得關注,因為CoreOs將作為主力的docker容器發展。下面這一段是老外將他在CoreOS安裝docker的事,主要是 Vagrantfile (這是一個Vagrant可以識別的配置檔案):
config.vm.box ="coreos" config.vm.box_url ="http://storage.core-os.net/coreos/amd64-generic/dev-channel/coreos_production_vagrant.box" config.vm.network "private_network", ip:"172.12.8.150"
如果使用NFS 就加下面一段:
# This will require sudo access when using "vagrant up" config.vm.synced_folder ".","/home/core/share", id:"core",:nfs =>true,:mount_options =>['nolock,vers=3,udp']
如果使用vmware不使用virtualbox:
config.vm.provider :vmware_fusion do|vb,override|override.vm.box_url ="http://storage.core-os.net/coreos/amd64-generic/dev-channel/coreos_production_vagrant_vmware_fusion.box"end
最好要加上一個外掛:
# plugin conflictifVagrant.has_plugin?("vagrant-vbguest")then
config.vbguest.auto_update =falseend
如果在CoreOS上操作過程中,提示重啟,請不要擔心,這是為了啟用特性所做的操作
下面為docker正式內容
你的第一個容器
第一步嘗試是必須的,雖然你可能不是直接發現docker的強大,但是足以“管中窺豹”(這老外比我都羅嗦)
docker有一些基礎的容器,也接受民間提供製作好的容器,以後你如果想貢獻,也可以在這裡 index.docker.io(link is external) 釋出自己的容器.
最流行最基礎的Docker映象還是“Ubuntu”
如果沒有這個映象,那麼需要下載~
Run Bash:
docker run ubuntu /bin/bash
什麼事情都沒有發生! 哈哈, 實際上已經有東西運行了. 執行 docker ps (像在linux主機上執行 ps) – 你什麼容器也看不到,一個程序都沒有(這老外~尼瑪). Run docker ps -a, 見證奇蹟的時刻!
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8ea31697f021 ubuntu:12.04/bin/bash About a minute ago Exit0 loving_pare
我們已經可以看到一個在執行的 /bin/bash
, 但是沒有任何程序在維持它的執行.一個docker容器是伴隨程序執行的.
先記住上面說的. 讓我們繼續操作docker,來玩一會兒:
docker run -t -i ubuntu /bin/bash
現在你可以看到你已經以root的身份登入到了docker 容器!
這些命令都在做什麼?
docker run
– 執行一個容器-i
– 開發輸入(so we can interact with it)ubuntu
– 使用ubuntu基礎映象/bin/bash
– 執行bash shell
跟進改變
使用 (ctrl+d
or type exit
) 來退出然後繼續執行 docker ps -a
. :
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
30557c9017ec ubuntu:12.04/bin/bash About a minute ago Exit127 elegant_pike
8ea31697f021 ubuntu:12.04/bin/bash 22 minutes ago Exit0 loving_pare
複製貼上現在執行的容器 ID (30557c9017ec in my case). 執行docker diff <container id>. :
[email protected] ~ $ docker diff 30557c9017ec
A /.bash_history
C /dev
A /dev/kmsg
我們可以看到我們僅僅登入了 bash之後的改變,建立了 .bash_history
file, a /dev
directory and a/dev/kmsg
file. 這是細微的變化,確實偉大的存在! Docker 會跟蹤我們在容器中的所有改動. 事實上,docker就是執行我們創造改動,提交改動,釋出改動,然後將改變帶到任何地方. 這就是我們使用docker所依賴的基礎.
下面我們就來安裝點新玩意到容器中,讓把它們打包成我們自己的.
# Get into Bash
docker run -t -i ubuntu /bin/bash
# Install some stuff
apt-get update
apt-get install -y git ack-grep vim curl wget tmux build-essential python-software-properties
等這些都執行完了之後,退出,再執行 docker ps -a . 在複製最新的ID (docker diff <Container ID>):
[email protected] ~ $ docker diff 5d4bdae290a4> A TON OF FILE LISTED HERE
當然又有很多的新檔案被新增. 下面我們就來打包我們的版本,為了以後更好的使用.我們將提交修改,給它命名並打上標籤。 我們將使用: docker commit <Container ID> <Name>:<Tag>
[email protected] ~ $ docker commit 5d4bdae290a4 fideloper/docker-example:0.1
c07e8dc7ab1b1fbdf2f58c7ff13007bc19aa1288add474ca358d0428bc19dba6 # You'll get a long hash as a Success message
我們來看看我們打包好的映象. Run docker images:
[email protected] ~ $ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
fideloper/docker-example 0.1 c07e8dc7ab1b 22 seconds ago 455.1 MB
ubuntu 13.109f676bd305a46 weeks ago 178 MB
ubuntu saucy 9f676bd305a46 weeks ago 178 MB
ubuntu 13.04 eb601b8965b8 6 weeks ago 166.5 MB
ubuntu raring eb601b8965b8 6 weeks ago 166.5 MB
ubuntu 12.105ac751e8d6236 weeks ago 161 MB
ubuntu quantal 5ac751e8d6236 weeks ago 161 MB
ubuntu 10.049cc9ea5ea5406 weeks ago 180.8 MB
ubuntu lucid 9cc9ea5ea5406 weeks ago 180.8 MB
ubuntu 12.049cd978db300e6 weeks ago 204.4 MB
ubuntu latest 9cd978db300e6 weeks ago 204.4 MB
ubuntu precise 9cd978db300e6 weeks ago 204.4 MB
你已經注意到了那麼多的ubuntu啊. 當我第一次載入使用ubuntu基礎映象的時候,就已經載入相應的ubuntu標記,更多知識請瀏覽 Docker index(link is external).
非常有趣,不管怎樣我們已經用了自己的映象 叫做 fideloper/docker-example
並且有個版本標籤0.1
!
使用 Dockerfile 建立一個伺服器
讓我們使用Dockerfile來建立一個伺服器,大概就是通過一個配置檔案,讓git和wget自動的完成這個伺服器環境的搭建工作.
建立一個目錄,然後cd進去,因為我們要使用nginx伺服器,就需要有個預設的配置檔案.
建立一個叫做 default
的配置檔案:
server {
root /var/www;
index index.html index.htm;# Make site accessible from http://localhost/
server_name localhost;
location /{# First attempt to serve request as file, then# as directory, then fall back to index.html
try_files $uri $uri//index.html;}}
這就是nginx的基礎配置了.
下面我們建立一個 Dockerfile
並新增如下內容, 修改映象FROM為我們自己的映象(多麼happy):
FROM fideloper/docker-example:0.1
RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe">/etc/apt/sources.list
RUN apt-get update
RUN apt-get-y install nginx
RUN echo "daemon off;">>/etc/nginx/nginx.conf
RUN mkdir /etc/nginx/ssl
ADD default/etc/nginx/sites-available/default
EXPOSE 80
CMD ["nginx"]
這些東西有都是什麼的?
FROM
告訴docker使用哪個映象,用什麼版本RUN
以root使用者身份來執行linux命令ADD
複製檔案到容器內- 這是一個非常方便來管理配置檔案的方式
EXPOSE
暴露埠給主機,也可以新增更多的埠比如:EXPOSE 80 443 8888
CMD
執行一個命令 (但不是以sh -c
). 這通常是來執行長時間的程序,但是我們只是來啟動nginx.- 在生產環境中,我們想看到nginx在執行失敗的情況下的表現
儲存好這些,讓我們來build一個新映象
docker build -t nginx-example .
如果它正常工作了並結束 Successfully built 88ff0cf87aba
(這個容器ID並不一定都是一樣的).
檢查一下你有獲得的什麼映象 docker images
:
[email protected] ~/webapp $ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
nginx-example latest 88ff0cf87aba35 seconds ago 468.5 MB
fideloper/docker-example 0.1 c07e8dc7ab1b 29 minutes ago 455.1 MB
...other Ubuntu images below ...
再執行一下 docker ps -a:
[email protected] ~/webapp $ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
de48fa2b142b 8dc0de13d8be/bin/sh -c #(nop) CM About a minute ago Exit 0 cranky_turing84c5b21feefc2eb367d9069c/bin/sh -c #(nop) EX About a minute ago Exit 0 boring_babbage3d3ed53987ec77ca921f5eef/bin/sh -c #(nop) AD About a minute ago Exit 0 sleepy_brattain
b281b7bf017f cccba2355de7 /bin/sh -c mkdir /et About a minute ago Exit0 high_heisenberg
56a84c7687e9 fideloper/docker-e.../bin/sh -c #(nop) MA 4 minutes ago Exit 0 backstabbing_turing... other images ...
你可以看到 每一行Dockerfile中的指令, 一個新的容器已經誕生 if that line results in a change to the image used. Similar(ish) to version control! (Also, how funny is the name “backstabbing_turing”?)(這一段很難明白?難道又是老外在用,英語文化開玩笑,希望給個指點)
最後,執行這個web服務
讓我們來執行web伺服器! 使用 docker run -p 80:80 -d nginx-example
(確定你要使用的名稱).
[email protected] ~/webapp $ docker run -d nginx-example
73750fc2a49f3b7aa7c16c0623703d00463aa67ba22d2108df6f2d37276214cc# Success!
[email protected] ~/webapp $ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a085a33093f4 nginx-example:latest nginx 2 seconds ago Up2 seconds 80/tcp determined_bardeen
現在我們使用 docker ps 而不是 docker ps -a – 我們可以看到容器中正在執行的程序(回想最初的命令). 執行 curl localhost:
[email protected] ~/webapp $ curl localhost/index.htmld <html><head><title>500InternalServerError</title></head><body bgcolor="white"><center><h1>500InternalServerError</h1></center><hr><center>nginx/1.1.19</center></body></html>
我們看到了nginx的迴應,但是是500錯誤. 這是因為我們並沒有一個index.html 資原始檔讓nginx返回. 讓我們停止這個容器的執行 docker stop <container id>:
[email protected] ~/webapp $ docker stop a085a33093f4
a085a33093f4
來解決一下這個問題,我們來共享一個目錄在主機和容器之間,這樣就用個index.html了,首先建立一個index.html在我們想要貢獻的目錄中
# I'm going to be sharing the /home/core/share directory on my CoreOS machine
echo "Hello, Docker fans!">>/home/core/share/index.html
然後我們再啟動這個容器(注意命令):
docker run -v /home/core/share:/var/www:rw -p 80:80 -d nginx-example
docker run
– 啟動容器-v /path/to/host/dir:/path/to/container/dir:rw
– 指定一個目錄共享到容器,並且指定許可權為讀寫,也可以指定為只讀-p 80:80
– 繫結埠.-d nginx-example
啟動nginx-example的容器,由於在配置檔案的CMD中已經指定啟動了nginx ,在容器啟動時nginx即啟動
執行 curl localhost:
[email protected] ~/webapp $ curl localhost
Hello,Docker fans!
…或者直接訪問主機ip
注意這個ip是主機的ip. 我已經在 Vagrantfile
中指定了ip。我不需要知道要轉發的ip究竟是什麼? 當時可以通過這個命令來看到 docker inspect <Container ID>
.
[email protected] ~/webapp $ docker inspect a0b531aa00f4
[{"ID":"a0b531aa00f475b0025d8edce09961077eedd82a190f2e2f862592375cad4dd5","Created":"2014-03-20T22:38:22.452820503Z",... a lot of JSON ..."NetworkSettings":{"IPAddress":"172.17.0.2","IPPrefixLen":16,"Gateway":"172.17.42.1","Bridge":"docker0","PortMapping":null,"Ports":{"80/tcp":[{"HostIp":"0.0.0.0","HostPort":"80"}]}},... more JSON ...}]
連結不同的容器
現在已經可以將多個容器聯合在一起了 。能將容器聯合在一起,是一項非常重要的技能. 舉個例子, 比如你的web容器想要連結你的資料庫容器. 連結可以讓多個分支應用,獨立於你的應用。
舉個例子:
啟動一個容器,並且取個有意義點的名字 (在這裡就叫, mysql
):
docker run -p 3306:3306-name mysql -d some-mysql-image
啟動你的web容器 將它和另外一個容器連結在一起 -d name:db (where db is an arbitrary name used in the container’s environment variables):
docker run -p 80:80-link mysql:db -d some-application-image
在例子中, some-application-image 有這樣的環境變數設定DB_PORT_3306_TCP_ADDR=172.17.0.8 and DB_PORT_3306_TCP_PORT=3306 用於在應用中的設定
結論
我們就是可以這麼簡單的來建立一臺伺服器,新增應用程式碼,控制應用。執行環境中的每一件事都在你的掌控之中
通過這種方式,我們可以 跳過複雜的環境設定,專心於自己的程式碼.
P.S. – Tips and Tricks
如果執行完了這次體驗,你想自己做點什麼,並且清理掉之前的docker 容器:
- 刪除容器r:
docker rm <Container ID>
- 刪除所有容器:
docker rm $(docker ps -a -q)
- 移除映象:
docker rmi <Container ID>
- 移除所有映象:
docker rmi $(docker ps -a -q)
Note: 在移除映象前,你必須刪除掉,所有依賴於該映象的容器
加入你已經完整體驗了上面的教程,那麼就已經對docker有了很系統的瞭解,因為docker 無非就是用來構建一個可移植環境,為了能有進一步的提高,推薦進行下面的學習:
- docker操作命令,主要熟悉一個常用的操作,docker的命令不多,基本上都會用到,推薦:docker命令詳解
- Dockerfile的編寫,用於建立一個屬於自己的定製化的docker image映象,docker建立映象很簡單,主要是要能夠編寫Dockerfile進行定製,推薦:Dockerfile說明文件
來源:
簡果網
連結:http://www.simapple.com/303.html