# Docker 筆記 docker的介紹及簡單操作,歡迎留言指證錯誤或直接修改 TODO : - [ ] 介紹 -> Network -> MACVLAN 待測試 - [ ] 操作 -> Docker Swarm 使用 待新增 --- # 介紹 ## 簡介 Docker為一個開源軟體專案,輕量化的虛擬技術, 在原本的OS上增加一層虛擬化容器,是以應用為其核心 不同於虛擬機以OS為核心需包含自己的OS, Docker是與host共用kernel, 在部屬時間及空間的節省上都更優於虛擬機  除了OS的有無以外,VM即使在沒有應用運行的時候也會保持開啟, 而 docker container 在應用結束後便會自動停止 ### 優點 - 低成本(時間、空間、效能) - 開發者: 環境架設方便,統一開發環境 - 正式部屬: 避免因不同執行環境造成的問題 ### 缺點 - 仍然存在安全上的隱患 - 共用kernel所以並不是實質意義上的隔絕 - 缺乏像vm disk的儲存空間(解法: 詳見[Volume](#Volume)) - 並不是所有應用都適合被包裝 --- ## Image & Container ### Image - 可重複產生container的模板 - 分層式架構 - 唯讀性質 - 從DockerHub上pull image - 使用DockerFile自訂(詳見[DockerFile](#DockerFile)) ### Container - 基於image啟動的實體 - container間被隔離且不互相衝突 - 在image上外加一層可寫層 ### 分層式架構  從圖可看出image是由base image不斷疊加資料層而來, container則是在最上層的可寫層做操作 ### 查看 image layer 以mysql image為例  tag一般用來標註版本, 點擊Tags可看到各種版本的mysql image 再來點擊tag就可看到image的layer  從layer就能夠大致推測dockerfile是如何撰寫  --- ## Volume - container不像vm有自己的disk,一旦消失資料也會隨之不見 - volume為docker提供的一種資料保留方法 - 將container內指定路徑mapping到host的指定路徑上 - 可用docker指令創建由docker管理的volume(可用指令刪除、列出、詳細資訊),或自行指定host路徑(自行管理) --- ## Network 使container對container或container對host能互相溝通 ### Bridge - 預設網路介面 - 使container可與host或其他container連線 - 創建時使用 `docker run -p hostPort:targetPort` 連接host及container的port - 使用 `docker network create -d bridge` 自訂義bridge  ### Host - 與host共用網路 - 取消了container在網路上的隔絕性質 - 只能在linux系統使用 ### MACVLAN(待測試) - 使用前須先將網卡開啟混雜模式(promiscuous mode) - 在實體網卡上設定多個 mac address 或 ip 分配給 container - 讓只能使用實體網卡的應用能正常運作  --- ### Overlay - 使不同host間的container能互相溝通 - Docker Swarm  --- ## Docker Swarm - 管理在多個host上的container - 自動擴展或縮減container數量 - 分散流量 swarm 將每個 host 都視為一個 node , node 又分為以下兩種 - manager : 控制worker、訊息同步、分派任務 manager 中有一個 leader 負責執行上述工作,一旦 leader 失效,其餘 manager 就會使用 [Raft Consensus Algorithm](http://thesecretlivesofdata.com/raft/) 推選出新的 leader 維持運作,manager的容忍失效數為 (n-1)/2 ,所以官方建議 manager 數量為奇數 - worker : 執行service  --- # 操作 ## Image常用指令 - `docker image ls` : 列出所有 image - `docker pull IMAGE` : 從 dockerhub 下載 image - `docker push IMAGE` : 上傳 image - `docker rmi IMAGE` : 刪除 image - 建立 image 詳見 [DockerFile](#DockerFile) --- ## Container常用指令 - `docker ps -a` : 列出 container 包含停止的,-a 意為 all ,選用 - `docker create CONTAINER` : 創造 container - `docker start CONTAINER` : 啟動 container - `docker stop CONTAINER` : 停止 container - `docker rm CONTAINER` : 刪除 container - `docker exec CONTAINER COMMAND` : 令container執行指令,若要執行 /bin/bash 等等終端介面需在 exec 後加 -it - `docker cp FILE CONTAINER:PATH` : 從host複製檔案進 container ,也可反向操作,用法類似 scp - `docker run [OPTION] IMAGE`: 創造並運行 container,option如下 `-i` : 保持stdin開啟 `-t` : 賦予終端介面 `-v` : volume,寫法為,`VOLUME:targetPATH`、`hostPATH:targetPATH` `-p` : port forwarding,寫法為,`hostPORT:targetPORT` `-d` : detach,背景執行 `-e` : 設定環境變數 `--rm` : container 停止時自動刪除 `--name` : 命名 container (建議要用) --- ## Volume常用指令 - `docker volume ls` : 列出所有 volume - `docker volume create VOLUME` : 創造 volume - `docker volume rm VOLUME` : 刪除 volume --- ## Network常用指令 - `docker network ls` : 列出所有 network - `docker network create NETWORK` : 創造 network - `docker network rm NETWORK` : 刪除 network - `docker network connect NETWORK CONTAINER` : 將 container 連接 network --- ## 其他 - `docker login` : push image 前需先登入,相對也有 logout - `docker inspect OBJECT` : 顯示 docker 物件的詳細資訊 - `docker --version` : 查看版本 --- ## DockerFile ### 關鍵字說明(可新增) - FROM 設定 base image ( dockerfile 的開頭 ) - RUN 執行指令 - WORKDIR 設定工作目錄 - COPY/ADD 將檔案複製進image - ENV 設定環境變數 - EXPOSE 對其他container開啟port - CMD/ENTRYPOINT 開啟container時執行 ### 簡單範例 下面兩個範例為 web server 及資料庫 mysql 的 image,串接起來即為一個小網站 - django web server image ```dockerfile= FROM python:3.8 RUN apt-get update WORKDIR /usr/src/app COPY /DataBaseProject/ . RUN pip install -r requirements.txt CMD python manage.py runserver 0.0.0.0:8000 ``` line 1 : 此 server 是用 python 套件 django 所建,所以用 python 為 base image line 3 : 更新以免發生問題 line 5 : 設定我的工作路徑 line 7、8 : 從 host 複製專案(包含前端及後端)及安裝所需套件 line 10 : 讓我的 container 開啟時自動啟動 server - mysql server image ```dockerfile= FROM mysql ENV MYSQL_ROOT_PASSWORD=0000 \ MYSQL_DATABASE=DBproject ADD /DataBaseDDL/* /docker-entrypoint-initdb.d EXPOSE 3306 ``` line 1 : base image 為 mysql line 3、4 : 設定環境變數,資料庫密碼及要預建的資料庫名稱 line 6 : 複製資料庫設定檔到指定初始路徑 line 8 : 對其他 container 開放 port 3306 ( mysql 預設 port ),應該可省略,因為 mysql image 預設就有開放 port ### build指令 ``` docker build -t IMAGE -f FILE PATH ``` - -t : 定義 image 名稱 - -f : dockerfile 名稱(Dockerfile為預設名稱,若為預設名稱不用特別註明) --- ## Docker Compose 撰寫YAML檔來定義多個容器,可使用一行指令啟動或刪除所有容器,不必逐一執行 ### 關鍵字說明(可新增) - version : 不同版本的 docker 支援的 compose 版本也不同,需查[對應表](https://docs.docker.com/compose/compose-file/) - service : 設定 service name - network : 設定使用的 network 名稱 - volume : 設定 volume ,寫法如下 `hostPath:targetPath` 或 `volumeName:targetPath` - port : port forwarding,寫法為 `hostPort:targetPort` 或 `targetPort` (不指名 hostPort 會隨機分配) - healthcheck : 確認container是否活著,內容詳見[官方說明](https://docs.docker.com/compose/compose-file/compose-file-v3/#healthcheck) - restart : 何種條件可重啟,四種選項, "no" 、 always 、 on-failure 、 unless-stopped , 詳見[官方說明](https://docs.docker.com/compose/compose-file/compose-file-v3/#restart) - depends_on : 設定啟動順序,會在 depend on 的service啟動後啟動 ### 特殊說明(可新增) - 在非 swarm mode 時 service 等同於 container ( swarm mode 下 service 可能會有多個 container ) - 在檔案最後要特別統整使用的 network 及 volume , 這時可設置 network driver , 沒設置則是預設使用 bridge ### 簡單範例 以下範例使用到前一節所示範的 dockerfile ,建立起一個簡易的網站 ```yaml= version: "3.9" services: db: image: barry0310/my_mysql networks: - backend volumes: - db_vol:/var/lib/mysql healthcheck: test: mysqladmin ping -h localhost -p0000 interval: 10s timeout: 5s retries: 3 restart: on-failure web: image: barry0310/my_django networks: - backend ports: - "80:8000" depends_on: db: condition: service_healthy healthcheck: test: curl -f localhost:8000 interval: 5m timeout: 5s retries: 3 restart: on-failure volumes: db_vol: networks: backend: ``` line 1 : 3.9版本的 docker compose line 4~15 : 創建 database container line 17~31 : 創建 web server container line 33~36 : 列出使用的 volume 及 network ### 相關指令 - 啟動: `docker-compose -p NAME up -d ` - 移除: `docker-compose -p NAME down` 註 : -p 意為 project name 、 -d 為 detach , 不然預設會跑出執行log --- ## Docker Machine 有預裝 docker 的虛擬機,為快速創立 swarm 的 node ### 安裝 在 windows 環境下的安裝 使用 Git bash 執行 ```bash= if [[ ! -d "$HOME/bin" ]]; then mkdir -p "$HOME/bin"; fi && \ curl -L https://github.com/docker/machine/releases/download/v0.13.0/docker-machine-Windows-x86_64.exe > "$HOME/bin/docker-machine.exe" && \ chmod +x "$HOME/bin/docker-machine.exe" ``` 輸入`docker-machine version`以確認安裝成功 ### 額外設定 因為是使用 windows hyperv 的關係需要做額外的設定 搜尋  進來後右邊選虛擬交換器管理員  新增外部交換器  名稱隨意  ### 指令 - `docker-machine create -d hyperv --hyperv-virtual-switch "SWITCH" NAME` : 創建 vm `-d` : driver , `--driver` 也可 `--hyperv-virtual-switch` : SWITCH 替換成前面額外設定的 switch 名稱 - `docker-machine start NAME` : 啟動 vm - `docker-machine stop NAME` : 停止 vm - `docker-machine rm NAME` : 刪除 vm - `docker-machine ssh NAME` : 進入 vm - `docker-machine ls` : 所有 vm --- ## Docker Swarm 使用(待新增) --- # 參考資源 https://github.com/twtrubiks/docker-tutorial https://github.com/twtrubiks/docker-swarm-tutorial https://ithelp.ithome.com.tw/articles/10242460 https://docs.docker.com/compose/compose-file/compose-file-v3/ ###### tags: `Docker`
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up