如何優雅使用Docker?請收下這15個小技巧.

2021-02-20 架構之路

Tip 1

獲取最近運行容器的id 這是我們經常會用到的一個操作,按照官方示例,你可以這樣做(環境ubuntu):

$ ID=$(docker run ubuntu echo hello world)hello world$ docker commit $ID helloworldfd08a884dc79

這種方式在編寫腳本的時候很有用,比如你想在腳本中批量獲取id,然後進一步操作。但是這種方式要求你必須給ID賦值,如果是直接敲命令,這樣做就不太方便了。 這時,你可以換一種方式:

$ alias dl=』docker ps -l -q』$ docker run ubuntu echo hello worldhello world$ dl1904cf045887$ docker commit `dl` helloworldfd08a884dc79

docker ps -l -q命令將返回最近運行的容器的id,通過設置別名(alias),dl命令就是獲取最近容器的id。這樣,就無需再輸入冗長的docker ps -l -q命令了。通過兩個斜引號「,可以獲取dl命令的值,也就是最近運行的容器的id。

Tip 2

儘量在Dockerfile中指定要安裝的軟體,而不用Docker容器的shell直接安裝軟體。 說實話,我有時候也喜歡在shell中安裝軟體,也許你也一樣,喜歡在shell中把所有軟體安裝都搞定。但是,搞來搞去,最後還是發現,你還是需要在Doockerfile中指定安裝文件。在shell中安裝軟體,你要這樣做:

$ docker run -i -t ubuntu bash #登陸到docker容器root@db0c3967abf8:/#

然後輸入下面的命令來安裝文件:

apt-get install postgresql

然後再調用exit:

root@db0c3978abf8:/# exit

退出docker容器,再給docker commit命令傳遞一個複雜的JSON字符串來提交新的鏡像:

$ docker commit -run=」{「Cmd」:[「postgres」,」-too -many -opts」] }」 `dl` postgres

太麻煩了,不是嗎?還是在Dockerfile中指定安裝文件吧,只要兩個步驟:

1.在一個小巧的Dockerfile中,指定當前操作的鏡像為FROM命令的參數2.然後在Dockerfile中指定一些docker的命令,如CMD, ENTERPOINT, VOLUME等等來指定安裝的軟體

Tip 3

超-超-超級用戶

你可能需要一直用超級用戶來操作docker,就像早期示例裡一直提示的:

# 添加docker用戶組$ sudo groupadd docker# 把自己加到docker用戶組中$ sudo gpasswd -a myusername docker# 重啟docker後臺服務$ sudo service docker restart# 註銷,然後再登陸$ exit

Wow!連續三個sudo!三次化身「超級用戶」,真可謂是「超-超-超級用戶」啊!別擔心,設置完畢,以後你就再也不用打那麼多sudo了!

Tip 4

清理垃圾

如果你想刪除所有停止運行的容器,用這個命令:

$ docker rm $(docker ps -a -q)

順便說一句,docker ps命令很慢,不知道為啥這麼慢,按理說Go語言是很快的啊。docker ps -a -q命令列出所有容器的id,然後根據id刪除容器。docker rm命令遇到正在運行的容器就會失效,所以這個命令完美的刪除了所有沒在運行的容器。

Tip 5

docker inspect輸出結果的解析利器:jq 要對docker inspect的輸出結果進行過濾,一般情況下,用grep命令,你需要這樣操作:

$docker inspect `dl` | grep IPAddress | cut -d '"' -f 4

哦!看上去很複雜,用jq吧,專業解析docker inspect輸出結果,具有更強的可讀性,方便易用:

$docker inspect `dl` | jq -r '.[0].NetworkSettings.IPAddress'

其中第一個』.』代表所有的結果。』[0]』代表數組的第一個元素。就像JavaScript訪問一個JSON對象一樣,簡單方便。

Tip 6

鏡像有哪些環境變量? 有時候,你需要知道自己創建的鏡像有哪些環境變量。簡單!只要這樣:

$ docker run ubuntu env

輸出結果如下:

HOME=/PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bincontainer=lxcHOSTNAME=5e1560b7f757

調用env查看環境變量,對於後面要講到的「連結」(-link)很有用,在連接兩個容器時候需要用到這些環境變量,具體請看最後一個要點「連結」。

Tip 7

RUN命令 vs CMD命令

