* 這裡介紹都使用容器這個名稱,而不是使用 **Docker** * 因為實踐容器技術的系統有很多種,不是只有 **Docker** * 但不可否認的是,Docker 確實是業界標準!畢竟它最早開始實作容器技術! 容器簡介 === 甚麼是容器(Container),為什麼它發展比虛擬系統還快,有甚麼優點? --- * 容器是一種應用程式系統打包、隔離執行環境、管理運行的技術。 * 隔離的環境包括CPU、Memory、Disk I/O、網路頻寬等資源,確保每個運行中的容器,不會互相干擾破壞,也不會影響 Container Host * 容器可以快速啟動執行!跟執行應用系統差不多時間。 * 虛擬系統跟實體系統一樣,啟動需要經過開機、測試硬體環境、載入作業系統、驅動程式等等...所以啟動需要花大量的時間。 * 每個虛擬系統需要佔用大量的記憶體給作業系統以及磁碟空間 * 容器本身是運行在已經啟動的系統上(不管是實體或是虛擬),它相當於你平常運行應用程式差不多! * 容器其實跟 Portable Apps 很像!只是以往要打包 Portable Apps 需要購買軟體授權,例如:[VMware ThinApp](https://www.vmware.com/tw/products/thinapp.html)、[Cameyo](https://cameyo.com/),當你安裝好 Portable Apps 建置系統之後,它會先掃描你的軟硬體環境,將這些資訊都紀錄下來,然後你安裝付費的授權軟體、啟用授權軟體,完成安裝之後,ThinApp 會再次掃描整個系統,確認那些地方被修改異動,然後將這些資訊打包成一個 Portable App,並附上一個沙箱環境,讓你可以將這個打包的應用程式搬移到任何電腦上運行! * 容器技術不只是打包應用軟體、隔離執行環境資源,還提供執行管理相關的工具,讓應用程式散佈運行更方便! | 比較項目 | 容器 | 虛擬系統 | 說明 | |--------------|-------|------------|-------| | 執行啟動效率 | 快 | 慢 | 虛擬系統需要經過開機啟動程序 | | 使用資源量 | 少 | 多 | 虛擬系統需要使用大量的 CPU、RAM、Disk 給作業系統 | | 費用成本 | 授權費0 | 授權費高 | 需要進階管理虛擬系統,需要支付高額的授權費用 | | 運行作業系統平台 | 需一致 | 不須一致 | Linux 平台上,只能運行 Linux 架構的容器,不能運行 Windows 架構的容器 | --- 容器技術的四個物件:Image, Container, Volume, Network --- * **Image**:Base Image + 你開發的應用程式/或是你要運行的系統 + 設定檔案 + 資料檔案等等,打包成一個新的 Image * Image 可以匯出成 tarball 格式(早在磁帶備份時期就開始使用的資料檔案封存格式,壓縮性低)檔案 * Image 可以上傳(push),到公有或[私有 Repository](https://repo.funday.asia/v2/_catalog) 儲存伺服器上 * 公有 Repository 有很多,最著名就是 Docker Hub,Redhat Linux 也有自家 Repository,Google GCP 也有 * [建立私有 Repository](https://hackmd.io/XYVXlNBwTdekfQFeD5Qcfg) * **Container**:包含了 Image 以及執行環境狀態紀錄;預設下,Container停止時,Container 只是停止運行,但是網路、磁碟等資源仍然是占用的狀態。 * **Volume**:方便管理的磁碟管理 * 可以讓你將 Host Volume 掛載到 Container 裡面,供Container 的應用程式系統讀寫;也因為是 Host Volume,你可以很方便地透過 Host 管理 * 可以透過 Host 掛載網路磁碟服務([網路芳鄰SMB/CIFS/Samba](https://learn.microsoft.com/zh-tw/windows/win32/fileio/microsoft-smb-protocol-and-cifs-protocol-overview)、[NFS](https://aws.amazon.com/tw/compare/the-difference-between-nfs-smb/)、[iSCSI](https://aws.amazon.com/tw/compare/the-difference-between-nfs-and-iscsi/))、後,再掛載到 Container。 ![enter image description here](https://lh3.googleusercontent.com/pw/ADCreHcuQj6noFcSr-789IvL_24ZLsTrnqwG9hYZ-W-tVYM2_LAqwihlnWsjqNXrUkrwGIFGd7rPP0fDxhiaBhshdOlSwh07st-GxJ7HhNygzCj_BRumxdhkvbOBbPcLkV8--XQ6QPHhAEmuFElMM3zVKRIK7Q=w401-h271-s-no-gm?authuser=0) * **Network**:容器的網路運行在虛擬的隔離網路之中,存取只能透過Container 技術,意即不容易透過網路入侵或攻擊外部,且虛擬的網路環境,可以很容易在其他 Host 進行部屬(不使用固定 IP) --- 一些常用的 Docker 指令 --- ### 查詢 Docker 指令參數說明 |指令|用途| |-----|------| |docker --help|查詢所有 Docker 指令及概要說明| |docker [command] --help|查詢 Docker Command 進一步的詳細說明| --- ### 如何管理 Images |指令|用途| |-----|------| |docker **pull** [image_name:image_tag]|從 Repository 下載 Image| |docker **images** [image_name:image_tag]|查看本機目前已經下載的 Images| |docker **push** [repo_host/image_name:image_tag]|將 Image 上傳到 Repository| |docker **rmi** [image_name:image_tag]|刪除本機的 Image| |docker **save** [image_name:image_tag] > file_name.tar|將本機 Image 匯出存成 tarball 檔案| |cat file_name.tar \| docker **load**|從 tarball 檔案匯入本機| |docker **history** [image_name:image_tag]|查看當初 image 建立的指令| |docker **inspect** [image_name:image_tag]|查看JSON格式的 Image 資訊| |docker **commit** [container_id 或 container_name] [new_image_name:new_image_tag]|將目前Container 內的檔案狀況寫成新的Image| |docker **tag** [image_name:image_tag]|設定/更改 Image 名稱及 Image Tag| #### docker push 要怎麼知道要把 Image push 到哪個 repository? 要透過 docker tag 將 image 設成 repo_server _fqdn/image_name:image_tag 例如: ```bash= docker tag newepay:20231010 repo.funday.asia/newebpay:latest docker push repo.funday.asia/newebpay:latest ``` --- ### 如何運行容器、停止容器、重新啟動容器、刪除容器 |指令|用途| |-----|------| |docker **run** [Options] [image_name:image_tag] [Command] [Args for Command]|以 Image 運行一個新的 Container| |docker **exec** [Options] [container_id 或 container_name] [Command] [Args for Command]|在一個運行中的 Container 執行指定的命令| |docker **attach** [container_id 或 container_name]|將Container 的標準輸出、輸入、錯誤,連接到Host。通常用於容器除錯。當你Ctrl-C中斷程式時,會連帶導致容器運行中止!要脫離Attach Mode,請按**Ctrl-PQ**| |docker **stop** [container_id 或 container_name]|停止運行指定的容器| |docker **start** [container_id 或 container_name]|啟動已停止運行指定的容器| |docker **restart** [container_id 或 container_name]|重新啟動證在執行的容器| |docker **rm** [container_id 或 container_name]|刪除已停止的容器| --- ### 如何觀察容器內運行的程式 |指令|用途| |-----|------| |docker **top** [container_id 或 container_name]|查看容器內運行的程式| |docker **inspect** [container_id 或 container_name]|顯示 JSON 格式的 Container 運行狀態資訊| --- ### 如何將容器內的資料取出?如何將檔案放入容器中 |指令|用途| |-----|------| |docker **cp** [container_id 或 container_name]:/path/to/[file] /host/path/to/[file]|將容器內的檔案複製到 Host 指定路徑檔名| |docker **cp** /host/path/to/[file] [container_id 或 container_name]:/path/to/file|將Host 指定路徑檔案複製到 Container 內的指定路徑檔名| --- ### 如何觀察容器內那些檔案被異動 |指令|用途| |-----|------| |docker diff [container_id 或 container_name]|條列容器內部有異動或新增的目錄及檔案,C 表示 Change,A 表示 Append| --- ### 如何觀察容器內程式運行的紀錄 |指令|用途| |-----|------| |docker logs [container_id 或 container_name]|查看容器內程式產生的 Log資訊| --- ### 如何遷移影像、容器、資料檔案 一種方式是把 Image Push 到 Repository Server,然後再從其他 Host Pull Image 下來執行 另一種方式,就是匯出 Image,然後傳送到 Remote Server 再匯入運行 --- ### 如何製作容器影像 * 選取一個可信任的 Base Image * 請選擇 docker Official Image 或是 Verified Publisher 提供的 Image * 熟悉 Dockerfile 指令及用途 --- ### 如何讓容器重新開機就自動運行 #### Docker 的開機後自動運行依賴 docker daemon 來管理 |--restart 參數值|用途說明| |-------------------|----| |no|default值,當容器狀態 exit 時,不要重新啟動| |on-failure|當容器發生異常結束時,自動重啟| |on-failure:n|當容器發生異常結束時,最多重啟 n次| |always|永遠自動重啟容器,即使在重新開機之前,容器就已經停止,開機啟動後,仍要自動執行容器| |unless-stopped|如果在重新開機之前,容器就已經停止,就不會自動重啟| ==--restart 參數不可以與 --rm 參數同時使用!== #### Podman 的開機後自動運行依賴 systemd 來管理 ```bash= podman generate systemd [containber_id 或 container_name] > /usr/lib/systemd/system/myweb.service systemctl enable myweb systemctl status myweb ``` --- Docker Engine --- https://docs.docker.com/engine/ Docker Compose --- https://docs.docker.com/compose/ Docker Build --- https://docs.docker.com/build/ Docker Extensions for Desktop --- https://docs.docker.com/desktop/extensions/ Docker Hub --- https://docs.docker.com/docker-hub/ Docker Plugins Docker Scout --- https://docs.docker.com/scout/ 參考資料 --- * [如何自行建立基底 Image](https://docs.docker.com/build/building/base-images/) from Docker Official Website * [Docker Engine CLI Reference](https://docs.docker.com/engine/reference/commandline/cli/) * [Docker Compose CLI Reference](https://docs.docker.com/compose/reference/) * [Docker Daemon CLI Reference](https://docs.docker.com/engine/reference/commandline/dockerd/) * [Docker Registry API Reference](https://docs.docker.com/registry/) * [Docker Engine API](https://docs.docker.com/engine/api/) * [Docker Hub API Reference](https://docs.docker.com/docker-hub/api/latest/#tag/authentication/operation/PostUsersLogin) * [Dockerfile Reference](https://docs.docker.com/engine/reference/builder/) * [How to Create Base Image](https://docs.docker.com/build/building/base-images/) * [Docker Image Layer Reference](https://docs.docker.com/storage/storagedriver/) * [Docker Engine Network Reference](https://docs.docker.com/network/) * [Docker Container Logs](https://docs.docker.com/config/containers/logging/) * [Docker Security Reference](https://docs.docker.com/engine/security/) * [Docker Swarm Mode](https://docs.docker.com/engine/swarm/) * [Docker Daemon Reference](https://docs.docker.com/config/daemon/) Docker Engine Security --- * [Protect the Docker daemon socket](https://docs.docker.com/engine/security/protect-access/) * [Verify repository client with certificates](https://docs.docker.com/engine/security/certificates/) * [AppArmor security profiles for Docker](https://docs.docker.com/engine/security/apparmor/) * [Seccomp security profiles for Docker](https://docs.docker.com/engine/security/seccomp/) * [Isolate containers with a user namespace](https://docs.docker.com/engine/security/userns-remap/) [Docker Swarm Mode](https://docs.docker.com/engine/swarm/)