iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 2
1

https://ithelp.ithome.com.tw/upload/images/20200906/20129656JXOudA2mZE.png
容器是一種輕量化的打包技術, 它將硬體層拆開, 只保留軟體層的部分, 其中運行的項目為映像檔。Docker 是創建容器的工具, 我們透過他創建的容器來運行映像檔, 工程師完成容器後就可以在實體機、虛擬機或雲端上運行, 經過容器打包之後的映像檔可以在不同的作業系統中運行。

使用映像檔來發布應用程式可以確保從工程師手上到正式環境的應用程式都是一致的。

映像檔是一個靜態檔案, 具有不可變性, 有異動時就要重新打包,
它必須在容器中才能運作, 同一份映像檔可以在多個不同的容器中運行。
每個容器有自己的IP, 各容器間相互隔離, 資源不共享。

組成 Docker 的三個概念

https://ithelp.ithome.com.tw/upload/images/20200906/20129656ovlp7mxLwe.png
圖片來源

  1. 映像檔(Image)
    是一個靜態模板, 裡面包了一個完整的服務, 需要在容器中才能運行,
    映像檔只檢查tag, 它透過 tag 管理每個映像檔的版本。部署時建議不要使用latest, 要加上tag版號, 因為latest是變動的, 不好掌握具體的版本號。在容器中執行時, 如果映像檔存在會直接使用本地映像檔, 不存在則會從遠端拉下來。

  2. 容器(Container)

    • 無狀態:
      容器運行時不會在容器中保留任何的資料, 而是統一將這些資料保存在容器外的數據庫。
    • 體積小, 啟動快速, 好移植:
      主機上的所有容器都使用相同的底層作業系統, 讓容器比起虛擬機體積要小得多,
      由於容器啟動時不需再啟動作業系統,使得容器的部署和啟動非常快速,
      這也賦予容器中的服務可以快速移植的特性。
  3. 倉庫(Registry)
    Docker Hub 是公認官方最大的映像檔儲存倉庫,
    存放在上面的映像檔只要透過容器啟動就可以在任何環境中運行。

Docker Engine

  • 採用主從式架構如下圖
    https://ithelp.ithome.com.tw/upload/images/20200906/20129656Wh7E71Oe2D.png
    圖片來源

    1. docker daemon: 容器運作、映像檔管理。
    2. REST API: Client 使用Restful API 和 Server 溝通。
    3. Client docker CLI: docker 物件是透過CLI來操作。

補充

Docker registry 和 Docker repository 的差別
在查Docker的時候一直有看到這兩個字眼, 所以google了一下發現有些不一樣 參考網址

  • Docker registry:
    用於儲存 Docker images 的服務, 他可能是Public也可能是Private的image 可以透過第三方託管。

  • Docker repository
    具有相同名稱但是不同tag的docker images 集合, 透過tag作為識別。

Dockerfile

Dockerfile 是生成映像檔的配置文件, 每一行指令都是在描述映像檔中的每一層應該完成的行為。透過 Dockerfile 可以把所有環境建置流程寫進去,編寫完成後可以請人協助 code review, 降低可變性, 讓 build 出來的東西可以在不同環境中維持一致。

