有關docker的24個實用技巧

jopen 9年前發布 | 24K 次閱讀 Docker

我們愛docker,并把它用于生產環境中。下面是一些提示和技巧,希望能對已經熟悉docker基礎的每一位提供幫助。

CLI(Command-line interface)

  1. 規整 docker ps 輸出
    docker ps管道上加個less -S來使輸出的每一行不被換行
    docker ps -a | less -S
  2. 跟蹤日志
    docker logs -f <containerid>
  3. a single value from docker inspect
    docker inspect 在默認情況下有大量的JSON輸出。你可以使用內置的模板命令如下:

    is the last run container still running?

    docker inspect --format '{{.State.Running}}' $(docker ps -lq)
  4. docker exec instead of sshd or nsenter
    這個命令眾所周知,如果你遵循docker版本。 在1.3版本中引入了exec,讓你在一個容器內運行一個新的進程。因此也就沒有必要在容器中運行的sshd或主機上安裝nsenter。
    docker exec -it <container Id> /bin/bash
  5. </ol>

    Dockerfiles

    1. docker build supports git repos
      你不僅可以構建鏡像用本地的Dockerfiles,也可以簡單地給docker一個git倉庫的URL,docker自己會辦妥余下的事。
    2. no package lists
      默認的鏡像(如Ubuntu)不包括軟件包列表來保持它們小容量,因此apt-get update幾乎夠用在基本的Dockerfile中。
    3. watch out for package versions
      小心包的安裝以及那些緩存的命令。這意味著當誤操作緩存或著安全更新的延遲,您可能會獲取不同版本。
    4. small base images
      有一個真正的空的docker鏡像。這就是所謂的scratch(譯注:scratch教程)。所以,如果你愿意,你可以從頭構建你的鏡像FROM scratch。大多數時候,你最好從busybox開始,如果你想有一個非常小的基礎鏡像(只有2.5MB大小)。
    5. FROM is latest by default
      如果你沒有在標簽具體說明版本,則FROM關鍵字將只使用最新的鏡像。小心這一點,如果你可以確定具體版本,請最好那樣做。
    6. shell or exec mode
      在Dockerfile中有幾個地方,您可以具體指定命令。(例如CMD,RUN)。docker支持兩種方式。如果你只寫命令,然后docker將把它封裝在sh -c。你也可以把他們作為一個字符串數組(如 [&quot;LS&quot;, &quot;-a&quot;])。該陣列的符號在容器內是可用的將不再需要shell(因為它使用go的exec),這就是docker的首選語法。
    7. ADD vs COPY
      在構建容器時ADDCOPY都可以添加本地文件,但ADD有額外的魔法,比如增加遠程文件以及ungzipping解包和untaring歸檔。如果你明白這些區別,只用使用ADD
    8. WORKDIR and ENV
      每個命令都將創建一個新的臨時鏡像并在一個新的shell里運行,因此,如果你在Dockerfile使用cd &lt;directory>export &lt;var>=&lt;value>將無法正常工作。使用WORKDIR來設置工作目錄來接受多個命令,而使用ENV是設置環境變量。
    9. CMD and ENTRYPOINT
      CMD為默認的命令的當鏡像被運行時執行。默認ENTRYPOINT/bin/sh -c以及CMD作為參數傳遞進去。我們可以在Dockerfile重寫ENTRYPOINT使我們的容器表現得像輸入命令行參數的可執行程序(默認參數在我們Dockerfile的CMD里面)。

      in Dockerfile

      ENTRYPOINT /bin/ls
      CMD [&quot;-a&quot;]

      we're overriding the command but entrypoint remains ls

      docker run training/ls -l</code></li>

    10. ADD your code lastADD會使緩存無效如果文件有改變。當在您的Dockerfile加入頻繁變化的東西,而又如果不想使緩存作廢。你可以先添加庫和依賴,在最后添加你的代碼。對于node.js apps 意味著你先加入的package.json,然后運行npm install,最后再加入你的代碼。
    11. </ol>

      docker networking

      Docker有一個IPs內部池,它的存在是為了容器的IP地址。默認的這些是隱蔽的,可以經由橋接來訪問。

      1. looking up port mappings
        docker run接受明確的端口映射作為參數,也可以指定-P自動映射所有端口。后者具有防止沖突并搜尋已分配的端口,命令如下:
        docker port &lt;containerId> &lt;portNumber>

        or

        docker inspect --format '{{.NetworkSettings.Ports}}' &lt;containerId>
      2. container IPs
        每個容器有它的IP在一個私有的子網中(默認情況下是172.17.42.1/16)。該IP在重啟后可以改變,但你也可以用以下命令查詢:
        docker inspect --format '{{.NetworkSettings.IPAddress}}' &lt;containerId>
        docker嘗試查找沖突并如果需要將使用不同的子網絡。
      3. taking over the hosts network stack
        docker run --net=host允許重新使用主機的網絡協議棧。不能這樣做。
      4. </ol>

        volumes

        一種方法為目錄或單個文件接近零開銷(綁定掛載)來繞過copy-on-write(寫入時復制)文件系統 。

        1. volume contents are not saved on docker commit
          數據卷內容不會被保存到docker的提交改動中。當鏡像被構建時,同時寫入您的數據卷沒有多大意義
        2. volumes are read-write by default
          默認情況下,數據卷有讀寫權限 但有一個 :ro 標志(read-only只讀權限)
        3. volumes exists separately from containers
          數據卷的退出是跟容器分開的,并且這是可能的直到至少有一個容器引用它們。數據卷可以在容器之間共享,使用 --volumes-from
        4. mount your docker.sock
          掛載你的docker.sock。你可以只掛在您的docker.sock來為容器內提供訪問docker的API。然后,您可以在容器內運行的docker的命令。這樣的容器,甚至可以消除自己。在容器內運行docker守護進程也是沒必要的。
        5. </ol>

          security

          1. docker runs as root...
            ...相應地對待它。docker API有充分的root訪問權限,你可以映射/掛載數據卷,讀,寫。或者你可以使用--net host來接管主機的網絡。不要向公眾暴露docker API或使用TLS。
          2. USER in Dockerfiles
            默認情況下,docker以root身份運行一切,當然你也可以在Dockerfiles使用USER。有在docker沒有用戶命名空間來使容器看到用戶在主機上,但只有uids,因此你需要在容器中添加用戶。
          3. 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)。
            我們希望盡快得獲得更多的細微的訪問控制,而不是沒有控制或者控制一切。
          4. </ol>
            原文鏈接

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