指南)
拿 Docker 快速開始這個標題來說網(wǎng)上教程一抓一大把但大部分都卡在裝完 Docker Desktop 就不知道怎么往下走這個環(huán)節(jié)。要么是安裝報錯直接把人勸退要么是跑起來之后完全不懂容器和鏡像的關(guān)系遇到 MySQL 起不來、網(wǎng)絡不通、權(quán)限拒絕這類問題只能干瞪眼。這篇東西我打算換個寫法直接從新手最常見的真實場景切入把安裝、踩坑、跑通第一個容器、部署 MySQL 和 Redis、排查日常故障這幾件事串成一條完整的鏈路命令直接給理由也講清楚。先說清楚一個容易誤導人的概念Docker 不是虛擬機。很多第一次接觸的人會以為 Docker 是那種裝一個操作系統(tǒng)鏡像啟動一個完整系統(tǒng)的東西這是錯的。Docker 里的容器共享宿主機內(nèi)核只是把進程、文件系統(tǒng)、網(wǎng)絡、環(huán)境變量隔離在各自的命名空間里所以一個容器往往只有幾十 MB 到幾百 MB啟動時間以毫秒級計算同樣一臺機器能跑的容器數(shù)量和虛擬機完全不是一個量級。這也是為什么有人能用 N100 這種低功耗小主機跑二十個 Docker 容器——每個容器本身就只是幾個進程而已而不是二十個操作系統(tǒng)。1.1 容器和虛擬機的本質(zhì)區(qū)別判斷自己到底有沒有理解容器可以問一個問題容器里的 Ubuntu 有內(nèi)核嗎答案是沒有。你執(zhí)行uname -r看到的其實是宿主機的內(nèi)核版本。容器鏡像里攜帶的是 rootfs根文件系統(tǒng)和用戶態(tài)的程序比如 bash、glibc、MySQL 服務本身內(nèi)核用的是宿主機的。這帶來的直接后果是容器天然輕量、啟動快、資源占用低但也意味著容器里不能隨便改內(nèi)核參數(shù)、不能加載內(nèi)核模塊遇到依賴特定內(nèi)核版本的應用會比較尷尬。虛擬機就不一樣每個虛擬機都有獨立的 Guest OS有自己完整的內(nèi)核隔離性更強但啟動要幾十秒到幾分鐘鏡像動輒幾個 GB運行時要預分配內(nèi)存和 CPU。所以 Docker 適合微服務、CI/CD、應用打包交付VM 適合需要強隔離、跨內(nèi)核的場景。這倆不是替代關(guān)系但在快速開始這個語境下Docker 確實是當下部署應用最主流的姿勢。1.2 Docker 解決的核心痛點結(jié)合熱搜詞里docker是干什么的這個問題我用一句大白話回答Docker 讓你的應用打包一次到處運行。以前部署一個 MySQL你得下載安裝包、處理依賴庫、配配置文件、設系統(tǒng)服務到了另一臺機器這套流程要再來一遍。用 Docker 之后鏡像里已經(jīng)把 MySQL 和它需要的一切都打包好了你只需要docker run服務就起來了。開發(fā)環(huán)境、測試環(huán)境、生產(chǎn)環(huán)境全都用同一個鏡像杜絕了在我電腦上是好的這種甩鍋現(xiàn)場。另外 Docker 還解決了環(huán)境隔離和快速清理的問題。想裝一個 GitLab、裝一個青龍面板、跑一個 DVWA 靶場練手直接拉官方鏡像跑起來不用了就docker rm -f刪掉宿主機干干凈凈不會像傳統(tǒng)安裝方式那樣留下一堆殘留文件。2. 安裝 Docker 之前需要搞明白的三件事安裝本身不難但很多報錯其實是安裝前的平臺理解出了問題。這里把三個關(guān)鍵決策點說透能避開后面 80% 的坑。2.1 你的系統(tǒng)平臺決定了走哪條安裝路線Docker 的安裝方式基本分成兩大流派帶圖形界面的 Docker Desktop適合 Windows 和 macOS以及純命令行安裝 Docker Engine適合 Linux 服務器。Windows 裝 Docker Desktop 需要 WSL2 或 Hyper-V 支持Mac 上有 Apple Silicon 和 Intel 兩種芯片的區(qū)分Linux 又分為 apt/yum/dnf 不同包管理器。選錯路線最常見的后果就是裝完了啟動不了然后陷入virtualization support not detected這類報錯循環(huán)。如果你用的是 Ubuntu 或者 CentOS 這類 Linux 服務器就直接裝 Docker Engine不要裝 Docker Desktop。Docker Engine 就是服務器上跑的守護進程dockerd加客戶端docker CLI沒有 GUI但對服務器部署來說完全夠用。Ubuntu 走 aptCentOS 7 走 yumCentOS 8 以上走 dnf。具體命令我放到后面先記住一個原則服務器環(huán)境永遠優(yōu)先 Docker Engine桌面環(huán)境圖省事才選 Docker Desktop。2.2 Windows 用戶繞不開的 WSL2 / Hyper-V 前置Windows 裝 Docker Desktop 的報錯里出現(xiàn)頻率最高的就是 Docker Desktop failed to start because virtualisation support wasnt detected也就是熱搜詞里反復出現(xiàn)的那條。這不是 Docker 本身的問題而是 Windows 的虛擬化功能沒開全。Docker Desktop 在 Windows 上需要虛擬機支持來跑 Linux 容器這個能力來自 WSL2 或者 Hyper-V。排查鏈路應該是這樣的第一步打開任務管理器 - 性能 - CPU看右下角虛擬化是否顯示已啟用。如果顯示已啟用說明 BIOS 層面的虛擬化是開著的如果顯示已禁用需要進 BIOS 開啟 Intel VT-x 或 AMD SVM。注意Windows 的虛擬化是否啟用除了 BIOS還取決于啟用 Windows 功能里的虛擬機平臺和 Hyper-V 有沒有勾上。第二步以管理員身份打開 PowerShell執(zhí)行wsl --status查看 WSL 版本如果提示沒有 WSL需要先安裝 WSL2執(zhí)行wsl --install即可。第三步確認 Windows 功能里適用于 Linux 的 Windows 子系統(tǒng)和虛擬機平臺這兩項都是勾選狀態(tài)然后用bcdedit /set hypervisorlaunchtype auto確保 Hyper-V 啟動類型是自動。我見過大量案例BIOS 虛擬化開著、WSL 也裝了Docker Desktop 還是啟動失敗最后發(fā)現(xiàn)是虛擬機平臺這個功能沒開。這三步必須挨個排查任何一環(huán)斷了Docker Desktop 都起不來。2.3 Linux 用戶最穩(wěn)的 Docker Engine 安裝路徑Linux 安裝 Docker Engine 的方式里最推薦的是配置官方 apt 源后安裝。以 Ubuntu 為例安裝基礎(chǔ)工具和證書sudo apt-get update sudo apt-get install ca-certificates curl gnupg lsb-release然后添加 Docker 官方 GPG 密鑰和倉庫地址sudo mkdir -p /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg echo deb [arch$(dpkg --print-architecture) signed-by/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable | sudo tee /etc/apt/sources.list.d/docker.list /dev/null更新索引后直接安裝sudo apt-get update sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin安裝完成后執(zhí)行sudo systemctl enable docker sudo systemctl start docker再用sudo docker run hello-world驗證。為什么不用一條 curl 腳本裝官方那個get.docker.com的一鍵腳本適合快速實驗但生產(chǎn)環(huán)境我建議手動加源安裝因為后續(xù)換鏡像源、升級版本時路徑更清晰也方便排查問題。CentOS 7 的坑主要是默認的 yum 源里 Docker 版本太老必須用官方源或阿里云源不然裝出來的可能還是 Docker 1.13。3. Docker Desktop 安裝實戰(zhàn)與啟動失敗排查Docker Desktop 是 Windows 和 macOS 上最容易上手的方式但也是報錯重災區(qū)。這里把完整的安裝流程和兩類高頻啟動失敗問題的排查鏈路寫出來照做就行。3.1 Windows 和 macOS 的安裝步驟詳解Windows 的安裝流程比 Linux 復雜完整步驟是開啟 Windows 功能控制面板 - 程序 - 啟用或關(guān)閉 Windows 功能勾選適用于 Linux 的 Windows 子系統(tǒng)、虛擬機平臺、Hyper-V三項其中完整版 Docker Desktop 依賴 Hyper-VWSL2 模式下只依賴前兩項。安裝 WSL2 內(nèi)核執(zhí)行wsl --update更新內(nèi)核然后執(zhí)行wsl --set-default-version 2確保以后創(chuàng)建的發(fā)行版默認走 WSL2。從 Docker 官網(wǎng)下載 Docker Desktop Installer.exe雙擊安裝安裝過程中如果提示是否使用 WSL2選“是”。安裝完成后重啟系統(tǒng)啟動 Docker Desktop等右下角鯨魚圖標變穩(wěn)定狀態(tài)。macOS 的步驟類似從官網(wǎng)下載 Docker.dmg 拖入 Applications 即可。Apple SiliconM1/M2/M3芯片的 Mac 默認走虛擬化框架不需要額外裝虛擬機軟件Intel 芯片的老 Mac 需要確認是否支持 HyperKit不過 Docker Desktop 新版已經(jīng)統(tǒng)一用 Apple 的 Virtualization.framework這點基本不用操心了。注意下 Mac 需要 macOS 11 Big Sur 或更高版本太老的系統(tǒng)裝不上新版的 Docker Desktop。3.2 virtualization support not detected報錯的完整排查鏈路這條報錯幾乎天天有人問完整排查思路按優(yōu)先級排列第一步確認 BIOS 虛擬化開關(guān)。重啟進 BIOS找 Intel Virtualization Technology 或 SVM Mode設為 Enabled。注意有些品牌機的 BIOS 里這個選項叫法不同比如 Dell 叫 VirtualizationHP 叫 Virtualization Technology聯(lián)想部分機型要在 Security - Virtualization 里開。第二步確認 Windows 功能。執(zhí)行systeminfo | findstr Hyper-V如果顯示 Hyper-V Requirements: A hypervisor has been detected. Features required for Hyper-V will not be displayed. 說明 Hyper-V 已經(jīng)在跑如果顯示 Virtualization Enabled In Firmware: Yes說明固件虛擬化正常但 Hyper-V 組件可能沒裝。這時去啟用或關(guān)閉 Windows 功能里勾上虛擬機平臺和Hyper-V。第三步核對 WSL2 狀態(tài)。執(zhí)行wsl -l -v如果版本顯示為 1需要wsl --set-version 發(fā)行版名 2升級。如果提示沒有已安裝的發(fā)行版用wsl --install -d Ubuntu裝一個。第四步檢查 Docker Desktop 的配置。打開 Settings - General確保勾選了 Use the WSL 2 based engine。如果用的是 Hyper-V 模式在 Settings - Resources - Advanced 里確認沒有把內(nèi)存設置得太低。這套鏈路走完至少能解決 95% 的啟動失敗。剩下的情況多半是 Windows 老版本的問題比如 Win10 的 1903 以下版本對 WSL2 支持不完整建議直接升級系統(tǒng)。3.3 failed to start docker application container engine的原因與處理這條報錯常見于 Linux 上 Docker 服務啟動失敗以及在 Windows 上 Docker Desktop 已經(jīng)能打開但內(nèi)部引擎沒跑起來。Linux 下先執(zhí)行sudo systemctl status docker看具體失敗原因。最常見的是配置了鏡像加速器地址但寫錯了格式或者/etc/docker/daemon.json文件里的 JSON 語法錯誤導致 dockerd 啟動崩掉。排查方法是先移走配置文件再啟動sudo mv /etc/docker/daemon.json /etc/docker/daemon.json.bak sudo systemctl start docker如果這樣啟動了說明問題出在 daemon.json。重新編輯時注意配置格式鏡像加速地址要加上https://前綴多個地址用數(shù)組。Windows 下的同類問題多數(shù)是退出 Docker Desktop 后重新啟動、徹底重置 WSL 的 Docker 數(shù)據(jù)來解決不要一上來就卸載重裝先試wsl --shutdown再啟動 Docker Desktop成功率很高。4. 第一次跑容器的完整流程從 hello-world 到 Nginx安裝完 Docker接下來的流程才是快速開始的意義所在。這一節(jié)帶你走一遍完整的驗證環(huán)境 - 拉鏡像 - 跑容器 - 操作容器鏈路。4.1 用 docker info 和 hello-world 驗證環(huán)境是否真正可用裝好 Docker 后第一件事不是急著部署應用而是確認環(huán)境正常。執(zhí)行docker info如果看到Server Version和Storage Driver都正常顯示說明 dockerd 守護進程在跑。如果看到ERROR: permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock這是熱搜詞里的另一個高頻問題說明當前用戶不在 docker 用戶組里執(zhí)行sudo usermod -aG docker $USER然后注銷重登或重啟系統(tǒng)。然后跑官方提供的測試鏡像docker run hello-world這個鏡像很小只有幾 KB作用是打印一段說明文字表示 Docker 端到端工作正常。如果你在服務器上沒有 sudo 權(quán)限記得所有 docker 命令前加 sudo如果你已經(jīng)加入了 docker 用戶組可以不用 sudo。這里提醒一句能用用戶組解決就不要用 sudo 執(zhí)行 docker 命令sudo 會把文件權(quán)限搞得很難受而且在某些自動化的腳本環(huán)境里容易出現(xiàn)雞生蛋問題。4.2 拉取鏡像和運行容器Nginx 實例拆解hello-world 只是驗證真正跑一個有實際意義的服務用 Nginx 最合適。先把鏡像拉到本地docker pull nginx:latestdocker pull的動作是拉鏡像鏡像是什么本質(zhì)上是一層一層的只讀文件系統(tǒng)的集合里面包含了 Nginx 的程序文件、配置文件、依賴庫。拉下來之后本地會有這份鏡像緩存下次docker run直接用本地鏡像不會再去遠程倉庫拉。然后啟動一個前臺運行用于觀察輸出或者后臺運行daemonized的容器docker run -d --name my-nginx -p 8080:80 nginx命令拆解-d表示后臺運行--name my-nginx給容器起名-p 8080:80把宿主機的 8080 端口映射到容器內(nèi)的 80 端口nginx是要運行的鏡像名。映射端口的邏輯很多人第一次犯迷糊記住一句話左邊是宿主機端口右邊是容器內(nèi)端口。瀏覽器訪問http://localhost:8080宿主機把流量轉(zhuǎn)發(fā)給容器里的 80 端口Nginx 接收之后返回默認頁面。驗證容器狀態(tài)docker ps如果能看到一個狀態(tài)為 Up 的 my-nginx 容器說明第一個真實服務已經(jīng)跑起來了。這條命令的意義相當于進程管理器的 Docker 版列出所有正在運行的容器它只顯示運行中的容器已經(jīng)停止的用docker ps -a查看。兩者之間的差別是新手最容易忽略的docker ps -a會把停止狀態(tài)的容器也列出來排查問題的時候永遠先用-a看全貌。4.3 進入容器內(nèi)部查看文件系統(tǒng)與日志跑起來之后你需要具備的三種最基本的觀察能力查看容器日志docker logs my-nginx這一步對應的是傳統(tǒng)方式下 tail 日志文件的習慣。docker logs會把容器的 stdout/stderr 全部打出來所以平時寫應用時記得把日志打到 stdout而不是寫到容器內(nèi)的日志文件里——否則用docker logs看什么都是空的。進入容器內(nèi)部docker exec -it my-nginx bashexec表示在運行中的容器里執(zhí)行命令-it是分配交互終端bash是要執(zhí)行的 shell。進去之后執(zhí)行l(wèi)s /usr/share/nginx/html就能看到 Nginx 默認網(wǎng)頁的存放位置。這個能力對應的是傳統(tǒng)方式下 SSH 到服務器上排查但在容器里你沒有 systemd、沒有 init 進程也沒有完整系統(tǒng)工具包很多命令不存在是很正常的事別慌。退出用exit。把宿主機的文件復制進容器docker cp index.html my-nginx:/usr/share/nginx/html/這個是臨時改容器內(nèi)文件的做法但不建議長期依賴。容器的文件系統(tǒng)是臨時的容器被刪除后一切改動都會消失正確的做法是用數(shù)據(jù)卷volume掛載這部分在后面 MySQL 實例里具體講。5. 每個新手都逃不過的兩個部署實例MySQL 8.0 與 Redis 主從熱搜詞里docker安裝mysql失敗、docker安裝mysql8.0并使用、docker安裝redis主從占了很大比例說明數(shù)據(jù)庫類應用是新手最普遍的實戰(zhàn)場景。這兩個實例跑通你基本就能理解 Docker 在數(shù)據(jù)持久化、端口映射、多容器協(xié)作上的核心用法。5.1 用 MySQL 8.0 理解端口映射和數(shù)據(jù)持久化先看一個新手最常見的失敗案例。很多人在 Docker 里裝 MySQL 失敗錯誤信息是docker: Error response from daemon: driver failed programming external connectivity on endpoint查了半天發(fā)現(xiàn)是端口被占用。宿主機的 3306 已經(jīng)被本地安裝的 MySQL 占了Docker 再映射 3306 自然沖突。解決辦法很簡單把宿主機的映射端口換掉docker run -d \ --name mysql8 \ -p 3307:3306 \ -e MYSQL_ROOT_PASSWORDyourpassword \ -e MYSQL_DATABASEtestdb \ -v mysql_data:/var/lib/mysql \ mysql:8.0這里有幾個關(guān)鍵點要講透第一-e環(huán)境變量是 MySQL 鏡像的配置入口。MYSQL_ROOT_PASSWORD設置 root 密碼MYSQL_DATABASE在首次啟動時自動創(chuàng)建數(shù)據(jù)庫。如果忘了設置 root 密碼容器啟動后你是進不去的到時候又要查一堆初始化方法所以這一步最好在run時想清楚。第二-v mysql_data:/var/lib/mysql是數(shù)據(jù)卷掛載。mysql_data是命名卷Docker 會把容器里/var/lib/mysql目錄的數(shù)據(jù)存到宿主機一個專門管理的目錄下。這樣即使容器被刪除數(shù)據(jù)還在下次用同一個卷名啟動新容器數(shù)據(jù)自動接上。這一點極其重要容器的文件系統(tǒng)是臨時的不加數(shù)據(jù)卷rm 掉容器等于刪除數(shù)據(jù)庫。啟動后連接測試docker exec -it mysql8 mysql -uroot -p輸入密碼進入 MySQL 命令行后你可以執(zhí)行show databases;看到 testdb 已經(jīng)創(chuàng)建。如果想從宿主機外部訪問要確認宿主機的 3307 端口能被連接防火墻問題不在這里展開但記住 MySQL 8.0 的默認認證插件是 caching_sha2_password老客戶端連不上會報Authentication plugin caching_sha2_password cannot be loaded需要客戶端升級或用ALTER USER root% IDENTIFIED WITH mysql_native_password BY password;兼容。用docker inspect mysql8可以查看容器的 IP 和掛載信息排查網(wǎng)絡和數(shù)據(jù)卷問題時這條命令很有用新手往往不知道容器有獨立的 IP總以為容器和宿主機共享網(wǎng)絡棧。5.2 Docker 里搭建 Redis 主從理解容器網(wǎng)絡的入門Redis 主從搭建是熱搜詞里另一個高頻需求。用 Docker 裝兩個 Redis 容器讓一個當主節(jié)點、一個當從節(jié)點套路和物理機差不多但關(guān)鍵區(qū)別在于容器之間的網(wǎng)絡通信。先創(chuàng)建 Docker 網(wǎng)絡這一步經(jīng)常被忽略docker network create redis-net為什么要手動創(chuàng)建網(wǎng)絡因為默認的 bridge 網(wǎng)絡里容器可以通過 IP 互訪但 IP 是動態(tài)的重啟可能就變了。自定義網(wǎng)絡的好處是提供了內(nèi)置 DNS 解析容器之間可以用容器名互相訪問比如從庫配置里寫replicaof redis-master 6379就可以了IP 變了也不影響。這是在 Docker 里玩多容器協(xié)作時最重要的基建認知。啟動主節(jié)點docker run -d --name redis-master --network redis-net -p 6379:6379 redis:7 redis-server --appendonly yes啟動從節(jié)點docker run -d --name redis-slave --network redis-net -p 6380:6379 redis:7 redis-server --replicaof redis-master 6379注意最后一段是覆蓋容器默認啟動命令的寫法。redis:7是鏡像后面redis-server --replicaof redis-master 6379是自定義啟動參數(shù)意思是讓這個 Redis 實例作為 6379 端口主節(jié)點的從庫。通過docker exec -it redis-slave redis-cli info replication可以看到role:slave和master_link_status:up。這一步跑通說明你已經(jīng)理解了 Docker 多容器通信的基本方式后面部署微服務、一般的前后端分離項目都用這個套路。5.3 Docker Compose把多容器配置固化下來手動docker run兩個 Redis 容器已經(jīng)能跑了但如果這個服務要復制到別的機器或者團隊里別人也要搭一套手敲命令顯然不優(yōu)雅。Docker Compose 的價值就是用 YAML 文件把多容器編排固化下來。先寫一個docker-compose.yml文件version: 3.8 services: redis-master: image: redis:7 container_name: redis-master command: redis-server --appendonly yes ports: - 6379:6379 networks: - redis-net redis-slave: image: redis:7 container_name: redis-slave command: redis-server --replicaof redis-master 6379 ports: - 6380:6379 depends_on: - redis-master networks: - redis-net networks: redis-net: driver: bridge然后執(zhí)行docker compose up -dCompose 會按照文件定義自動創(chuàng)建網(wǎng)絡、拉鏡像、啟動容器。注意depends_on只是控制啟動順序并不保證主節(jié)點已經(jīng)完全就緒所以在一些需要依賴就緒的場景下還要配合健康檢查healthcheck使用。這是從能用走向好用的關(guān)鍵一步。MySQL 也可以加進 Compose順便把前面的數(shù)據(jù)卷、端口映射、環(huán)境變量都寫在文件里。以后部署一整套環(huán)境只需docker compose up -d一條命令這就是 Docker 對開發(fā)運維體驗改變最大的地方。6. 日常使用高頻故障排查手冊實測記錄這部分全部來自實際使用中踩過的坑按出現(xiàn)頻率排序每一條都給出判斷思路和解決方法。6.1 權(quán)限錯誤permission denied while trying to connect to the Docker daemon socket這是提問率最高的報錯之一出現(xiàn)在 Linux 上執(zhí)行 docker 命令時。完整報錯通常是permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock意思是當前用戶沒有訪問 Docker 守護進程 socket 的權(quán)限。解決方案前面提過把用戶加進 docker 組sudo usermod -aG docker $USER執(zhí)行后必須注銷當前會話或者重啟系統(tǒng)組權(quán)限才會生效。有時候groups命令已經(jīng)顯示你在 docker 組里了但當前 shell 的權(quán)限緩存還沒更新需要重啟 shell 或重新登錄。另外有一種變體是docker: permission denied伴隨/var/run/docker.sock掛載卷的情況通常是容器里要訪問宿主機的 Docker socket但 socket 文件權(quán)限是 660 且屬主是 root:docker容器內(nèi)用戶無權(quán)限時的處理方式是要么用 root 用戶運行容器要么把 socket 文件的組權(quán)限放開——不過后者有安全風險一般不推薦。6.2 鏡像下載慢的根治思路docker鏡像下載慢幾乎是所有國內(nèi)用戶必經(jīng)的坎。核心思路是換鏡像加速源。Docker Engine 和 Docker Desktop 都要改daemon.jsonLinux 路徑是/etc/docker/daemon.jsonDocker Desktop 在 Settings - Docker Engine 里編輯 JSON。一個可行的配置示例{ registry-mirrors: [ https://docker.m.daocloud.io, https://dockerproxy.com, https://docker.mirrors.ustc.edu.cn ] }改完重啟 Docker。不同加速源的穩(wěn)定性波動很大如果一個鏡像源拉不動換另一個。注意國內(nèi)鏡像加速源并不能加速所有倉庫比如某些小眾倉庫可能不在加速列表里這時可以用代理或換源方案。另外拉取不存在的鏡像名時也會表現(xiàn)為下載慢或者一直轉(zhuǎn)圈用docker pull前先到 Docker Hub 上確認鏡像名拼寫正確。6.3 容器網(wǎng)絡不通的定位方法docker網(wǎng)絡不通涵蓋的情況很多但新手最常見的是三種宿主機訪問容器端口不通、容器訪問外網(wǎng)不通、容器之間互相不通。宿主機訪問容器端口不通時先用docker ps確認真實端口映射。有時候你自己敲了-p 8080:80但容器里面 Nginx 監(jiān)聽的是 8000這時候訪問當然不通。用docker port my-nginx查看當前映射關(guān)系一目了然。容器訪問外網(wǎng)不通時先在容器里執(zhí)行docker exec -it my-nginx ping 8.8.8.8如果 ping 不通但宿主機能上網(wǎng)多半是 Docker 默認 bridge 網(wǎng)絡的 iptables 規(guī)則被清了或者開了防火墻。檢查/etc/docker/daemon.json里的iptables: false是否被誤設以及sysctl net.ipv4.ip_forward是否為 1。有些云服務器廠商的鏡像默認把 ip_forward 關(guān)了導致容器無法上網(wǎng)這個坑比較隱蔽。容器之間互相不通時檢查它們是否在同一個網(wǎng)絡里。前面強調(diào)過自定義網(wǎng)絡有 DNS 解析如果兩個容器一個在默認 bridge 網(wǎng)、一個在自定義網(wǎng)絡用容器名是 ping 不通的。解決時把它們放到同一網(wǎng)絡docker network connect redis-net my-nginx6.4 服務啟動失敗failed to start docker application container engine這條報錯在前面 Docker Desktop 小節(jié)提過但在純 Docker Engine 環(huán)境下也常見。排查順序是sudo systemctl status docker sudo journalctl -u docker --no-pager | tail -50日志里如果出現(xiàn)failed to start daemon: error while opening volume store metadata多半是/var/lib/docker目錄權(quán)限損壞修復方式是sudo chown -R root:root /var/lib/docker sudo chmod -R 755 /var/lib/docker但注意這只在確認數(shù)據(jù)不重要時才建議操作。如果日志里出現(xiàn)overlay2 is not supported說明當前文件系統(tǒng)不支持 OverlayFS 存儲驅(qū)動可以改用 vfs 或 fuse-overlayfs但性能會受影響。反復遇到服務啟動失敗的話建議把daemon.json暫時移走用默認配置啟動確認是不是自己的配置導致的問題。這一步成本很低能排除掉大部分配置型故障。6.5 容器退出狀態(tài)的快速判斷docker ps -a看到 Exited(0) 和 Exited(1) 的意義完全不同。Exited(0) 是正常退出比如docker run --rm hello-world打印完內(nèi)容就退出這是正?,F(xiàn)象。Exited(1) 或非零狀態(tài)碼說明程序運行時出錯??焖俨榭赐顺鰰r的日志用docker logs 容器名查看即可。有一種常見情況是前臺進程跑完就退出比如啟動一個容器但命令是bash沒有任何交互進程容器立刻退出。這時候加上-it交互終端就能保持運行或者用-d跑一個自帶常駐進程的鏡像如nginx。個人實際經(jīng)驗里Docker 排查問題的大原則是先看日志、再看網(wǎng)絡、最后才考慮重啟和重裝。很多新手一遇到問題就docker rm -f再來一遍這樣不僅學不到東西還可能把數(shù)據(jù)卷里的數(shù)據(jù)一并刪掉。先理解報錯信息在說什么再動手這個習慣能幫你省非常多的無用功。最后再補充一個實用的小技巧如果你經(jīng)常在一臺機器上同時跑多個項目盡量不要讓所有容器都在默認 bridge 網(wǎng)絡上按照項目維度創(chuàng)建各自的網(wǎng)絡配合 Compose 文件管理這樣端口不沖突、容器名不沖突、網(wǎng)絡也清晰。等你真正熟悉了這套操作就會理解為什么很多人說Docker 用好了部署一個服務真的只需要一條命令。