Dockerfile 指令

  • 常用指令說明 詳細指令參考

    1. FROM ... AS ... :
       - 從哪一個image繼承 
       - ex: FROM golang:1.14.8 AS builder
    
    2. ENTRYPOINT:
       - 在container 啟動的時候要先跑什麼指令
    
    3. RUN:
      - 在這個container image 中跑什麼指令, 可以多個, 一行就是一句
      - docker 預設在 / 根目錄底下 , 每一個RUN執行的指令互不影響
      - ex: 
          FROM      
          RUN cd /tmp   
          RUN cd /var/log   
          RUN RUN echo ""World!"" > /hello.txt   
          最後停在 / 根目錄 因為 docker 預設就是在根目錄 , 如果要改變最後停止目錄要用 WORKDIR      
    
    4. COPY:
      - 將本地端指定路徑的檔案把包到image裡面
      - ex: COPY --from=builder /go/src/hello/hello /go/src/hello/env.example ./
    
    5. ADD:
      - 等同 COPY, 可以自動解壓縮會下載url, 若無解壓縮與下載需求建議使用 COPY
      - ex: ADD ./ /go/src/hello
    
    6. EXPOSE:
      - 容易暴露出來的 port
      - ex: EXPOSE 1031
    
    7. WORKDIR:
       - 切換執行目錄, 最後 WORKDIR 位置會成為容器啟動的執行目錄
       - ex: WORKDIR /go/src/hello
    
    8. LABEL:
       - 設定映像檔的Metadata資訊
    
    9. ENV:
      - 設定環境變數
      - ex: ENV GO111MODULE=on
    
    10. 文件可以使用 `#` 來進行註解
    
  • build 指令

    docker build -t name -f Dockerfile .
    

    最後要加上 . , 意思是把目前路徑所有檔案傳給 docker daemon

dockerfile 練習

事先已在自己的github上推了一個具備http回應的專案

  • 編寫 dockerfile

    FROM golang:1.14.8
    
    RUN git clone https://github.com/[---放http服務的地方].git /go/src/hello
    
    RUN cd /go/src/hello && go build
    
    WORKDIR /go/src/hello
    
    EXPOSE 1031
    
    ENTRYPOINT ["./hello"]
    
  • 執行 Dockerfile ,最後記得加上 .

    docker build -t hello -f Dockerfile .
    
  • 執行結果
    https://ithelp.ithome.com.tw/upload/images/20200906/20129656AoZaOIsCUQ.png

  • 把image拉下來之後啟動

    docker run --name hello -d -p 127.0.0.1:1031:1031 hello
    
  • 檢查狀態, hello 正在執行中
    https://ithelp.ithome.com.tw/upload/images/20200907/20129656BsPeXff9CH.png

  • 測試打 docker 中的服務, 應該要取得當下時間
    https://ithelp.ithome.com.tw/upload/images/20200909/20129656HQxHg2vlRS.png

常用 Docker CLI

  • 登入/登出 dockerhub

    • docker login
    • dokcer logout
    
  • image 操作 詳細參照

    • docker images 或 docker image ls - 列出所有 image
    • docker build - 打包 image
    • docker history - 列出 image 各層資訊
    • docker pull - 從遠端 docker registry 拉 image 下來
    • docker push : 推送 image 到遠方 docker registry
    • docker rmi 或 docker image rm - 刪掉 image
    • docker save : 將 image 存到本地端
    • docker tag - 為 image 更改 tag 作版本管理
    

    docker pause / docker unpause: container 記憶體狀態會保存
    docker start / docker stop / docker restart: container 記憶體狀態不會保存

  • Container 操作 詳細參照

    • docker cp - 複製檔案 to/from container
    • docker create - 建立 container, 但不啟動
    • docker exec - 讓 container 執行指令
    • docker kill - 強制終止 container 
    • docker logs - 呈現 container 的 log
    • docker pause - 暫停 container
    • docker ps - 列出運作中 container (加 -a 列出所有container, 包含暫停的) 
    • docker rm - 刪除容器
    • docker run - create + start 建立後接著啟動
    • docker restart - 重新啟動 container
    • docker start - 啟動 container
    • docker stats - container 資源使用狀態 
    • docker stop - 停止 container
    • docker unpause - 繼續 container
    

今日小結

Docker 本身具備很完整的功能, 從容器打包到部署一應俱全, 但是 Docker 適用於管理單一容器, 一旦開始使用越來越多的容器時, 為了要串起各個容器之間的網路, 跨容器的管理跟調度就會變得越來越困難,這些需求的累積一步步推動K8s的誕生,我想可以這麼說: K8s 是搭著容器的熱潮應運而生的產物。


上一篇
day 1 K8s以前和以後
下一篇
day 3 認識 Kubernetes 物件關係(Pod, Controller, Service)
系列文
K8S - 30天從擦槍到提槍上陣學習筆記。30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言