跳到主要內容

Docker Concept and Best Practice

Docker


參考 GitBook - Docker Practice

鏡像(Image)和容器(Container)的關係,就像是 OOP (Object-oriented Programming) 中的 class 和 instance 一樣, Image 是靜態的定義, Container 是 Image 運行時的實體。容器可以被創建、啟動、停止、刪除、暫停等。

基本的運作方式像這樣, 參考 這份PPT


Developer Best Practice

Keep Images Small

確保 Images 越小越好, 跟 layers 越少越好, 這樣啟動的速度就越快.
Layers 指的是在 Dockerfile 的每一行指令, 代表一個 layer, 例如下面這份 Dockfile 就代表 6 Layers.

FROM ubuntu:15.04
COPY . /app
RUN apt-get -y update
RUN apt-get install -y python
RUN make /app
CMD python /app/app.py

可以修改為 4 layers.

FROM ubuntu:15.04
COPY . /app
RUN apt-get -y update && apt-get install -y python && make /app
CMD python /app/app.py

Layers 的說明: 參考



  • JDK 的開發者, 可以考慮 Docker 官方建議的 OpenJDK Image, 官方目前不支援 oracle-jdk 呦。
  • Multiple Build, 在一份 Dockerfile 同時使用不同來源的 image, 可以避免同時維護多個 dockerfiles, 參考:用 Docker Multi-Stage 編譯出 Go 語言最小 Image
  • 如果有多個 images 擁有相同的 common, 可以考慮建立一個 base image, 類似父層級的 image, docker 會協助做快取來加速其他 image 的啟動.
  • 在建立多個 images 時, 可以透過 tags 的指令做管理, 不要依賴 latest 的 tag.


Where and how to persist application data

  • 避免將資料存到 container 裡面, 這會導致 I/O 效率降低.
  • 建議使用 volumes, 將 host 的目錄或檔案掛載(mounted)到 docker 容器裡。
  • 敏感的資訊, 或 config 相關設定, 請考慮 docker secret

Differences between -v and --mount behavior

在閱讀文件的時候, 剛好看到自己的疑問, -v--mount 的差異,

  • -v - 永遠都會做 created direcotry 這個動作。
  • --mount - 如果檔案或目錄不存在, docker 會拋出 error。
透過 docker inspect devtest 可以看到詳細的差異。

volume 用法


docker run -d \
  -it \
  --name devtest \
  -v "$(pwd)"/src:/app \ 
  nginx:latest

mount 用法


docker run -d \
  -it \
  --name devtest \
  --mount type=bind,source="$(pwd)"/src,target=/app \ 
  nginx:latest

Use swarm services when possible

這部分主要是建議以 群集(SWARM) 的架構使用 container, 目前還沒有深入的需求, 沒有深入研究



留言

這個網誌中的熱門文章

Parse URI query string to Key Value

Parse URI query String to Map 做 urlDecode 處理 沒有任何 query String 回傳 Empty Map 確保只處理 key-value 結構的 query String package com.example.util; import lombok.extern.slf4j.Slf4j; import org.apache.http.client.utils.URIBuilder; import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URISyntaxException; import java.net.URLDecoder; import java.util.LinkedHashMap; import java.util.Map; import java.util.Objects; /** * Created by jerry on 2017/12/28. * * @author jerry */ @Slf4j public class UriUtil { private UriUtil() { } public static Map splitQuery(final String uri) { Map queryPairs = new LinkedHashMap (); try { final URI uri = new URIBuilder(uri).build(); final String rawQuery = uri.getRawQuery(); log.info("CurrentUrl Query: {}", rawQuery); // 過濾沒有 query string // 還有過濾無法成對 keyValue 的 query, e.g. http://host/path?123 if (Objects.isNull(rawQuery) |...

Google Compute Engine‎ - AccessDeniedExceptions 403

原因 打算從 instance 打包 logs 到 google cloud storage 發生了 AccessDeniedException: 403 Insufficient OAuth2 scope to perform this operation. , 看起來是 instance 沒有 storage 權限 解決 Reference: https://cloud.google.com/compute/docs/access/create-enable-service-accounts-for-instances#changeserviceaccountandscopes 重新設定 service account 權限 instance 上內建有 gcloud , 就直接用現有的工具查詢一下 instance 的 account. $ gsutil info 或者在本機直接 gcloud compute instances describe INSTANCE_NAMES Account: [alpha-number-compute@developer.gserviceaccount.com] Project: [our-project-name] 會看到 instance 的一些狀態, 接下來就簡單多了, 按照下列的說明, 要先 stop instance, 更改 storage scope 再重新 start 。 To change an instance's service account and access scopes, the instance must be temporarily stopped. To stop your instance, read the documentation for Stopping an instance. After changing the service account or access scopes, remember to restart the instance. # Stop Instance gcloud compute instances stop INSTANCE_NAMES # 設定 storage scope 為 full (Read, Write) gcloud co...

Spring-boot Thymeleaf Html5 SAXParseException 解析錯誤

thymeleaf 解析 html5 出錯 <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="description" content=""> <meta name="author" content=""> <title>SB Admin - Start Bootstrap Template</title> <!-- Bootstrap core CSS--> <link href="../static/vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet"> <!-- Custom fonts for this template--> <link href="../static/vendor/font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css"> <!-- Page level plugin CSS--> <link href="../static/vendor/datatables/dataTables.bootstrap4.css" rel="stylesheet"> <!-- Custom styles for this template--> <li...