天天看點

Docker從頭開始:使用容器,第1部分

這是關于使用Docker容器的分為兩部分的系列之一。 在這一部分中,我們将重點介紹運作映像的多種方法和選項,以及主機如何與Docker容器進行互動。

在第二部分中,我們将介紹列出,啟動,停止和重新啟動容器,以及在正在運作的容器上執行指令。 Docker映像是部署的機關。 運作映像時,您将執行個體化一個Docker容器,該容器在其自己的隔離環境中針對檔案系統,網絡和程序樹運作單個程序。

Docker容器非常靈活,可以支援許多用例,這些用例對于其他技術(如虛拟機和裸機伺服器)而言過于繁重,複雜和/或昂貴。

在開始之前,請確定已在您的環境中正确安裝了Docker。 根據安裝方式和使用者的不同,您可能需要以sudo身份運作它。 我将跳過sudo。

運作圖像

您可以通過運作映像來啟動Docker容器。 有幾種運作容器的方法,這些方法會影響管理所有容器的難易程度。 容器啟動時,通常會運作Dockerfile中定義的指令。 這是hello-world容器的Dockerfile:

FROM scratch
COPY hello /
CMD ["/hello"]
           

該指令僅運作建構映像時複制到容器根目錄的“ hello”二進制檔案。

前景與獨立

容器可以在其阻塞的前台運作,直到程序退出并且容器停止運作。 在前台模式下,容器将其輸出列印到控制台,并且可以讀取标準輸入。 在分離模式下(當您提供-d标志時),控件立即傳回,并且容器

運作未命名的容器

運作容器的最簡單方法是:

docker run <image id or name>

使用此指令運作容器時,Docker将為其配置設定一個由兩個随機詞組成的名稱。 例如:

docker run hello-world

如果您已經有了hello-world映像,那麼Doc​​ker将運作它。 如果不這樣做,它将從官方Docker存儲庫DockerHub中提取它,然後運作它。 輸出應如下所示:

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate work-flows, and more with a free Docker ID:
 https://cloud.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/engine/userguide/
           

顯示消息後,hello程式退出,該消息終止容器内運作的程序并結束容器運作。 如果您要連接配接到該容器,檢查日志或其他任何内容,該容器仍會粘住。 要檢視容器,可以運作以下指令:

docker ps -a  --format "table {{.ID}}\t{{.Status}}\t{{.Names}}"

CONTAINER ID        STATUS                     NAMES
8e2e491accb5        Exited (0) 2 minutes ago   clever_liskov
           

稍後我将解釋如何列出容器和所有相關選項。 現在,讓我們關注“名稱”部分。 Docker會自動生成名稱“ clever_liskov”,并且出于任何目的(例如重新啟動,删除它或執行指令),我都必須使用它或容器ID來引用該容器。

運作命名容器

有時使用容器ID或自動生成的名稱很不友善。 如果您經常與一個容器進行互動,而您又經常重新建立一個容器,那麼它将獲得一個不同的ID和自動生成的名稱。 此外,名稱将是随機的。

Docker通過提供“ --name <container name>”指令行參數來使您在運作容器時為其命名。 在簡單的情況下,每個圖像隻有一個容器,可以用圖像命名容器:

docker run --name hello-world hello-world

現在,如果我們看一下該過程(我之前删除了clever_liskov ),我們将看到該容器名為hello-world:

docker ps -a --format "table {{.ID}}\t{{.Names}}"
CONTAINER ID        NAMES
f6fe77b3b6e8        hello-world
           

命名容器有幾個好處:

  • 您在互動和腳本中使用的容器都有一個穩定的名稱。
  • 您可以選擇一個有意義的名稱。
  • 在進行互動工作時,可以選擇一個簡短的名稱以友善使用。
  • 這樣可以防止您意外地擁有多個具有相同圖像的容器(隻要您始終提供相同的名稱)。

讓我們看看最後一個選項。 如果我嘗試使用相同的“ hello-world”名稱再次運作相同的運作指令,則會收到清晰的錯誤消息:

docker run --name hello-world hello-world
docker: Error response from daemon: Conflict. The container name
"/hello-world" is already in use by container 
f6fe77b3b6e8e77ccf346c32c599e67b2982893ca39f0415472c2949cacc4a51. 
You have to remove (or rename) that container to be able to reuse 
that name.
See 'docker run --help'.
           

運作自動删除圖像

預設情況下,容器會粘在周圍。 有時,您不需要它們。 您無需手動删除退出的容器,而是使容器自行消失。

--rm

指令行參數可以達到目的:

docker run --rm hello-world

運作不同的指令

預設情況下,Docker運作用于建構映像的Dockerfile中指定的指令(如果未找到指令,則直接運作入口點)。 您始終可以通過在run指令末尾提供自己的指令來覆寫它。 讓我們在busybox映像上運作

