極簡概括
官網: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,用於建立豐富的監控儀表盤和報表,展示監控資料的實時和歷史變化,以及執行定製化的資料分析。