2021年9月28日 星期二

BDSE15 - Learn Docker

  從資策會巨量資料分析就業養成班(BDSE)結訓之後,很快就找到了資料分析工程師的工作,然而因為發生許多不如預期的狀況,選擇於試用期最後一刻提出離職,並於一個月後向新公司報到,但是這次不再是資料科學相關的工作,而是DevOps工程師。

  DevOps對我來說是全新的領域,沒有相關工作經驗,也沒有充足知識水準,完全不是現在的我可以駕馭的高複雜度工作,因此必須趁新手時期,盡可能把Shell ScriptGitDockerKubernetesTerraform等常用的基本工具學好,我也回顧了BDSE課程,發現或許只有LinuxDocker課程所學之基礎觀念可以沿用下去,故此次整理這兩個主題的筆記。

  Docker是容器化技術,在BDSE課程中,主要在VM內做為虛擬環境使用,以區隔不同的開發環境或執行環境,然而在工作應用上則更加多變,容器可以做為隨時啟用與刪除的暫時執行環境,也可以透過Kubernetes提供可擴展、容錯、升級的服務提供者,以DevOps工程師而言,是非常重要的基礎工具之一。

  由於Docker並非BDSE一系列課程的重點,因此倉促之下,我借閱了《Docker工作現場實戰寶典》,補充學習BDSE課程未觸及的重要知識點,例如Dockerfiledocker-compose,但docker-compose這類需大量查閱文件、格式,以編修yaml檔的工具,因難以適切地整理為筆記,故並未記錄於此學習筆記。

一、BDSE15

 

Ubuntu安裝Docker

l   建議直接參考官網提供之安裝方式:
https://docs.docker.com/get-docker/

l   使用自動化腳本在Linux上安裝Docker,可以運作在這些發行版本-CentOSFedoraDebianUbuntuRaspbian
curl -fsSL get.docker.com -o get-docker.sh
sudo sh get-docker.sh

 

Docker相關指令

l   開源專案Moby Project被動式開發,每年369月出Community穩定版。

l   預設Docker服務使用/var/run目錄內的docker.sock檔案來接收外來的要求。

l   Docker檢查與升級
#
檢查Docker資訊
docker info
#
檢查Docker版本
docker version
#
檢查Docker服務
systemctl list-unit-files | grep 'docker'
systemctl status docker.service
#
升級Docker
apt update
apt install docker-ce docker-ce-cli
apt install containerd.io

 

基礎映像檔操作指令

l   Docker Hub可以存放使用者的Image Repository,稱為Registry

l   存放映像檔、容器與容器設定檔的路徑是/var/lib/dockercontainers資料夾的config.v2.json存放各式設定。

l   提取一個映像檔:
docker image pull alpine

l   列出已存在的映像檔:
docker image ls

l   檢視映像檔歷史:
docker image history debian:9 --human
docker image history debian:9 -H

l   刪除一個映像檔:
docker image rm debian:9

l   搜尋映像檔:
docker search --filter is-official=true mysql

 

容器相關指令

l   建立互動式容器:
# run
建立但啟動,create建立但不啟動
# --name
取名字
# --restart
重啟策略
# --label
建立標籤,篩選與識別用
# -i
鍵盤
# -t
螢幕
# ubuntu
映像檔
# /bin/bash
command shell工具
docker container run --name my_ubuntu --restart=always --label label_name -i -t ubuntu /bin/bash
# --device
在容器中存取/dev/sdc
docker container run --device=/dev/sdc:/dev/xvdc -i -t ubuntu /bin/bash

l   使用互動式容器:
#
看所有容器
docker container ls -a
#
看目前執行的容器
docker container ls
docker container inspect
#
執行容器
docker container start my_ubuntu
#
複製在hosthello.py到容器內
docker container cp hello.py my_ubuntu:/root
#
複製在容器內的hello.pyhost
docker container cp my_ubuntu:/root/hello.py .
#
進入容器
docker container attach my_ubuntu
#
離開且關閉容器
exit
#
離開且不關閉容器
Ctrl+P+Q
#
停止容器
docker container stop my_ubuntu
#
強制停止容器
docker container kill my_ubuntu
#
重新命名已存在的容器
docker container rename my_ubuntu my_new_ubuntu
#
刪除已存在的容器
docker container rm my_new_ubuntu
#
移除所有的容器
docker container prune

l   建立服務式容器:
# -d
背景服務
docker container run --name daemon_demo -d ubuntu /bin/bash
# exec
開一個互動式Session到服務式容器內,可危機處理
docker container exec -i -t daemon_demo /bin/bash
ps -el
kill -9 [process number]

