有關docker的24個實用技巧
我們愛docker,并把它用于生產環境中。下面是一些提示和技巧,希望能對已經熟悉docker基礎的每一位提供幫助。
CLI(Command-line interface)
- 規整 docker ps 輸出
docker ps管道上加個less -S來使輸出的每一行不被換行
docker ps -a | less -S
- 跟蹤日志
docker logs -f <containerid>
- a single value from docker inspect
docker inspect 在默認情況下有大量的JSON輸出。你可以使用內置的模板命令如下:
is the last run container still running?
docker inspect --format '{{.State.Running}}' $(docker ps -lq) - docker exec instead of sshd or nsenter
這個命令眾所周知,如果你遵循docker版本。 在1.3版本中引入了exec,讓你在一個容器內運行一個新的進程。因此也就沒有必要在容器中運行的sshd或主機上安裝nsenter。
docker exec -it <container Id> /bin/bash
</ol>
- docker build supports git repos
你不僅可以構建鏡像用本地的Dockerfiles,也可以簡單地給docker一個git倉庫的URL,docker自己會辦妥余下的事。 - no package lists
默認的鏡像(如Ubuntu)不包括軟件包列表來保持它們小容量,因此apt-get update
幾乎夠用在基本的Dockerfile中。 - watch out for package versions
小心包的安裝以及那些緩存的命令。這意味著當誤操作緩存或著安全更新的延遲,您可能會獲取不同版本。 - small base images
有一個真正的空的docker鏡像。這就是所謂的scratch(譯注:scratch教程)。所以,如果你愿意,你可以從頭構建你的鏡像FROM scratch。大多數時候,你最好從busybox開始,如果你想有一個非常小的基礎鏡像(只有2.5MB大小)。 - FROM is latest by default
如果你沒有在標簽具體說明版本,則FROM
關鍵字將只使用最新的鏡像。小心這一點,如果你可以確定具體版本,請最好那樣做。 - shell or exec mode
在Dockerfile中有幾個地方,您可以具體指定命令。(例如CMD,RUN)。docker支持兩種方式。如果你只寫命令,然后docker將把它封裝在sh -c
。你也可以把他們作為一個字符串數組(如["LS", "-a"]
)。該陣列的符號在容器內是可用的將不再需要shell(因為它使用go的exec
),這就是docker的首選語法。 - ADD vs COPY
在構建容器時ADD
和COPY
都可以添加本地文件,但ADD
有額外的魔法,比如增加遠程文件以及ungzipping
解包和untaring
歸檔。如果你明白這些區別,只用使用ADD
。 - WORKDIR and ENV
每個命令都將創建一個新的臨時鏡像并在一個新的shell里運行,因此,如果你在Dockerfile使用cd <directory>
或export <var>=<value>
將無法正常工作。使用WORKDIR
來設置工作目錄來接受多個命令,而使用ENV
是設置環境變量。 - CMD and ENTRYPOINT
CMD
為默認的命令的當鏡像被運行時執行。默認ENTRYPOINT
是/bin/sh -c
以及CMD
作為參數傳遞進去。我們可以在Dockerfile重寫ENTRYPOINT
使我們的容器表現得像輸入命令行參數的可執行程序(默認參數在我們Dockerfile的CMD里面)。
in Dockerfile
ENTRYPOINT /bin/ls
CMD ["-a"]
we're overriding the command but entrypoint remains ls
docker run training/ls -l</code></li>- ADD your code last
</ol>ADD
會使緩存無效如果文件有改變。當在您的Dockerfile加入頻繁變化的東西,而又如果不想使緩存作廢。你可以先添加庫和依賴,在最后添加你的代碼。對于node.js apps 意味著你先加入的package.json,然后運行npm install
,最后再加入你的代碼。
docker networking
Docker有一個IPs內部池,它的存在是為了容器的IP地址。默認的這些是隱蔽的,可以經由橋接來訪問。
- looking up port mappings
docker run
接受明確的端口映射作為參數,也可以指定-P
自動映射所有端口。后者具有防止沖突并搜尋已分配的端口,命令如下:
docker port <containerId> <portNumber>
or
docker inspect --format '{{.NetworkSettings.Ports}}' <containerId> - container IPs
每個容器有它的IP在一個私有的子網中(默認情況下是172.17.42.1/16)。該IP在重啟后可以改變,但你也可以用以下命令查詢:
docker inspect --format '{{.NetworkSettings.IPAddress}}' <containerId>
docker嘗試查找沖突并如果需要將使用不同的子網絡。 - taking over the hosts network stack
docker run --net=host
允許重新使用主機的網絡協議棧。不能這樣做。
</ol>
- volume contents are not saved on docker commit
數據卷內容不會被保存到docker的提交改動中。當鏡像被構建時,同時寫入您的數據卷沒有多大意義 - volumes are read-write by default
默認情況下,數據卷有讀寫權限 但有一個:ro
標志(read-only只讀權限) - volumes exists separately from containers
數據卷的退出是跟容器分開的,并且這是可能的直到至少有一個容器引用它們。數據卷可以在容器之間共享,使用--volumes-from
。 - mount your docker.sock
掛載你的docker.sock
。你可以只掛在您的docker.sock
來為容器內提供訪問docker的API。然后,您可以在容器內運行的docker的命令。這樣的容器,甚至可以消除自己。在容器內運行docker守護進程也是沒必要的。
</ol>
- docker runs as root...
...相應地對待它。docker API有充分的root訪問權限,你可以映射/掛載數據卷,讀,寫。或者你可以使用--net host
來接管主機的網絡。不要向公眾暴露docker API或使用TLS。 - USER in Dockerfiles
默認情況下,docker以root身份運行一切,當然你也可以在Dockerfiles使用USER
。有在docker沒有用戶命名空間來使容器看到用戶在主機上,但只有uids,因此你需要在容器中添加用戶。 - use TLS on the docker API
直到1.3當他們加入了TLS, 在docker API才有了訪問控制。他們使用相互驗證:客戶端和服務端都有密鑰。把鑰匙作為root密碼。
自從1.3版本,Boot2docker默認具有TLS,也會為您產生密鑰。
在其他情況下,生成密鑰需要的OpenSSL 1.0.1, 然后docker守護程序需要與--tls-verify
運行,并使用安全docker端口(2376)。
我們希望盡快得獲得更多的細微的訪問控制,而不是沒有控制或者控制一切。
</ol>
volumes
一種方法為目錄或單個文件接近零開銷(綁定掛載)來繞過copy-on-write
(寫入時復制)文件系統 。
security
原文鏈接 - ADD your code last
Dockerfiles
本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!