共用方式為


教學課程:在 VS Code 中使用磁碟區在容器應用程式中保存數據

在本教學課程中,您將瞭解如何將資料保存在容器應用程式中。 當您執行或更新它時,數據仍可供使用。 有兩種主要類型的磁碟區可用來保存數據。 本教學課程著重於 具名磁碟區

您也會瞭解 系結掛接,以控制主機上的確切裝入點。 您可以使用系結掛接來保存數據,但它也可以將更多數據新增至容器。 在處理應用程式時,您可以使用系結掛接將原始程式碼掛接至容器,讓它看到程式代碼變更、回應,以及讓您立即看到變更。

本教學課程也會介紹影像分層、圖層快取和多階段組建。

在本教學課程中,您將瞭解如何:

  • 瞭解跨容器的數據。
  • 使用具名磁碟區保存數據。
  • 使用系結掛接。
  • 檢視影像圖層。
  • 快取相依性。
  • 瞭解多階段組建。

先決條件

本教學課程會繼續進行上一個教學課程: 使用Visual StudioCode建立及共用容器應用程式。 首先,選擇其中包含必要條件的一個。

瞭解跨容器的數據

在本節中,您將啟動兩個容器,並在每個容器中建立檔案。 在一個容器中建立的檔案無法在另一個容器中使用。

  1. 使用此指令啟動 ubuntu 容器:

    docker run -d ubuntu bash -c "shuf -i 1-10000 -n 1 -o /data.txt && tail -f /dev/null"
    

    此命令會透過 &&來啟動並叫用兩個命令。 第一個部分會挑選單一隨機數,並將它寫入 /data.txt。 第二個命令正在監控檔案,確保容器持續運行。

  2. 在 VS Code 的 [容器瀏覽器] 中,以滑鼠右鍵按一下 ubuntu 容器,然後選取 [ 附加殼層]。

    此螢幕快照顯示 [容器工具] 延伸模組中已選取的容器,以及【附加 Shell】已選取的功能表。

    終端機隨即開啟,並在 Ubuntu 容器中運行一個殼層。

  3. 執行下列命令以查看 /data.txt 檔案的內容。

    cat /data.txt
    

    終端機顯示介於 1 到 10000 之間的數字。

    若要使用命令行來查看此結果,請使用 docker ps 命令取得容器標識符,然後執行下列命令。

    docker exec <container-id> cat /data.txt
    
  4. 啟動另一個 ubuntu 容器。

    docker run -d ubuntu bash -c "shuf -i 1-10000 -n 1 -o /data.txt && tail -f /dev/null"
    
  5. 使用此命令來查看資料夾內容。

    docker run -it ubuntu ls /
    

    那裡不應該有 data.txt 檔案,因為它只被寫入第一個容器的臨時空間。

  6. 選取這兩個Ubuntu容器。 以滑鼠右鍵點擊並選取 移除。 從命令列中,您可以使用 docker rm -f 命令來移除它們。

使用具名磁碟區保存您的 Todo 數據

根據預設,待辦事項應用程式會將其數據儲存在 /etc/todos/todo.db 中。 SQLite 資料庫是儲存單一檔案之數據的關係資料庫。 此方法適用於小型專案。

您可以在主機上保存單一檔案。 當您將它傳遞至下一個容器時,應用程式可以繼續從中斷的地方開始。 藉由建立一個磁碟區並將其連接或 掛載到存放資料的資料夾中,您可以保留資料。 容器會寫入 todo.db 檔案,並且該數據會持續保存至主機的卷中。