ls -la

( hello-world映像沒有

ls

可執行檔案):

docker run busybox ls -la
total 44
drwxr-xr-x   18 root     root          4096 Mar 18 17:06 .
drwxr-xr-x   18 root     root          4096 Mar 18 17:06 ..
-rwxr-xr-x    1 root     root             0 Mar 18 17:06 .dockerenv
drwxr-xr-x    2 root     root         12288 Mar  9 00:05 bin
drwxr-xr-x    5 root     root           340 Mar 18 17:06 dev
drwxr-xr-x    2 root     root          4096 Mar 18 17:06 etc
drwxr-xr-x    2 nobody   nogroup       4096 Mar  9 00:05 home
dr-xr-xr-x   85 root     root             0 Mar 18 17:06 proc
drwxr-xr-x    2 root     root          4096 Mar  9 00:05 root
dr-xr-xr-x   13 root     root             0 Mar 18 17:06 sys
drwxrwxrwt    2 root     root          4096 Mar  9 00:05 tmp
drwxr-xr-x    3 root     root          4096 Mar  9 00:05 usr
drwxr-xr-x    4 root     root          4096 Mar  9 00:05 var
           

與主機互動

Docker容器在自己的小世界中運作隔離的程序。 但是提供對主機的通路通常是必要且有用的。

将環境變量傳遞給容器

Docker容器不會自動繼承運作它們的主機程序的環境。 使用

-e

指令行标志運作容器時,需要為容器顯式提供環境變量。 您可以傳遞多個環境變量。 這是一個例子:

docker run --rm -it -e ENV_FROM_HOST="123" busybox
/ # env
HOSTNAME=8e7672bce5a7
SHLVL=1
HOME=/root
ENV_FROM_HOST=123
TERM=xterm
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/
/ #
           

第一行運作busybox容器, 向其傳遞ENV_FROM_HOST變量,然後在運作

env

的容器内部顯示ENV_FROM_HOST設定正确。

您也可以使用主機環境變量。 這将設定幾個主機環境變量,并在run指令中使用它們:

$ export VAR_1=1
$ export VAR_2=2
$ docker run --rm -it -e VAR_1="$VAR_1" -e VAR_2="$VAR_2" busybox
           

在容器内,它們現在可見:

/ # env | grep VAR
VAR_1=1
VAR_2=2
           

挂載主機目錄

最有用的互動之一是挂載主機目錄。 這允許幾個有趣的用例:

  • 在同一主機上運作的容器之間的共享存儲。
  • 使用主機環境和工具以及容器中的檔案檢視和編輯檔案。
  • 超出容器生存期的主機級持久性。

在這裡,我在主機上建立了一個檔案:

$ echo "Yeah, it works!" > ~/data/1.txt

$ echo "Yeah, it works!" > ~/data/1.txt

然後,我運作busybox映像,将〜/ data目錄安裝到容器中的/ data并在螢幕上顯示檔案内容:

$ docker run --rm -v ~/data:/data busybox cat /data/1.txt
Yeah, it works!
           

我在這裡使用了

cat /data/1.txt

指令。

将端口公開給主機

如果使用EXPOSE在Dockerfile中公開端口,則隻有其他Docker容器才能通路該端口。 要使其在主機上可通路,您需要使用

-p

指令行參數。 文法為

-p <host port>:<exposed container port>

這裡正在運作nginx映像,該映像公開了端口80,并使用

-p

指令行參數使它在端口9000的主機上可見:

docker run --name nginx --rm -d -p 9000:80 nginx
           

請注意,與之前執行某些任務并完成的指令不同,nginx容器将繼續運作并監聽傳入的請求。 讓我們驗證一下nginx确實已經啟動并正在運作,并且可以響應端口9000上的請求。與curl相比,我更喜歡出色的httpie HTTP用戶端,它可以從指令行通路Web伺服器和服務:

http HEAD localhost:9000

HTTP/1.1 200 OK
Accept-Ranges: bytes
Connection: keep-alive
Content-Length: 612
Content-Type: text/html
Date: Sun, 19 Mar 2017 07:35:55 GMT
ETag: "58a323e4-264"
Last-Modified: Tue, 14 Feb 2017 15:36:04 GMT
Server: nginx/1.11.10
           

結論

運作Docker映像以建立容器的方法有很多,并且有很多選項。 每種組合都支援特定用途。 在使用Docker容器來完全掌握細節并使用最佳方法啟動容器時,這非常有用。

此外,附加主機卷以及公開和釋出端口可實作與主機的緊密內建以及多種使用場景。 在第二部分中,我們将深入研究管理一堆容器并利用Docker提供的全部功能。

翻譯自: https://code.tutsplus.com/tutorials/docker-from-the-ground-up-working-with-containers-part-1--cms-28483