Docker的新手用戶比較容易混淆RUN和CMD這兩個命令。 RUN命令在構建(Build)Docker時執行,這時CMD命令不執行。CMD命令在RUN命令執行時才執行。我們來理清關係,假設Dockerfile內容如下:

FROM thelanddownunderMAINTAINER crocdundee

我們要向系統中安裝一些軟體,那麼:

# docker build將會執行下面的命令:RUN apt-get updateRUN apt-get install softwares# dokcer run默認執行下面的命令:CMD [「softwares」]

Build時執行RUN,RUN時執行CMD,也就是說,CMD才是鏡像最終執行的命令。

Tip 8

CMD命令 vs ENTRYPOINT命令

又是兩條容易混淆的命令!具體細節我們就不說了,舉個例子,假設一個容器的Dockerfile指定CMD命令,如下:

FROM ubuntuCMD [「echo」]

另一個容器的Dockerfile指定ENTRYPOINT命令,如下:

FROM ubuntuENTRYPOINT [「echo」]

運行第一個容器:

docker run image1 echo hello

得到的結果:

hello

運行第二個容器:

docker run image2 echo hello

得到的結果:

echo hello

看到不同了吧?實際上,CMD命令是可覆蓋的,docker run後面輸入的命令與CMD指定的命令匹配時,會把CMD指定的命令替換成docker run中帶的命令。而ENTRYPOINT指定的命令只是一個「入口」,docker run後面的內容會全部傳給這個「入口」,而不是進行命令的替換,所以得到的結果就是「echo hello」。

Tip 9

Docker容器有自己的IP位址嗎? 

剛接觸Docker的人或許會有這樣的疑問:Docker容器有自己的IP位址嗎?Docker容器是一個進程?還是一個虛擬機?嗯…也許兩者兼具?哈哈,其實,Docker容器確實有自己的IP,就像一個具有IP的進程。只要分別在主機和Docker容器中執行查看ip的命令就知道了。

查看主機的ip:

$ ip -4 -o addr show eth0

得到結果:

2: eth0 inet 162.243.139.222/24

查看Docker容器的ip:

$ docker run ubuntu ip -r -o addr show eth0

得到結果:

149: eth0   inet 172.17.0.43/16

兩者並不相同,說明Docker容器有自己的ip。

Tip 10

基於命令行的瘦客戶端,使用UNIX Socket和Docker後臺服務的REST接口進行通信。Docker默認是用UNIX socket通信的,一直到大概0.5、0.6的版本還是用埠來通信,但現在則改成UNIX socket,所以從外部無法控制Docker容器的內部細節。下面我們來搞點有趣的事情,從主機連結到docker的UNIX socket:

# 像HTTP客戶端一樣連接到UNIX socket$ nc -U / /var/run/docker.sock

連接成功後,輸入:

GET /images/json HTTP/1.1

輸入後連敲兩個回車,第二個回車表示輸入結束。然後,得到的結果應該是:

HTTP/1.1 200 OKContent-Type: application/jsonDate: Tue, 05 Nov 2013 23:18:09 GMTTransfer-Encoding: chunked16aa[{「Repository」:」postgres」,」Tag」:」.

有一天,我不小心把提交的名稱打錯了,名字開頭打成」-xxx」(我把命令和選項的順序搞混了),所以當我刪除的時候出了問題,docker rm -xxx,會把-xxx當成參數而不是鏡像的名稱。所以我只得通過socket直接連到容器來調用REST Server把錯誤的東西刪掉。

Tip 11

把鏡像的依賴關係繪製成圖

docker images命令有一個很拉風的選項:-viz,可以把鏡像的依賴關係繪製成圖並通過管道符號保存到圖片文件:

# 生成一個依賴關係的圖表$ docker images -viz | dot -T png -o docker.png

這樣,主機的當前路徑下就生成了一張png圖,然後,用python開啟一個微型的HTTP伺服器:

python -m SimpleHTTPServer

然後在別的機器上用瀏覽器打開:

http://machinename:8000/docker.png

OK,依賴關係一目了然!

(譯者註:要使用dot命令,主機要安裝graphviz包。另外,如果主機ip沒有綁定域名,machinename換成主機的ip即可。)

Tip 12

Docker把東西都存到哪裡去了? Docker實際上把所有東西都放到/var/lib/docker路徑下了。切換成super用戶,到/var/lib/docker下看看,你能學到很多有趣的東西。執行下面的命令:

$ sudo su# cd /var/lib/docker# ls -Fcontainers/ graph/ repositories volumes/

可以看到不少目錄,containers目錄當然就是存放容器(container)了,graph目錄存放鏡像,文件層(file system layer)存放在graph/imageid/layer路徑下,這樣你就可以看看文件層裡到底有哪些東西,利用這種層級結構可以清楚的看到文件層是如 何一層一層疊加起來的。

Tip 13

Docker原始碼:Go, Go, Go, Golang! Docker的原始碼全部是用Go語言寫的。Go是一門非常酷的語言。其實,不只是Docker,很多優秀的軟體都是用Go寫的。對我來說,Docker源文件中,有4個是我非常喜歡閱讀的:

commands.go docker的命令行接口,是對REST API的一個輕量級封裝。Docker團隊不希望在命令中出現邏輯,因此commands.go只是向REST API發送指令,確保其較小的顆粒性。

api.go REST API的路由(接受commands.go中的請求,轉發到server.go)

server.go 大部分REST API的實現

buildfile.go Dockerfile的解析器

有的夥計驚嘆」Wow!Docker是怎麼實現的?!我無法理解!」沒關係,Docker是開源軟體,去看它的原始碼就可以了。如果你不太清楚Dockerfile中的命令是怎麼回事,直接去看buildfile.go就明白了。

Tip 14

運行幾個Docker後臺程序,再退出容器,會發生什麼? OK,倒數第二個要點。如果在Docker中運行幾個後臺程序,再退出Docker容器,會發生什麼?答案是:不要這麼做!因為這樣做後臺程序就全丟了。

Dockerfile中用RUN命令去開啟一個後臺程序,如:

RUN pg_ctl start

這樣的話,RUN命令開啟的後臺程序就會丟失。調用容器的bash連到容器的shell:

$ docker run -i -t postgresimage bash

然後調用 ps aux查看進程,你會發現postgres的進程並沒有跑起來。 RUN命令會影響文件系統。因此,不要再Dockerfile中用啟動後臺程序,要把後臺程序啟動成前臺進程。或者,像一些高手提議的那樣,寫一個啟動腳 本,在腳本中啟動這些後臺程序或進程。

Tip 15

容器之間進行友好溝通:連結 

這是最拉風的功能!我把它留到最後壓軸!這是0.6.5中最重要的新功能,我們前面已經提過兩次了。運行一個容器,給它一個名稱,在下面的例子中,我們通過-name參數給容器指定名稱」loldb」:

$ docker run -d -name loldb loldbimage

再運行另一個容器,加上-link參數來連接到第一個容器(別名為loldb),並給第二個容器也指定一個別名(這裡用的是cheez):

$ docker run -link /loldb:cheez otherimage env

順便得到cheez的環境變量:

CHEEZ_PORT=tcp://172.17.0.8:6379CHEEZ_PORT_1337_TCP=tcp://172.17.0.8.6379CHEEZ_PORT_1337_TCP_ADDR=tcp://172.17.0.12CHEEZ_PORT_1337_TCP_PORT=6379CHEEZ_PORT_1337_TCP_PROTO=tcp

這樣,我們就在兩個容器間建立起一個網絡通道(bridge),基於此,我們可以建立一個類似rails的程序:一個容器可以訪問資料庫容器而不對外暴露其他接口。非常酷!資料庫容器只需要知道第一個容器的別名(在本例中為cheez)和要打開的埠號。所以資料庫容器也可以env命令來查看這個埠是否打開。

在公眾號後臺回復"微信"關鍵字,免費加入高大上的架構之路微信群,學習交流,技術探討,資源共享,不定期免費抽獎送書哦。

相關焦點

  • 10個日常Docker使用技巧
    docker使用技巧/ (點擊尾部閱讀原文前往)原文:https://dzone.com/articles/10-practical-docker-tips-for-day-to-day-docker-usa已獲轉載授權
  • Docker容器如何優雅使用NVIDIA GPU
    要將 GPU 與 Docker 結合使用,請首先將NVIDIA Container Toolkit[1]添加到您的主機。這集成到 Docker 引擎中以自動配置您的容器以支持 GPU。該base鏡像是基本 CUDA 運行時二進位文件的最小選項。runtime是一個功能更全面的選項,包括用於跨GPU通信[3]的 CUDA 數學庫和 NCCL 。第三種變體devel為您runtime提供了用於創建自定義 CUDA 鏡像的所有內容以及頭文件和開發工具。如果其中一個鏡像適合您,請將其用作Dockerfile.
  • 10 個冷門卻實用的Docker使用技巧
    在平時的工作中,docker 接觸得很多,除了經常使用的 docker run ,docker stop 等命令,docker 還有很多十分有用但是卻不經常使用的命令,下面就來總結一下:1. docker top這個命令是用來查看一個容器裡面的進程信息的,比如你想查看一個 nginx
  • 15分鐘掌握15個Docker要點
    獲取最近運行容器的id這是我們經常會用到的一個操作,按照官方示例,你可以這樣做:$ ID=$(docker run -d ubuntu echo hello world)hello world$ docker commit $ID helloworldfd08a884dc79這種方式在編寫腳本的時候很有用,比如你想在腳本中批量獲取id,然後進一步操作。
  • 優化Docker 鏡像小技巧
    它們是「容器的藍圖」,提供了有關如何生成容器的說明。在本文中,我將介紹一些經常被忽視的概念,這些概念將有助於優化Docker鏡像的開發和構建過程。讓我們從Docker構建過程開始。Docker構建是通過使用Docker CLI工具中的docker build命令觸發。docker build命令根據Dockerfile文件中指定的指令構建Docker鏡像。
  • 10 個冷門但又非常實用的 Docker 使用技巧
    在平時的工作中,docker 接觸得很多,除了經常使用的 docker run ,docker stop等命令,docker 還有很多十分有用但是卻不經常使用的命令,下面就來總結一下:1. docker top這個命令是用來查看一個容器裡面的進程信息的,比如你想查看一個 nginx
  • 如何使用Docker Machine創建Swarm集群
    通過本篇文章,讓我們來了解一下Docker Machine,以及如何使用Docker Machine創建Swarm集群。與Docker Compose一樣,Docker Machine 也是旨在幫助開發人員快速使用Docker的工具。
  • Docker 圖形化頁面管理工具使用
    DockerUI 是 Portainer 的前身,這三個工具通過docker api來獲取管理的資源信息。平時我們常常對著shell對著這些命令行客戶端,審美會很疲勞,如果有漂亮的圖形化界面可以直觀查看docker資源信息,也是非常方便的。今天我們就搭建單機版的三種常用圖形頁面管理工具。這三種圖形化管理工具以Portainer最為受歡迎。
  • iPad的使用小技巧 15個iPad mini+iPad使用技巧
    ,會使用安卓手機,那麼使用安卓平板電腦自然是輕車熟路。今天為大家分享15個iPad使用技巧,擁有iPad mini、iPad 3以及iPad 4平板電腦新手朋友不妨學習下。 1 ﹑鎖屏界面直接啟動」數碼相框」 在鎖屏界面,點擊「移動滑塊來解鎖」右邊的按鈕就可以啟動」數碼相框」,並且有很多照片切換特效哦。
  • 關於docker的15個小tip,你都知道嗎?
    調用env查看環境變量,對於後面要講到的「連結」(-link)很有用,在連接兩個容器時候需要用到這些環境變量,具體請看最後一個要點「連結」。,第二個回車表示輸入結束。(譯者註:要使用dot命令,主機要安裝graphviz包。另外,如果主機ip沒有綁定域名,machinename換成主機的ip即可。)Docker把東西都存到哪裡去了? Docker實際上把所有東西都放到/var/lib/docker路徑下了。切換成super用戶,到/var/lib/docker下看看,你能學到很多有趣的東西。
  • 如何優雅的使用Mac
    作為一個程式設計師,你該如何優雅的使用Mac呢?1. 最好不要拿 Macbook 裝 windows,即使必須要用 windows 的話能不裝 xp 麼?即使必須使用 xp 的話能麻煩升級一下 IE 麼?(以下均指使用 OS X)2、不要裝 3603.
  • 在Hyper-V的Docker主機上使用Visual Studio Docker工具
    不幸的是這個過程有一些繁瑣,所以我認為應該在這介紹一下。注意:你當然可以使用Azure運行Docker主機。但是,為了編輯和刷新能夠起作用,需要在你的Docker主機和你本地開發機器共享驅動。由於通用的防火牆和網絡限制,這功能在Azure虛擬機上經常很難獲得。本地Docker主機則可以很優雅的獲得該功能。
  • Python使用selenium操作Docker裡的Chrome瀏覽器的技巧
    介紹1.1 介紹今天福哥要帶著大家學習如何使用selenium去調用部署在Docker環境裡面的Chrome瀏覽器的方法。為什麼我們要把chromedriver部署到Docker裡面呢?因為把Chrome瀏覽器部署到Docker裡面有如下幾個優點:不用擔心Chrome升級導致的需要手動升級chromedriver驅動的問題。
  • Day 42 生信必備第三個利器Docker 系列 (七) Docker Volume 操作
    生信必備神器Docker回顧前面我們分幾篇文章聊了Docker 是什麼Day 34 生信必備三個利器之Docker 系列 (一)Docker是什麼 # 100天生信/數據科學自我挑戰#,聊了如何使用 Docker發布的一個單細胞分析教程Day 35 生信必備第三個利器Docker 系列 (二)  在生信中的應用,聊了Docker的安裝、什麼是image和container
  • 如何優雅的使用桑格box?
    這標題有bug,桑格box是個啥?! 我們團隊是個以IT和生信能力為主的團隊,另有前醫生現產品經理一人和擅長做實驗但就是不寫東西的博士一人。我們有意無意間透露過桑格box很多次(其實就是有意的..) 場景二:如何優雅的下載TCGA數據呢首先從工具盒中找到一個叫TCGA下載工具的東西
  • 手機攝影,如何表現中年女性優雅大氣雍容美?5個技巧就夠用
    那麼,用手機拍照,如何能夠表現出中年女性的優雅大氣雍容美呢?侍墨姑娘,總結了5個實拍技巧,分享給愛攝影的阿姨和姐姐。歡迎收藏和轉發。也歡迎您把拍照心得分享到評論區。我們開始吧!手機攝影和單反攝影最大的區別,是手機的coms相對比較小。所謂「底大一級壓死人」就是如此,也許在不久的將來,手機的coms能夠與單反媲美吧?但是眼前還沒有這樣的手機問世。一般情況下,手機的畫質、景深、色彩解析方面普遍不如單反。於是我們看到的結果就是,用手機給人拍照,攝影師會感覺攝影主體和自己「離得很近」。在有些場景中,想要拍攝全身像就似乎比較困難。
  • Day 43 生信必備第三個利器Docker 系列 (八) 如何創建Docker image並實戰演練發布自己的應用
    Docker 已更新內容回顧前面我們分幾篇文章聊了Docker 是什麼Day 34 生信必備三個利器之Docker 系列 (一)Docker是什麼 # 100天生信/數據科學自我挑戰#,聊了如何使用 Docker發布的一個單細胞分析教程Day 35 生信必備第三個利器Docker 系列 (二)  在生信中的應用,聊了Docker的安裝、什麼是image和container
  • Docker的基本使用-Ubuntu18.04
    Docker基本使用-CentOS版,請訪問:https://mp.weixin.qq.com/s/lu70ykBZ4yRu1gpNxnbytwDocker能做什麼提供一個虛擬的操作平臺,供我們安裝依賴不同版本系統的工具軟體。
  • 這54個docker命令!你必須懂!
    所以命令總是在變化。docker一些老的命令經常被棄用,並被新的或更有效的命令取代。您可以使用幫助選項檢查Docker安裝上的最新可用命令:要使用特定命令的選項,可以使用該命令的help選項。例如,要使用docker run命令選項,可以使用以下命令:目前,有13個管理命令和41個通用命令。
  • 如何在Docker中使用Arthas
    註:本文假設你已經會使用Arthas的命令,如您不熟悉arthas的基本使用方法,請移步https://arthas.aliyun.com/doc/quick-start.html查看2. 在Docker裡使用JDK很多時候,應用在docker裡出現arthas無法工作的問題,是因為應用沒有安裝 JDK ,而是安裝了 JRE 。如果只安裝了 JRE,則會缺少很多JAVA的命令行工具和類庫,Arthas也沒辦法正常工作。下面介紹兩種常見的在Docker裡使用JDK的方式。