請在此部分使用名為 卷。 Docker 會管理磁碟上的磁碟區實體位置。 請參閱磁碟區的名稱,而 Docker 提供正確的數據。

  1. 使用 docker volume create 命令建立磁碟區。

    docker volume create todo-db
    
  2. 在 [CONTAINERS] 底下,選取 [入門指南],然後按下滑鼠右鍵。 選取 [停止] 以停止應用程式容器。

    若要從命令行停止容器,請使用 docker stop 命令。

  3. 使用下列命令啟動 getting-started 容器。

    docker run -dp 3000:3000 -v todo-db:/etc/todos getting-started
    

    volume 參數指定要掛接的磁碟區和位置,/etc/todos

  4. 刷新瀏覽器以重新載入應用程式。 如果您已關閉瀏覽器視窗,請移至 http://localhost:3000/。 將一些專案新增至您的 Todo 清單。

    螢幕快照顯示範例應用程式,其中已新增數個專案至清單。

  5. 拿掉 todo 應用程式的 快速入門 容器。 以滑鼠右鍵按兩下容器總管中的容器,然後選取 [移除 ] 或使用 docker stopdocker rm 命令。

  6. 使用相同的指令啟動新的容器:

    docker run -dp 3000:3000 -v todo-db:/etc/todos getting-started
    

    此命令會掛接與之前相同的磁碟驅動器。 重新整理瀏覽器。 您新增的專案仍在清單中。

  7. 再次移除 入門 容器。

下面討論的具名磁碟區和系結掛接是預設 Docker 引擎安裝所支援的主要磁碟區類型。

