極簡概括 官網:https://www.docker.com 利用比虛擬機更加輕量級的容器化虛擬技術,能夠低成本的把當前環境快速打包或在新環境部署相同子環境的運維工具,基於Go語言實現,跨平臺(支持Linux、Windows、MacOS)。 通俗類比:無論什麼牌子什麼價位的主機,都可以利用同一個的W ...
極簡概括
官網:https://www.docker.com
利用比虛擬機更加輕量級的容器化虛擬技術,能夠低成本的把當前環境快速打包或在新環境部署相同子環境的運維工具,基於Go語言實現,跨平臺(支持Linux、Windows、MacOS)。
通俗類比:無論什麼牌子什麼價位的主機,都可以利用同一個的Windows鏡像文件安裝相同的系統,同時也支持對操作系統的不同進度進行打包,方便安裝到另一臺設備上。
解決問題
- 環境統一:本地開發環境、測試環境、生產環境不一致,本地測試沒問題,一到線上就出故障。Docker 可以打包應用程式及其所有依賴項,確保在任何環境中都能以相同的方式運行。
- 降低運維成本: Docker 可以將應用程式及其所有依賴項打包到一個稱為 Docker 鏡像的容器中。這些鏡像可以在秒級時間快速部署到任何支持 Docker 的主機上。
- 微服務架構支持: Docker 容器可以用於構建和部署微服務架構中的各個組件,每個微服務可以打包為一個獨立的容器。這樣可以實現高度的可擴展性、靈活性和可維護性。
適用場景
- 捲:為什麼要學?很多人都會docker,不得不捲。
- 微服務架構:Docker 被廣泛用於微服務架構中,每個微服務可以打包為一個 Docker 容器,使得應用程式模塊化、可擴展和易於管理。
- 持續集成/持續部署(CI/CD):Docker 可以用於構建 CI/CD 管道,通過容器化應用程式,可以實現自動化的構建、測試和部署流程,提高開發團隊的效率和交付速度。
- 開發環境一致性:開發團隊可以使用 Docker 來創建一致的開發環境,確保開發、測試和生產環境之間的一致性,減少因環境差異導致的問題。
- 混合雲和跨平臺部署:由於 Docker 容器具有高度可移植性,可以在不同的雲平臺和操作系統上運行,適用於混合雲環境和跨平臺部署。
優點
- 輕量級: Docker 容器比傳統的虛擬機更輕量級,因為它們共用主機系統的內核,並且不需要運行完整的操作系統。
- 快速操作: 由於 Docker 容器與宿主機共用內核,並且容器中的應用程式直接運行在主機的操作系統上,因此它們的安裝、部署、啟動速度非常快。
- 可移植: Docker 容器可以在不同的環境中輕鬆移植和部署,一次打包處處運行。
- 一致性: Docker 容器提供了一個一致的運行環境,確保應用程式在開發、測試和生產環境中的行為一致。
- 易於管理: Docker 提供了強大的命令,使得可以完成度容器、鏡像、倉庫的各種操作。
- 資源隔離: Docker 容器提供了一定程度的資源隔離,使得不同的容器可以在同一臺主機上並行運行而不會相互干擾。
- 生態系統支持: Docker 擁有龐大的生態系統,意味著有成熟的解決方案,不容易遇見死衚衕。
缺點
- 學習成本: Docker 擁有自己的一套規則,需要運維或者開發者做功課。
- 沙箱逃逸:docker不比虛擬機有更好的隔離性,可能引發沙箱逃逸漏洞,(虛擬機也有沙箱逃逸漏洞)。
- 系統相容:32位的CentOS系統不支持安裝Docker。
- 像是MySQL、等需要高可用和高IO的組件,docker能部署,但有缺點(文末有詳解)。
Docker三板斧
- 容器:是一個獨立、輕量級的運行環境,一些組件在容器里運行,(類比裝好的Windows系統)。
- 鏡像:是一個只讀的模板,存放了應用程式的各種配置,可以被分享、複製,(類比Windows的ISO鏡像文件)。
- 倉庫:類似GitHub,做鏡像的共用與托管,可見其流行程度和重要性,(類比各版本Windows的ISO鏡像文件下載網站)。
理解虛擬化中的虛擬
- 從軟硬體交互角度講:操作系統的運行離不開電腦硬體(CPU、記憶體、硬碟),然而容器卻依附於宿主機又建立的子系統,再和硬體交互,從上帝視角看,容器就像虛擬出來的真實系統一樣。
- 從軟硬體數據角度講:docker中的數據,對於磁碟硬體實體而言,也只是一塊實體的二進位數據,所謂的鏡像、系統、容器都存在於軟體,像虛擬出來的世界一樣。
對比與虛擬機
- 量級不同:虛擬機是運行一整個系統,而docker是利用宿主機的內核部分。
- 隔離性:Docker 提供了進程級別的隔離,虛擬機提供了更高級的隔離策略。
- 部署難度:docker幾個命令輕鬆部署,而虛擬機需要手動安裝鏡像。
為什麼Docker會比虛擬機快
docker利用的是宿主機的內核,不需要像虛擬機一樣重新載入操作系統進行各種初始化環節。
多個docker實例共用宿主機內核資源,而多個虛擬機是重新運行一套操作系統。
安裝(CentOS7.6環境)
yum install -y yum-utils
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
systemctl start docker
systemctl enable docker
#測試運行,如果出現版本號,則說明安裝成功
docker -v
Docker version 26.0.0, build 2ae903e
配置阿裡雲鏡像加速
登錄阿裡雲之後,搜索容器鏡像服務,進入專題頁面後到控制台,點擊個人版,點擊鏡像工具,然後點擊鏡像加速器。
複製上面的bash shell,然後執行它。
/etc/docker/daemon.json 文件是 Docker 使用的配置文件,用於指定 Docker 守護進程的各種選項和設置。
mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://xxxx.mirror.aliyuncs.com"]
}
EOF
systemctl daemon-reload
systemctl restart docker
卸載(CentOS7.6環境)
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
存儲在中的映像、容器、捲和網路/var/lib/docker/卸載Docker時不會自動刪除,所以需要
rm -rf /var/lib/docker /var/lib/containerd
虛懸鏡像
- 概念:虛懸鏡像又叫做dangling image。倉庫名,標簽名都是none的鏡像,是虛懸鏡像。
- 原因:docker import或者docker build時沒有設置名字和版本號。
- 刪除:可以使用rmi命令刪除,也可以使用docker image prune刪除所有虛懸鏡像。
基礎命令
啟動、停止、重啟
systemctl start/stop/restart docker
開機自啟動
systemctl enable docker
命令幫助文檔
docker --help
某個命令幫助文檔
docker 命令 --help
查看狀態
systemctl status docker
docker概要
docker info
docker system df
TYPE(類型) TOTAL(資源總數) ACTIVE(當前運行的資源總數) SIZE(占空間大小) RECLAIMABLE(可回收空間大小)
Images(鏡像) 0 0 0B 0B
Containers(容器) 0 0 0B 0B
Local Volumes(本地捲) 0 0 0B 0B
Build Cache(構建緩存) 0 0 0B 0B
容器命令
docker run 鏡像名稱 [-it] [shell類型] [/bin/bash]
docker會在本機中尋找該鏡像,如果本機存在則直接運行,如果不存在,則會去阿裡雲 docker hub上找,如果能找到下載後運行,找不到則報錯。
註意同一個鏡像可以啟多個容器,每個容器之間,預設不互通。
--name 為容器指定一個名字,如果不指定,系統隨機分配
-d 後臺守護進程運行並返回容器id。
-i 以交互模式運行容器。
-t 為容器分配一個終端。
-P 隨機埠映射。
-p 指定埠映射 -p 外部埠:容器埠。
-it會經常配合使用,因為運行的組件,可能需要進入這個容器去做一些操作。
例如要運行一個Ubuntu,進入Ubuntu,要輸入docker run -it ubuntu /bin/bash
/bin/bash表示用什麼shell啟動一個終端。
docker ps [-qa]
類比宿主機的ps,docker 只是針對容器的ps
CONTAINER ID(容器id) IMAGE(鏡像id) COMMAND(終端) CREATED(創建時間) STATUS(狀態) PORTS(埠) NAMES(容器名,docker run --name時會顯示自定義的用戶名)
162cdb700348 ba6acccedd29 "/bin/bash" 13 seconds ago Up 12 seconds romantic_kare
-a 顯示全部的容器,預設只顯示正在運行的容器
-q 只顯示容器id
docker ps中的STATUS欄位,如果顯示UP字樣,說明已經啟動,如果顯示Exited字樣,說明已經停止運行。
退出容器
方式一:exit 容器停止。
方式二:Ctrl p q 容器不會停止。
docker exec [-it] [-d] 容器id [/bin/bash]
用例:docker exec -it 5e66cda41f9a /bin/bash
重新進入容器,再容器內部的命令行執行exit,不會導致容器停止。
-d 後臺守護進程運行並返回容器id。
-i 以交互模式運行容器。
-t 為容器分配一個終端。
docker attach 容器id
用例:docker attach 容器id
重新進入容器,再容器內部的命令行執行exit,會導致容器停止。
docker start/stop/restart 容器id或容器名
啟動、關閉、重啟容器。
註意開啟容器,不等於進入這個容器。
docker rm [-f] 容器id或容器名
刪除容器。
docker rm $(docker ps -aq)可刪除所有容器。
docker logs 容器id
查看某個容器的日誌。
docker top 容器id
類比top命令,查看容器的資源占用情況
UID PID PPID C STIME TTY TIME CMD
root 27931 27910 0 00:00 ? 00:00:00 nginx: master process nginx -g daemon off;
UID: 進程的用戶標識符(User ID),表示進程所屬的用戶。
PID: 進程標識符(Process ID),是內核為每個進程分配的唯一標識符。
PPID: 父進程標識符(Parent Process ID),表示啟動當前進程的父進程的PID。
C: 進程的CPU利用率,表示進程正在使用的CPU核心數量。
STIME: 進程的啟動時間,表示進程啟動的時間戳。
TTY: 進程所關聯的終端設備(如果有)。
TIME: 進程已經使用的CPU時間。
CMD: 進程的命令行,表示正在運行的進程的命令。
docker inspect 容器id
會返回一個大json,用來顯示容器的信息
docker cp
容器複製到宿主機:docker cp 容器id:/路徑 /路徑
宿主機複製到容器:docker cp /路徑 容器id:/路徑
文件複製與容器的開始與結束無關。
鏡像命令
docker images [-a] [-q]
列出本機上的所有鏡像
REPOSITORY(鏡像倉庫源) TAG(標簽版本號) IMAGE ID(鏡像ID) CREATED(創建時間) SIZE(大小)
同一個REPOSITORY有多個TAG,好比CentOS,以後6、7、8的版本一樣。
如果不指定一個鏡像的版本標簽,docker將預設使用latest鏡像。
-a 表示列列舉本地的所有驚喜那個
-q 表示只顯示鏡像id
docker rmi [-f] [鏡像id或鏡像名] [...]
刪除某鏡像
-f 強制刪除,不加-f,正在運行的容器將無法刪除,不推薦使用。
docker rmi -f $(docker images -qa) 刪除全部,極不推薦用。
docker export 容器id > 文件名
導出容器
docker export 容器id > 容器名.dat
docker import 備份容器文件 容器名[:tag]
通過文件導入容器,如果不寫tag,那預設是latest。
docker commit -m 註釋 -a 作者 容器id 鏡像名[:版本號]
提交容器副本,使其成為一個新的鏡像
docker tag old_name:old_tag new_name:new_tag
相當於在原有的基礎上複製出來一份鏡像並改名,用docker images查看,old,和new是兩條數據。
倉庫命令
docker search 組件名 [--limit n]
NAME DESCRIPTION STARS(星星) OFFICIAL(是否官方) AUTOMATED(是否自動構建)
作者/包名 Official build of Nginx. 18879 [OK]
--limit n,可進行數量篩選前幾個
docker pull 鏡像名[:版本]
類比git pull,向共有倉庫拉取鏡像。
docker push [OPTIONS] NAME[:TAG]
將鏡像推送到遠程倉庫,例如推送到阿裡雲。
docker push registry.cn-hangzhou.aliyuncs.com/xxx/xxx:[鏡像版本號]
本地鏡像發佈到阿裡雲
- 請免費開啟容器鏡像服務,然後選擇一個地區的節點,我選的是杭州。
- 在訪問憑證頁面先設置密碼,對docker login命令的密碼做鋪墊。https://cr.console.aliyun.com/cn-hangzhou/instance/credentials
- 新建命名空間,然後新建鏡像倉庫,創建鏡像倉庫的最後一步選擇,本地倉庫。https://cr.console.aliyun.com/cn-hangzhou/instance/namespaces
- 創建完成之後,跟隨阿裡雲的操作指南第3步,然後去執行它
docker login --username=xxx registry.cn-hangzhou.aliyuncs.com
docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/xxx/xxx:[鏡像版本號]
docker push registry.cn-hangzhou.aliyuncs.com/xxx/xxx:[鏡像版本號]
可使用以下命令去從遠程倉庫拉取鏡像到本地
docker pull registry.cn-hangzhou.aliyuncs.com/xxx/xxx:[鏡像版本號]
本地鏡像發佈到公司或個人的私有雲(Docker Registry)
當前測試的機器區域網IP是192.168.0.180,需要再來一臺機器模擬Docker Registry,IP為192.168.0.160,首先按照上文所述安裝docker,不然docker命令不存在。
在160機器上,安裝registry,執行docker images 查看是否安裝成功。
docker pull registry
在160機器上,創建一個容器捲映射地址
mkdir /docker
在160機器上,後臺運行這個registry
docker run --name docker_registry -d -v /docker:/docker --privileged=true -p 5000:5000 registry
在160機器上,查看是否成功運行
docker ps
再180機器上,vim /etc/docker/daemon.json,指定Docker客戶端可以連接的不安全的Registry地址,
避免報錯Get "https://192.168.0.160:5000/v2/": http: server gave HTTP response to HTTPS client
,
"insecure-registries":["192.168.0.160:5000"]
在180機器上,重啟docker。
systemctl daemon-reload
systemctl restart docker
在180機器上,使用docker tag 命令做個鏡像複製和更名。
註意這個名字192.168.0.160:5000/zs_ubuntu:0.0.1,要和docker push後面跟的保持一致
docker tag zs_ubuntu:0.0.1 192.168.0.160:5000/zs_ubuntu:0.0.1
在180機器上,執行推送,註意這個192.168.0.160:5000/zs_ubuntu:0.0.1,要與docker tag的對應上。
docker push 192.168.0.160:5000/zs_ubuntu:0.0.1
在180機器上,驗證是否push成功(除了IP和埠,其餘都是固定路徑):
curl 192.168.0.160:5000/v2/_catalog
{"repositories":["zs_ubuntu"]}
168.0.160:5000/v2/_catalog能看見鏡像名,但是看不見鏡像版本號,到時候拉取會存在困難,此時就需要其它命令的參與:
curl http://192.168.0.160:5000/v2/鏡像名稱/tags/list
curl http://192.168.0.160:5000/v2/zs_ubuntu/tags/list
在其它機器上,其它人拉取鏡像:
docker pull 192.168.0.160:5000/zs_ubuntu:0.0.1
在160機器上,對私有倉庫存放鏡像的增操作:
如上所講。
在160機器上,對私有倉庫存放鏡像的刪操作:
docker exec -it registry容器id sh
鏡像文件是被放到 目錄下的,/var/lib/registry/docker/registry/v2/repositories,在這裡直接刪除指定目錄即可。
在160機器上,對私有倉庫存放鏡像的改操作:
不常用。
在160機器上,對私有倉庫存放鏡像的查操作:
curl 192.168.0.160:5000/v2/_catalog
為什麼不建議在docker中使用MySQL
- 數據高可用問題:資料庫存儲的是公司的各項核心數據,求的是穩定,而不是一時候的部署方便。使用容器捲可以持久化數據。但是如果容器不小心停止,或者配置出錯,造成的事故影響高可用,為了保證MySQL數據的高可用,下足了功夫,引入了redo log和不同的刷盤機制來應對性能與高可用之間的權衡,而docker的Union FS 鏡像層提供持久存儲,但是高可用缺乏保證。
- 性能問題:MySQL最大的性能瓶頸在於IO,原本是刷盤後就可以了,若使用了docker,如果沒有容器捲很不保險,如果使用了容器捲,讀寫問題又多了一個流程。
- 使用受限:整個業務所使用的技術組件中,壓力最大的往往就是資料庫,MySQL包了一層容器,相當於多了一個環節,CPU、記憶體、磁碟IO、網路等,可能會受到一些限制。
Portainer:輕量級容器監控工具
- 官方文檔:https://docs.portainer.io
- 極簡概括:Portainer是一個輕量級的容器管理工具,它提供了用戶界面用於管理Docker容器和集群,常用的Docker命令行操作,都可以通過這個組件在圖形化界面完成。
- 註意:預設的9000埠,如果宿主機對內占用或者其它容器對外開放了9000埠,Nginx與PHP進行TCP方式的通信(還有一種UNIX的Socket通信),PHP-FPM進程會占用9000埠,所以需要修改portainer的埠為非9000。
- 安裝並初始化:
安裝
docker run --name portainer --restart=always -d -p 8000:8000 -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer
若埠衝突,可以這樣改
docker run --name portainer --restart=always -d -p 8000:8000 -p 9001:9001 -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer
使用docker ps查看是否運行
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
073537d3fb66 portainer/portainer "/portainer" 30 seconds ago Up 29 seconds 0.0.0.0:8000->8000/tcp, :::8000->8000/tcp, 0.0.0.0:9000->9000/tcp, :::9000->9000/tcp portainer
訪問相關頁面並註冊用戶:
http://192.168.0.180:9000/#/init/admin
註冊成功後點擊local,再次點擊local,就會看到Dashboard儀錶盤頁面。
http://192.168.0.180:9000/#/dashboard
之後進行各種查看和操作……
CAdvisor+InfluxDB+Granfana(CIG重量級容器監控工具)
這種對於個人開發者或小公司跟本用不上,個人開發者和小公司不需要太複雜的管理工具,而大公司有專門的運維,不需要開發者關註,僅做瞭解。
- 極簡概括:簡稱CIG(C負責監控收集,I負責存儲數據,G負責展示圖表),是對docker進行重量級的監控工具。
- CAdvisor(Container Advisor)是一個用於監控容器性能的工具。它能夠收集關於運行中的容器的信息,例如 CPU 使用率、記憶體使用量、網路統計等,並將這些數據提供給其他監控或可視化工具。
- InfluxDB 是一個時間序列資料庫,特別適用於處理和存儲監控數據。InfluxDB 允許將收集到的數據存儲起來,並提供靈活的查詢功能,以便進行數據分析和可視化。
- Grafana 則是一個開源的監控和數據可視化平臺。它能夠與各種數據源集成,包括 InfluxDB,用於創建豐富的監控儀錶盤和報表,展示監控數據的實時和歷史變化,以及執行定製化的數據分析。