l   使用服務式容器:
#
顯示最後幾項容器日誌
docker container logs daemon_demo
# -f
持續監控容器日誌
docker container logs -f daemon_demo
# --tail 10
顯示最後十項容器日誌
docker container logs --tail 10 daemon_demo
# -t
顯示容器日誌時間
docker container logs -t daemon_demo
#
檢視容器設定檔資訊,至於容器的DNS設定要看resolv.conf
docker container inspect daemon_demo
#
檢視容器運作狀態
docker container inspect --format='{{ .StateRunning }}' daemon_demo
#
檢視容器IP位址
docker container inspect --format='{{ .NetworkSettings.IPAddress }}' daemon_demo
#
檢視容器程序資訊
docker container top daemon_demo

l   建立網路橋接式容器,以Jupyter Lab為例:
# -rm
容器用完即丟
# -p
對應埠號,8888:8888左邊是host8888,右邊是容器的8888
# -e
設定環境變數
# --user
登入帳號
# --mount
可見https://docs.docker.com/storage/bind-mounts/,此範例容器移除後,資料仍將存在
docker container run -rm -p 8888:8888 -e JUPYTER_ENABLE_LAB=yes -e GRANT_SUDO=yes --user root --mount type=bind,source=$PWD,target=/home/jovyan/work --name ds-env jupyter/datascience-notebook

l   使用網路橋接式容器:
#
查詢容器的埠號對應
docker container port ds-env

 

Data Volume

l   保存容器內的資料,只要對容器內的那個資料夾做任何存取,host相對應資料夾的內容也會跟著改變:
docker volume create --name share-folder

l   建立容器的同時掛載Data Volume,名稱為share-folder,容器中的路徑為/html,亦可繼續接-v來掛載多個Volume
docker create --name web -v share-folder:/html nginx

 

二、Docker工作現場實戰寶典(第一章~第三章)

 

進階映像檔操作指令

l   從容器建立映像檔-手動地在容器中做些改變:
docker container run -i -t ubuntu /bin/bash
apt-get update
apt-get install -y apache2
exit
#
查看容器ID以建立映像檔
docker container ls -a
docker container commit --author "Timmy" --message "Ubuntu with apache2 package" [container id] myapache2
docker image ls
# docker container diff
指令會列出從映像檔中取出在容器上的所有變更

l   發佈映像檔到Registry,需先註冊Docker Hub帳號,docker login以及docker logout指令都是以https://hub.docker.com做為預設的Registry
docker login
docker image tag myapache2 [account id]/myapache2
docker image push [account id]/myapache2
docker logout

l   匯出映像檔:
docker image save --output=myapache2.tar myapache2

l   匯入映像檔:
docker image import myapache2.tar apache2:imported

l   從容器建立映像檔-依據Dockerfile的內容建立出映像檔:
mkdir sample_image
cd sample_image
#
開始編輯Dockerfile內容
# Use ubuntu as the base image
FROM ubuntu
# Add author's name
LABEL maintainer="Timmy"
# Add the command to run at the start of container
CMD date
#
結束編輯Dockerfile內容
# -t
建立自己的倉庫名稱為sample
docker image build -t sample .

 

進階映像檔操作指令-Dockerfile指令格式

l   FROM <images>:<tag>
基礎映像檔一定要寫在Dockerfile檔案的第一行。

l   RUN ["executable", "param1", ..., "paramN"]
RUN <command> <param1> ... <paramN>
第一種下指令寫法為直接執行一個可執行檔,第二種下指令寫法為Shell中執行。

l   LABEL distro=ubuntu
建立標籤。

l   CMD ["executable", "param1", ..., "paramN"]
CMD <command> <param1> ... <paramN>
Dockerfile
檔案只能有一個CMD指令,若超過只有最後一個有效;啟動容器時的預設可執行檔,下docker container run沒有帶指令的時候,會使用Dockerfile定義的CMD

l   ENTRYPOINT ["executable", "param1", ..., "paramN"]
ENTRYPOINT <command> <param1> ... <paramN>
Dockerfile
檔案只能有一個ENTRYPOINT指令,若超過只有最後一個有效;用法與CMD類似,把容器配置為可執行的。

l   EXPOSE <port> [<port> ...]
在容器中使網路連接埠暴露出來。

l   ENV <key> <value>
設定環境變數的鍵值。

l   ADD ["src", "dest"]
ADD <src>, <dest>
從建置映像檔之工作目錄、解開本機tar檔進映像檔、遠端url(src)複製檔案到容器中的絕對路徑(dest)

l   COPY ["src", "dest"]
COPY <src>, <dest>
從建置映像檔之工作目錄(src)複製檔案到容器中的絕對路徑(dest)

l   VOLUME ["/data"]
VOLUME /data
掛載外部的儲存體。

l   USER <username>/<UID>
要執行指令的使用者名稱。

l   WORKDIR <path>
設定工作目錄。

l   ONBUILD [INSTRUCTION]
讓此映像檔可以被用來做為其它映像檔的基礎映像檔。

沒有留言:

張貼留言