財產 具名磁碟區 系結掛接
主機位置 Docker 選擇 您控制
掛接範例 (使用 -v my-volume:/usr/local/data /path/to/data:/usr/local/data
使用容器的內容寫入新磁碟區 是的
支援磁碟區驅動程式 是的

有許多磁碟區驅動程式外掛程式可用來支援 NFS、SFTP、NetApp 等等。 這些外掛程式對於在叢集環境中的多個主機上執行容器特別重要,例如 Swarm 或 Kubernetes。

如果您想知道 Docker 實際上 儲存資料的位置,請執行下列命令。

docker volume inspect todo-db

請查看輸出,結果類似於此。

[
    {
        "CreatedAt": "2019-09-26T02:18:36Z",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/todo-db/_data",
        "Name": "todo-db",
        "Options": {},
        "Scope": "local"
    }
]

Mountpoint 是儲存數據的實際位置。 在大部分的計算機上,您需要根存取權,才能從主機存取此目錄。

使用系結掛接

透過 綁定掛載,您可以控制主機上的確切掛載點。 此方法會保存數據,但通常用來將更多數據提供給容器。 您可以使用系結掛接將原始程式碼掛接至容器,讓它看到程式代碼變更、回應,以及讓您立即看到變更。

若要執行容器以支持開發工作流程,您將採取下列步驟:

  1. 移除任何 getting-started 容器。

  2. 在 [app] 資料夾中,執行下列命令。

    docker run -dp 3000:3000 -w /app -v ${PWD}:/app node:lts-alpine sh -c "yarn install && yarn run dev"
    

    此命令包含下列參數。

    • -dp 3000:3000 與之前相同。 以分離模式執行,並建立端口映射。
    • -w /app 容器內的工作目錄。
    • -v ${PWD}:/app" Bind 會將目前目錄從容器中的主機掛接至 /app 目錄。
    • node:lts-alpine 要使用的映像。 此映像是來自 Dockerfile應用程式的基礎映像。
    • sh -c "yarn install && yarn run dev" 一個命令。 它會使用 sh 啟動命令列介面,並執行 yarn install 來安裝所有相依套件。 然後,它會執行 yarn run dev。 如果您檢視 package.json,則 dev 文稿會開始 nodemon
  3. 您可以使用 docker logs來監看記錄。

    docker logs -f <container-id>
    
    $ nodemon src/index.js
    [nodemon] 2.0.20
    [nodemon] to restart at any time, enter `rs`
    [nodemon] watching path(s): *.*
    [nodemon] watching extensions: js,mjs,json
    [nodemon] starting `node src/index.js`
    Using sqlite database at /etc/todos/todo.db
    Listening on port 3000
    

    當您看到此清單的最後一個專案時,應用程式正在執行。

    當您完成監看日誌時,請在終端機視窗中按下任意鍵,或在外部視窗中按下 Ctrl +

  4. 在 VS Code 中,開啟 src/static/js/app.js。 變更行 109 上 [新增專案 ] 按鈕的 文字。

    - {submitting ? 'Adding...' : 'Add Item'}
    + {submitting ? 'Adding...' : 'Add'}
    

    儲存您的變更。

  5. 重新整理瀏覽器。 您應該會看到變更。

    螢幕快照顯示按鈕上具有新文字的範例應用程式。

  6. 移除node:lts-alpine容器。

  7. app 資料夾中,執行下列命令來移除 node_modules 在先前步驟中建立的資料夾。

    rm -r node_modules
    

檢視影像圖層

您可以查看組成影像的層次。 執行 docker image history 命令,以查看用來在影像中建立每個圖層的命令。

  1. 使用 docker image history 來查看您在教學課程中早先建立的 入門 映像中的圖層。

    docker image history getting-started
    

    您的結果應該類似此輸出。

    IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
    a78a40cbf866        18 seconds ago      /bin/sh -c #(nop)  CMD ["node" "/app/src/ind…   0B                  
    f1d1808565d6        19 seconds ago      /bin/sh -c yarn install --production            85.4MB              
    a2c054d14948        36 seconds ago      /bin/sh -c #(nop) COPY dir:5dc710ad87c789593…   198kB               
    9577ae713121        37 seconds ago      /bin/sh -c #(nop) WORKDIR /app                  0B                  
    b95baba1cfdb        13 days ago         /bin/sh -c #(nop)  CMD ["node"]                 0B                  
    <missing>           13 days ago         /bin/sh -c #(nop)  ENTRYPOINT ["docker-entry…   0B                  
    <missing>           13 days ago         /bin/sh -c #(nop) COPY file:238737301d473041…   116B                
    <missing>           13 days ago         /bin/sh -c apk add --no-cache --virtual .bui…   5.35MB              
    <missing>           13 days ago         /bin/sh -c #(nop)  ENV YARN_VERSION=1.21.1      0B                  
    <missing>           13 days ago         /bin/sh -c addgroup -g 1000 node     && addu…   74.3MB              
    <missing>           13 days ago         /bin/sh -c #(nop)  ENV NODE_VERSION=12.14.1     0B                  
    <missing>           13 days ago         /bin/sh -c #(nop)  CMD ["/bin/sh"]              0B                  
    <missing>           13 days ago         /bin/sh -c #(nop) ADD file:e69d441d729412d24…   5.59MB   
    

    每一行都代表影像中的圖層。 輸出會顯示底部,最新的圖層在頂端。 使用這項資訊,您可以看到每個圖層的大小,協助診斷大型影像。

  2. 有幾行被截斷了。 如果您新增 --no-trunc 參數,您將取得完整的輸出。

    docker image history --no-trunc getting-started
    

快取相依性

一旦圖層變更,所有下游層也都必須重新建立。 以下是再次 Dockerfile

FROM node:lts-alpine
WORKDIR /app
COPY . .
RUN yarn install --production
CMD ["node", "/app/src/index.js"]

Dockerfile 中的每個命令都會成為映像中的新層。 若要將圖層數目降到最低,您可以重組 Dockerfile 以支援依賴項緩存。 針對節點型應用程式,這些相依性定義於 package.json 檔案中。

方法是先只複製該檔案、安裝依賴項,然後 接著 複製其他所有內容。 如果 package.json有變更,過程只會重新建立 yarn 依賴項。

  1. 更新 Dockerfile,先將 package.json 複製進去,接著安裝相依性,然後再複製其他所有內容。 以下是新的檔案:

    FROM node:lts-alpine
    WORKDIR /app
    COPY package.json yarn.lock ./
    RUN yarn install --production
    COPY . .
    CMD ["node", "/app/src/index.js"]
    
  2. 使用 docker build建置新的映像。

    docker build -t getting-started .
    

    您應該會看到類似下列結果的輸出:

    Sending build context to Docker daemon  219.1kB
    Step 1/6 : FROM node:lts-alpine
    ---> b0dc3a5e5e9e
    Step 2/6 : WORKDIR /app
    ---> Using cache
    ---> 9577ae713121
    Step 3/6 : COPY package* yarn.lock ./
    ---> bd5306f49fc8
    Step 4/6 : RUN yarn install --production
    ---> Running in d53a06c9e4c2
    yarn install v1.17.3
    [1/4] Resolving packages...
    [2/4] Fetching packages...
    info fsevents@1.2.9: The platform "linux" is incompatible with this module.
    info "fsevents@1.2.9" is an optional dependency and failed compatibility check. Excluding it from installation.
    [3/4] Linking dependencies...
    [4/4] Building fresh packages...
    Done in 10.89s.
    Removing intermediate container d53a06c9e4c2
    ---> 4e68fbc2d704
    Step 5/6 : COPY . .
    ---> a239a11f68d8
    Step 6/6 : CMD ["node", "/app/src/index.js"]
    ---> Running in 49999f68df8f
    Removing intermediate container 49999f68df8f
    ---> e709c03bc597
    Successfully built e709c03bc597
    Successfully tagged getting-started:latest
    

    已重建所有圖層。 這是預期的結果,因為您已更改 Dockerfile

  3. src/static/index.html進行變更。 例如,將標題變更為 「真棒的 Todo 應用程式」。

  4. 現在使用 docker build 再次建置 Docker 映像。 這次,您的輸出看起來應該有點不同。

    Sending build context to Docker daemon  219.1kB
    Step 1/6 : FROM node:lts-alpine
    ---> b0dc3a5e5e9e
    Step 2/6 : WORKDIR /app
    ---> Using cache
    ---> 9577ae713121
    Step 3/6 : COPY package* yarn.lock ./
    ---> Using cache
    ---> bd5306f49fc8
    Step 4/6 : RUN yarn install --production
    ---> Using cache
    ---> 4e68fbc2d704
    Step 5/6 : COPY . .
    ---> cccde25a3d9a
    Step 6/6 : CMD ["node", "/app/src/index.js"]
    ---> Running in 2be75662c150
    Removing intermediate container 2be75662c150
    ---> 458e5c6f080c
    Successfully built 458e5c6f080c
    Successfully tagged getting-started:latest
    

    因為您正在使用建置快取,所以應該會運行得更快。

多階段組建

多階段建置是一個令人難以置信的強大工具,可協助使用多個階段來建立映像。 有數個優點:

  • 將建置時間相依性與運行時間相依性分開
  • 只運送應用程式需要執行的內容,以降低整體映像大小

本節提供簡短的範例。

Maven/Tomcat 範例

當您建置以 Java 為基礎的應用程式時,需要 JDK 才能將原始程式碼編譯為 Java 位元組程式代碼。 生產環境中不需要該 JDK。 您可能使用 Maven 或 Gradle 之類的工具來協助建置應用程式。 最終圖片中也不需要這些工具。

FROM maven AS build
WORKDIR /app
COPY . .
RUN mvn package

FROM tomcat
COPY --from=build /app/target/file.war /usr/local/tomcat/webapps 

此範例使用一個階段,build,以使用 Maven 執行實際的 Java 組建。 第二個階段從「FROM tomcat」開始,會從 build 階段複製檔案。 最後的圖像僅是最後階段,可以使用 --target 參數進行覆寫。

React 範例

建置 React 應用程式時,您需要 Node 環境,才能將 JavaScript 程式代碼、Sass 樣式表單等編譯成靜態 HTML、JavaScript 和 CSS。 如果您未執行伺服器端轉譯,則甚至不需要生產組建的 Node 環境。

FROM node:lts-alpine AS build
WORKDIR /app
COPY package* yarn.lock ./
RUN yarn install
COPY public ./public
COPY src ./src
RUN yarn run build

FROM nginx:alpine
COPY --from=build /app/build /usr/share/nginx/html

此範例會使用 node:lts-alpine 映射來執行建置,以最大化圖層快取,然後將輸出複製到 nginx 容器中。

清除資源

請保留到目前為止所做的一切,以繼續這一系列的教學課程。

後續步驟

您已瞭解儲存容器應用程式資料的選項。

接下來您要做什麼?