如何應用Docker?簡明教程告訴你new

JonCrittend 8年前發布 | 18K 次閱讀 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而是使用其他的,可以在這個頁面  this page(link is external) 找到安裝方式(這個是官方的,這里是民間的 http://www.simapple.com/255.html(link is external) ,陸續完善中). Note: Docker是基于 Ubuntu開發的隨意選擇什么,你懂得。

如果在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  - 運行一個容器
  • -t  - 分配一個(偽)  tty (link is external)
  • -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>. :

core@localhost ~ $ 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>):

core@localhost ~ $ docker diff 5d4bdae290a4> A TON OF FILE LISTED HERE

當然又有很多的新文件被添加. 下面我們就來打包我們的版本,為了以后更好的使用.我們將提交修改,給它命名并打上標簽。 我們將使用: docker commit <Container ID> <Name>:<Tag>

core@localhost ~ $ docker commit 5d4bdae290a4 fideloper/docker-example:0.1 c07e8dc7ab1b1fbdf2f58c7ff13007bc19aa1288add474ca358d0428bc19dba6 # You'll get a long hash as a Success message 

我們來看看我們打包好的鏡像. Run docker images:

core@localhost ~ $ 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 :

core@localhost ~/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:

core@localhost ~/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 (確定你要使用的名稱).

-p 80:80 經容器的80端口 綁定到了主機上 通過curl localhost 或者訪問主機ip就可以看到運行的狀態

core@localhost ~/webapp $ docker run -d nginx-example

73750fc2a49f3b7aa7c16c0623703d00463aa67ba22d2108df6f2d37276214cc# Success! core@localhost ~/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:

core@localhost ~/webapp $ curl localhost/index.htmld &lt;html&gt;&lt;head&gt;&lt;title&gt;500InternalServerError&lt;/title&gt;&lt;/head&gt;&lt;body bgcolor=&quot;white&quot;&gt;&lt;center&gt;&lt;h1&gt;500InternalServerError&lt;/h1&gt;&lt;/center&gt;&lt;hr&gt;&lt;center&gt;nginx/1.1.19&lt;/center&gt;&lt;/body&gt;&lt;/html&gt;

我們看到了nginx的回應,但是是500錯誤. 這是因為我們并沒有一個index.html 資源文件讓nginx返回. 讓我們停止這個容器的運行 docker stop <container id>:

core@localhost ~/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:

core@localhost ~/webapp $ curl localhost Hello,Docker fans!

...或者直接訪問主機ip

注意這個ip是主機的ip. 我已經在 Vagrantfile 中指定了ip。我不需要知道要轉發的ip究竟是什么? 當時可以通過這個命令來看到  docker inspect <Container ID> .

core@localhost ~/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 用于在應用中的設置

這是一個mysql的dockerfile MySQL Dockerfile

結論

我們就是可以這么簡單的來創建一臺服務器,添加應用代碼,控制應用。執行環境中的每一件事都在你的掌控之中

通過這種方式,我們可以 跳過復雜的環境設置,專心于自己的代碼.

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.yunweipai.com/archives/6615.html

 本文由用戶 JonCrittend 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!