作為許多開發(fā)和生產(chǎn)環(huán)境中基礎(chǔ)設(shè)施的重要組成部分,docker 的版本穩(wěn)定性直接影響著整個(gè)系統(tǒng)的可靠性。本文將詳細(xì)介紹如何有效地管理和固定 docker 的版本。
在開始之前,不得不提到 Docker 已經(jīng)誕生了十二年。作為容器化技術(shù)的先驅(qū),它已經(jīng)成為眾多開發(fā)者和企業(yè)的必備工具。然而,隨著 Docker 的不斷發(fā)展,頻繁的版本更新也帶來了不少問題。
許多開發(fā)者可能都曾遇到過這樣的困境:之前運(yùn)行良好的容器,在更新 Docker 版本后突然出現(xiàn)了各種奇怪的問題。這些問題可能是配置文件不兼容、命令參數(shù)變化,甚至影響到整個(gè)應(yīng)用的穩(wěn)定性。
更令人頭疼的是,當(dāng)試圖解決這些問題時(shí),網(wǎng)上搜索到的許多文章要么已經(jīng)過時(shí),要么就是簡(jiǎn)單地復(fù)制粘貼一些錯(cuò)誤的或已經(jīng)失效的命令。這不僅無法解決問題,還會(huì)浪費(fèi)大量的時(shí)間。(在使用這些命令時(shí),你是否考慮過它們的可靠性?)
基于這些原因,我決定撰寫這篇文章,詳細(xì)介紹如何在 ubuntu 環(huán)境中有效地管理和固定 Docker 版本,幫助你避免版本更新帶來的各種意外問題。
準(zhǔn)備工作:Docker 安裝如果你的系統(tǒng)中尚未安裝 Docker,可以參考我之前寫的《搭建 Ubuntu 24.04 基礎(chǔ)開發(fā)環(huán)境指南》,文章中詳細(xì)介紹了 Docker 的安裝和基礎(chǔ)配置步驟。
實(shí)戰(zhàn)過程首先,我們需要找出系統(tǒng)中已經(jīng)安裝的 Docker 相關(guān)包。
查找 Docker 依賴軟件包我們可以使用 dpkg-query 命令來查詢系統(tǒng)中已安裝的軟件包,并用 grep 篩選出 Docker 相關(guān)的內(nèi)容:
# dpkg-query -l | grep docker ii docker-buildx-plugin 0.20.0-1~ubuntu.24.04~noble arm64 Docker Buildx cli plugin. ii docker-ce 5:27.5.1-1~ubuntu.24.04~noble arm64 Docker: the open-source application container engine ii docker-ce-cli 5:27.5.1-1~ubuntu.24.04~noble arm64 Docker CLI: the open-source application container engine ii docker-ce-rootless-extras 5:27.5.1-1~ubuntu.24.04~noble arm64 Rootless support for Docker. ii docker-compose-plugin 2.32.4-1~ubuntu.24.04~noble arm64 Docker Compose (V2) plugin for the Docker CLI. ii python3-docker 5.0.3-1ubuntu1.1 all Python 3 wrapper to Access docker.io's control socket
為了避免手動(dòng)復(fù)制粘貼可能帶來的錯(cuò)誤,我們可以使用 awk 命令來提取包名。使用命令獲取軟件包名還有一個(gè)好處,即在 docker 軟件依賴發(fā)生變化后,相較于手動(dòng)“復(fù)制粘貼”,使用命令可以自適應(yīng)解決問題。
# dpkg-query -l | grep docker | awk '{print $2}' docker-buildx-plugin docker-ce docker-ce-cli docker-ce-rootless-extras docker-compose-plugin python3-docker
日志中的結(jié)果就是 Docker 的主要程序組件依賴。不過,這只是處理了那些名字中明顯包含 “docker” 關(guān)鍵詞的包。接下來,我們還需要處理一些可能被遺漏的依賴包。
深入了解 Docker 軟件包依賴關(guān)系在研究 Docker 的子依賴時(shí),我們可以使用 apt-cache depends 結(jié)合 xargs 來進(jìn)行分析。
首先,讓我們看看如何獲取相關(guān)軟件包的依賴情況:
# dpkg-query -l | grep docker | awk '{print $2}' | xargs -I {} apt-cache depends {} docker-buildx-plugin Replaces: docker-ce-cli Enhances: docker-ce-cli docker-ce Depends: containerd.io Depends: docker-ce-cli Depends: iptables Depends: libseccomp2 Depends: libc6 Depends: libsystemd0 Conflicts: <docker> Conflicts: <docker-engine> Conflicts: docker.io Recommends: apparmor Recommends: ca-certificates Recommends: docker-ce-rootless-extras Recommends: git Recommends: kmod Recommends: libltdl7 Recommends: pigz Recommends: procps Recommends: xz-utils |Suggests: cgroupfs-mount Suggests: cgroup-lite Replaces: <docker-engine> docker-ce-cli Depends: libc6 Conflicts: <docker> Conflicts: <docker-engine> Conflicts: docker.io Breaks: docker-ce Recommends: docker-buildx-plugin Recommends: docker-compose-plugin Replaces: docker-ce docker-ce-rootless-extras Depends: dbus-user-session Depends: libc6 Conflicts: rootlesskit Breaks: rootlesskit Recommends: slirp4netns Replaces: rootlesskit Enhances: docker-ce docker-compose-plugin Enhances: docker-ce-cli python3-docker Depends: python3-requests Depends: python3-websocket Depends: <any> python3 Depends: python3-packaging Depends: python3-urllib3 Breaks: python3-minimal </any> </docker-engine> </docker> </docker-engine> </docker-engine> </docker>
這個(gè)命令會(huì)為我們展示詳細(xì)的依賴信息,包括:
- 必需依賴(Depends)
- 推薦安裝(Recommends)
- 沖突包(Conflicts)
- 替換包(Replaces)
考慮到我們主要關(guān)注穩(wěn)定環(huán)境下的版本控制和簡(jiǎn)化維護(hù)工作,我們本身不會(huì)強(qiáng)制安裝古早的淘汰軟件包,也不會(huì)強(qiáng)制安裝沖突軟件包。所以,重點(diǎn)應(yīng)該放在 Depends 和 Recommends 這兩類依賴上。我們可以這樣繼續(xù)篩選:
# dpkg-query -l | grep docker | awk '{print $2}' | xargs -I {} apt-cache depends {} | grep -E "Depends|Recommends" Depends: containerd.io Depends: docker-ce-cli Depends: iptables Depends: libseccomp2 Depends: libc6 Depends: libsystemd0 Recommends: apparmor Recommends: ca-certificates Recommends: docker-ce-rootless-extras Recommends: git Recommends: kmod Recommends: libltdl7 Recommends: pigz Recommends: procps Recommends: xz-utils Depends: libc6 Recommends: docker-buildx-plugin Recommends: docker-compose-plugin Depends: dbus-user-session Depends: libc6 Recommends: slirp4netns Depends: python3-requests Depends: python3-websocket Depends: <any> Depends: python3-packaging Depends: python3-urllib3 </any>
我們從輸出結(jié)果中,能夠看到非常清晰的依賴關(guān)系,其中主要包括:
- 基礎(chǔ)組件:containerd.io、iptables、libseccomp2
- 系統(tǒng)庫(kù):libc6、libsystemd0
- 工具包:docker-ce-cli、docker-buildx-plugin
- 安全相關(guān):apparmor、ca-certificates
- 其他工具:git、kmod、pigz、procps
其中一個(gè)依賴支持“任意版本的 Python 軟件包”,所以在后續(xù)處理過程中,我們可以將這個(gè)依賴項(xiàng)去掉。
為了讓結(jié)果更清晰易讀,我們可以用 sed 來繼續(xù)優(yōu)化輸出格式,只保留包名:
dpkg-query -l | grep docker | awk '{print $2}' | xargs -I {} apt-cache depends {} | grep -E "Depends|Recommends" | grep -v ":any" | sed 's/^[[:space:]]*(Depends|Recommends): //' containerd.io docker-ce-cli iptables libseccomp2 libc6 libsystemd0 apparmor ca-certificates docker-ce-rootless-extras git kmod libltdl7 pigz procps xz-utils libc6 docker-buildx-plugin docker-compose-plugin dbus-user-session libc6 slirp4netns python3-requests python3-websocket python3-packaging python3-urllib3
這樣就得到了一個(gè)簡(jiǎn)潔的 Docker 核心依賴列表,對(duì)于我們理解當(dāng)前版本的 Docker 的組件構(gòu)成和進(jìn)行環(huán)境配置都很有幫助。
編寫軟件包獲取腳本程序有了前面的經(jīng)驗(yàn),我們可以寫一個(gè)更完整的腳本,來獲取所有軟件包的依賴列表。這對(duì)我們后續(xù)鎖定特定軟件包會(huì)很有幫助。
#!/bin/bash # 創(chuàng)建臨時(shí)文件存儲(chǔ)所有依賴 temp_file=$(mktemp) # 獲取所有 docker 相關(guān)包的依賴 dpkg-query -l | grep docker | awk '{print $2}' | while read pkg; do echo "=== Dependencies for $pkg ===" >> "$temp_file" apt-cache depends "$pkg" | grep -E "Depends:|Recommends:" | grep -v "> " >> "$temp_file" echo >> "$temp_file" done # 顯示所有依賴(帶包名標(biāo)題) cat "$temp_file" echo -e "n=== Unique dependencies (sorted) ===" # 提取唯一的依賴項(xiàng)并排序 grep -v "^===" "$temp_file" | grep -v "^$" | sort -u # 清理臨時(shí)文件 rm "$temp_file"
我們將這個(gè)腳本保存為 get_docker_dependencies.sh,并運(yùn)行它:
./get_docker_dependencies.sh
這樣,我們就能夠得到一個(gè)完整的 Docker 依賴列表,并且可以根據(jù)需要進(jìn)行版本鎖定。