
簡(jiǎn)介這份文檔面向在國(guó)產(chǎn)化服務(wù)器環(huán)境中部署容器平臺(tái)的運(yùn)維工程師與信創(chuàng)適配人員聚焦銀河麒麟 v10 SP1 Server 上 Docker 的落地安裝問(wèn)題。由于官方源缺少 docker server 軟件包文檔給出阿里云 docker-ce 源與麒麟官方依賴源的配置方法并說(shuō)明為何只能安裝 18.09.7 版本、無(wú)法直接升級(jí)到最新版。資源為 1 個(gè) docx 文件壓縮包約 17KB體量輕便適合離線查閱或隨環(huán)境交付存檔。內(nèi)容按「配置 yum 源—安裝 docker-ce-cli 與 docker-ce—啟動(dòng)服務(wù)—查看版本」的順序組織附有完整 repo 文件內(nèi)容、可復(fù)制的命令與真實(shí)報(bào)錯(cuò)信息讀者可據(jù)此快速?gòu)?fù)現(xiàn)安裝流程并借助其中的 container-selinux 依賴報(bào)錯(cuò)分析掌握排查思路。該文檔已有 7220 人學(xué)習(xí)下載對(duì)需要在麒麟系統(tǒng)上搭建容器運(yùn)行環(huán)境的初、中級(jí)用戶具有直接參考價(jià)值。1. 從一臺(tái) aarch64 服務(wù)器說(shuō)起麒麟上裝 Docker 為什么先降版本第一次在銀河麒麟 v10 SP1 Server 上敲yum install docker-ce多數(shù)人以為十分鐘能收工結(jié)果終端甩回一行nothing provides container-selinux 2:2.74。機(jī)器是 aarch64 架構(gòu)系統(tǒng)自帶源里壓根沒(méi)有 docker server 包第三方源里最新版的依賴又跟麒麟的 selinux 策略包對(duì)不上裝到一半就卡死。這類機(jī)器在國(guó)產(chǎn)化改造的場(chǎng)景里太常見(jiàn)了docker 銀河麒麟這個(gè)組合踩的坑九成都集中在「版本對(duì)不上」和「源沒(méi)配對(duì)」兩件事上。下面按我實(shí)際裝過(guò)的那套流程走一遍先核對(duì)架構(gòu)和版本再配雙源然后按 cli → engine 的順序釘死 18.09.7最后給一套能自查的驗(yàn)收命令。手上正卡在依賴報(bào)錯(cuò)、或者裝完 docker 起不來(lái)的開(kāi)發(fā)者可以照著復(fù)現(xiàn)。2. 裝前把底子摸清麒麟 v10 SP1 的架構(gòu)、內(nèi)核與版本取舍動(dòng)手改源之前先花三分鐘做體檢。這一步偷懶的人最多后面翻車的也最多——源地址里的$basearch填錯(cuò)、把 x86_64 的包往 aarch64 機(jī)器上懟、內(nèi)核太老撐不起 overlay2都是在這個(gè)環(huán)節(jié)埋下的雷。2.1 三條命令確認(rèn)系統(tǒng)版本、內(nèi)核與 CPU 架構(gòu)# 麒麟自己的發(fā)行版標(biāo)識(shí)確認(rèn)是不是 v10 SP1 cat /etc/kylin-release # 通用發(fā)行版信息重點(diǎn)看 ID 和 VERSION_ID cat /etc/os-release # CPU 架構(gòu)aarch64 還是 x86_64直接決定源地址里 $basearch 展開(kāi)成什么 uname -m # 內(nèi)核版本4.19 及以上對(duì) overlay2、cgroup v2 的支持才比較穩(wěn) uname -r/etc/kylin-release是麒麟特有的文件CentOS 上沒(méi)有用它確認(rèn)小版本號(hào)最直接SP1 和 SP2 的源路徑不一樣抄錯(cuò)一個(gè)字整段源就廢。/etc/os-release里的ID字段一般會(huì)寫(xiě)成kylin有的鏡像版本寫(xiě)成centos這會(huì)影響后面 yum 變量展開(kāi)的行為裝之前心里要有數(shù)。uname -m是關(guān)鍵中的關(guān)鍵。飛騰、鯤鵬這類機(jī)器輸出aarch64海光、兆芯輸出x86_64。同一個(gè) Docker CE 源里兩個(gè)架構(gòu)的包是分目錄放的$basearch寫(xiě)對(duì)了 yum 才會(huì)去對(duì)應(yīng)目錄取包。我見(jiàn)過(guò)有人把 x86_64 機(jī)器的 repo 文件整體拷到 aarch64 機(jī)器上$basearch雖然會(huì)展開(kāi)但如果寫(xiě)成了硬編碼的x86_64yum 就會(huì)報(bào)「沒(méi)有可用軟件包」而且報(bào)錯(cuò)信息完全不提架構(gòu)的事特別迷惑。內(nèi)核版本決定存儲(chǔ)驅(qū)動(dòng)。麒麟 v10 SP1 常見(jiàn)內(nèi)核在 4.19 一帶overlay2 能用如果碰上更老的 4.4 內(nèi)核就得退回devicemapper性能和穩(wěn)定性都差一截。先看清楚省得裝完再折騰。檢查項(xiàng)命令期望值不匹配的后果系統(tǒng)版本cat /etc/kylin-releaseKylin Linux Advanced Server V10 (SP1)源路徑寫(xiě)錯(cuò)元數(shù)據(jù)拉不下來(lái)CPU 架構(gòu)uname -maarch64 / x86_64拉到錯(cuò)誤架構(gòu)的包安裝直接失敗內(nèi)核版本uname -r4.19 及以上overlay2 不可用需換存儲(chǔ)驅(qū)動(dòng)磁盤(pán)空間df -h /var剩余 20G 以上鏡像一多就寫(xiě)滿docker 服務(wù)假死2.2 版本選擇18.09.7-3.el7 與 20.10 的取舍Docker CE 在 EL 系倉(cāng)庫(kù)里同時(shí)維護(hù) el7 和 el8 兩個(gè)包線aarch64 的構(gòu)建產(chǎn)物主要掛在centos/7/aarch64/stable下面。麒麟 v10 SP1 的 glibc 和 systemd 版本其實(shí)更接近 EL8 時(shí)代但 el7 的 docker 包依賴少、自帶組件多反而更容易在這套系統(tǒng)上落地。真正卡住的是新版。20.10 系列的 rpm 包在 spec 里硬性聲明了container-selinux 2:2.74而麒麟 v10 SP1 自帶源里的 container-selinux 版本低于這個(gè)門(mén)檻第三方源又不提供 aarch64 的 container-selinux于是依賴鏈在第一步就斷了。yum 給出的建議是加--skip-broken或--nobest這兩個(gè)參數(shù)看著像救命稻草實(shí)際上--skip-broken會(huì)把 docker-ce 本身也跳過(guò)--nobest則會(huì)降級(jí)去挑一個(gè)更老的候選包結(jié)果往往裝上一個(gè)版本號(hào)更亂的殘件。版本包名關(guān)鍵依賴在麒麟 v10 SP1 aarch64 的實(shí)際情況18.09.7docker-ce-18.09.7-3.el7依賴鏈短運(yùn)行時(shí)組件內(nèi)置能裝、能起、能跑容器20.10.xdocker-ce-3:20.10.17-3.el7container-selinux 2:2.74源里找不到滿足條件的包解析失敗所以這份環(huán)境里我固定用18.09.7-3.el7。它不算新但 Docker 的 API 版本兼容性一向做得好日常的鏡像構(gòu)建、容器編排、私有倉(cāng)庫(kù)對(duì)接都不受影響。真要上新版得先自己編譯 container-selinux 或者從別的源里找 aarch64 的包手動(dòng)裝那是另一個(gè)工作量級(jí)的事不適合在業(yè)務(wù)機(jī)器上折騰。2.3 裝前清場(chǎng)卸掉殘留 docker 與沖突包很多麒麟機(jī)器出廠自帶 podman 或者裝過(guò)舊版 docker直接覆蓋裝會(huì)出現(xiàn)二進(jìn)制打架、/etc/docker目錄殘留配置覆蓋新配置的問(wèn)題。裝之前先清一遍。# 卸掉歷史遺留的 docker 相關(guān)包不存在也不會(huì)報(bào)錯(cuò) yum remove -y docker docker-client docker-client-latest docker-common \ docker-latest docker-latest-logrotate docker-logrotate docker-engine # 看看有沒(méi)有 podman / buildah / containerd / runc 占著底層依賴 rpm -qa | grep -E podman|buildah|containerd|runc # 殘留的運(yùn)行時(shí)目錄確認(rèn)沒(méi)在用再刪 ls -ld /var/lib/docker /etc/docker /run/docker.sock 2/dev/null第一條命令里的包名是從 EL 系歷史沿革下來(lái)的麒麟上大部分不存在yum remove對(duì)不存在的包會(huì)靜默跳過(guò)不會(huì)有副作用。第二條命令是重點(diǎn)podman 和 docker 都依賴 containerd、runc 這些底層組件但版本要求不一樣如果系統(tǒng)里已經(jīng)裝了 podman 自帶的一套 runcdocker 裝上去可能跑的是不兼容的 runc 版本表現(xiàn)是容器起來(lái)了但秒退日志里報(bào)OCI runtime create failed。這種情況要么卸 podman要么用yum install時(shí)觀察 runc 是否被升級(jí)。/var/lib/docker目錄如果存在且里面還有舊數(shù)據(jù)新裝的 docker 會(huì)直接接管鏡像層格式不兼容時(shí)會(huì)出現(xiàn)「鏡像列表里有但起不來(lái)」的怪現(xiàn)象。確認(rèn)沒(méi)數(shù)據(jù)就rm -rf有數(shù)據(jù)先備份。這一步做完環(huán)境才算干凈。3. 配置 yum 源docker-ce 源加麒麟官方源的組合打法麒麟官方源里查不到 docker server 的包這是前提事實(shí)所以必須引第三方源。但只加第三方源又不夠——docker 運(yùn)行還需要libcgroup、iptables、container-selinux這類系統(tǒng)級(jí)依賴它們得從麒麟自己的源里來(lái)。兩個(gè)源各管一段缺一個(gè)都裝不完整。3.1 寫(xiě) docker-ce.repo$basearch與 gpgcheck 兩個(gè)關(guān)鍵參數(shù)先備份現(xiàn)有源出事能整段回滾這是血淚經(jīng)驗(yàn)。# 備份現(xiàn)有 repo 文件到 /root 下出問(wèn)題直接拷回來(lái) mkdir -p /root/repo-backup cp -a /etc/yum.repos.d/*.repo /root/repo-backup/ # 新建 docker-ce 源文件 vi /etc/yum.repos.d/docker-ce.repo文件內(nèi)容如下[docker-ce-stable] nameDocker CE Stable - 7 baseurlhttps://鏡像站域名/docker-ce/linux/centos/7/$basearch/stable enabled1 gpgcheck1 gpgkeyhttps://鏡像站域名/docker-ce/linux/centos/gpgbaseurl里的鏡像站域名換成你環(huán)境里能訪問(wèn)的 Docker CE 鏡像站域名內(nèi)網(wǎng)有同步源就填內(nèi)網(wǎng)地址比走公網(wǎng)穩(wěn)。路徑里的centos/7不是指操作系統(tǒng)必須是 CentOS 7而是 Docker 官方對(duì) EL7 包線的目錄約定aarch64 的構(gòu)建產(chǎn)物就在centos/7/aarch64/stable下面。$basearch是 yum 的內(nèi)置變量在 aarch64 機(jī)器上自動(dòng)展開(kāi)成aarch64在 x86_64 上展開(kāi)成x86_64所以這一行在兩個(gè)架構(gòu)上都能用不要手寫(xiě)成固定值。gpgcheck1配合gpgkey做包簽名校驗(yàn)安全上應(yīng)該開(kāi)。但如果內(nèi)網(wǎng)鏡像站是自建的、沒(méi)有同步 gpg 文件校驗(yàn)會(huì)失敗并報(bào)GPG key retrieval failed這時(shí)候要么把 gpgkey 指向內(nèi)網(wǎng)可達(dá)的地址要么臨時(shí)設(shè)gpgcheck0——后者是妥協(xié)裝完記得改回來(lái)。enabled1表示默認(rèn)啟用。如果同一個(gè) repo 文件里想禁用某個(gè)倉(cāng)庫(kù)單獨(dú)寫(xiě)enabled0即可不用刪文件。3.2 補(bǔ)一份麒麟官方源依賴包從這里來(lái)麒麟的源文件通常已經(jīng)在/etc/yum.repos.d/下了文件名類似kylin_aarch64.repo。先看現(xiàn)有的# 列出所有 repo 文件 ls -l /etc/yum.repos.d/ # 看現(xiàn)有源里都配了哪些 baseurl抄一個(gè)能用的 grep -rh baseurl /etc/yum.repos.d/*.repo如果現(xiàn)有的源被禁用了或者地址失效需要補(bǔ)一份。內(nèi)容參照這個(gè)結(jié)構(gòu)[ks10-os-media] name Kylin Linux Advanced Server 10 - Os baseurl http://麒麟官方源域名/yum/v10/sp1-openstack-q/aarch64/os/ gpgcheck 0 enabled 1baseurl里的路徑要跟你的系統(tǒng)版本嚴(yán)格對(duì)應(yīng)v10 和 v10 SP1 的目錄名不同sp1 后面還帶-openstack-q這類倉(cāng)庫(kù)標(biāo)識(shí)抄錯(cuò)就 404。最穩(wěn)的辦法是從機(jī)器上已有的源文件里復(fù)制一行過(guò)來(lái)改不要憑記憶手敲。gpgcheck 0在這里是常見(jiàn)做法。麒麟官方源的 gpg key 分發(fā)不一定完整開(kāi)了校驗(yàn)經(jīng)常拉不下來(lái)元數(shù)據(jù)導(dǎo)致整個(gè)源不可用。這個(gè)源只用來(lái)裝系統(tǒng)依賴包風(fēng)險(xiǎn)可控但對(duì)安全要求高的環(huán)境還是應(yīng)該把 key 導(dǎo)進(jìn)去再開(kāi)校驗(yàn)。3.3 刷新緩存并確認(rèn)兩個(gè)源都生效源文件寫(xiě)完不等于生效yum 有元數(shù)據(jù)緩存不清就是舊的。# 清掉所有緩存包括元數(shù)據(jù)和包 yum clean all # 重建緩存這一步會(huì)去兩個(gè)源拉元數(shù)據(jù)耗時(shí)看網(wǎng)絡(luò) yum makecache # 列出所有啟用的倉(cāng)庫(kù)確認(rèn) docker-ce-stable 和麒麟源都在 yum repolist # 看 docker-ce 有哪些可用版本重點(diǎn)確認(rèn) 18.09.7-3.el7 在列表里 yum --showduplicates list docker-ceyum repolist的輸出里每個(gè)倉(cāng)庫(kù)后面會(huì)跟一個(gè)包數(shù)量如果某個(gè)源顯示0或者狀態(tài)是repodata is over 2 weeks old說(shuō)明元數(shù)據(jù)沒(méi)拉到先解決源連通性再往下走。--showduplicates list會(huì)把同一個(gè)包的所有可用版本列出來(lái)aarch64 的 18.09.7 應(yīng)該出現(xiàn)在 docker-ce-stable 那一列沒(méi)出現(xiàn)就是$basearch或者路徑寫(xiě)錯(cuò)了。麒麟 v10 上yum其實(shí)是dnf的軟鏈接兩條命令等價(jià)但dnf的報(bào)錯(cuò)信息更詳細(xì)排查依賴問(wèn)題時(shí)用dnf往往能多看到一層原因。4. 用 yum 裝 docker-ce 18.09.7先 cli 再 engine 的順序不能反源配好之后安裝本身只有兩條命令但順序和版本號(hào)的寫(xiě)法有講究。docker-ce這個(gè)包依賴docker-ce-cli的精確版本一次性裝會(huì)讓 yum 自己去解析依賴解析結(jié)果不一定是你要的那個(gè)版本。4.1 先裝 docker-ce-cli把版本號(hào)釘死# 顯式指定完整版本號(hào)連 release 號(hào)一起寫(xiě) yum install -y docker-ce-cli-18.09.7-3.el7版本號(hào)必須寫(xiě)全18.09.7-3.el7只寫(xiě)18.09.7會(huì)讓 yum 去匹配所有 release可能挑到el7之外的構(gòu)建。-y是免交互確認(rèn)腳本化部署時(shí)必帶。為什么先裝 clidocker-ce的 rpm 里聲明了Requires: docker-ce-cli 18.09.7-3.el7這樣的精確依賴。如果直接yum install docker-ce-18.09.7-3.el7yum 會(huì)順帶解析出 cli 的依賴?yán)碚撋弦材苎b上。但實(shí)際情況是倉(cāng)庫(kù)里同時(shí)存在 20.10 的 cliyum 的依賴解析器在遇到多版本候選時(shí)可能挑最新的那個(gè)裝完就變成 cli 是 20.10、engine 是 18.09.7docker version里 Client 和 Server 版本對(duì)不上某些 API 調(diào)用直接報(bào)client version too new。先把 cli 釘死engine 安裝時(shí)的依賴解析就只剩一層沖突概率大幅下降。這是我在幾臺(tái)機(jī)器上反復(fù)驗(yàn)證過(guò)的順序不按這個(gè)來(lái)也能成但失敗的次數(shù)明顯更多。4.2 再裝 docker-ceengine 與 cli 版本對(duì)齊# 同樣寫(xiě)全版本號(hào) yum install -y docker-ce-18.09.7-3.el7裝完立刻核對(duì) rpm 層面的一致性# 兩個(gè)包的版本號(hào)應(yīng)該完全一致 rpm -qa | grep docker-ce正常輸出是兩行docker-ce-18.09.7-3.el7.aarch64和docker-ce-cli-18.09.7-3.el7.aarch64架構(gòu)后綴也必須是 aarch64。如果看到x86_64或者只有一行說(shuō)明依賴解析出了問(wèn)題yum remove重來(lái)。有個(gè)參數(shù)值得提一句--setoptobsoletes0。某些第三方源里會(huì)把 docker-ce 標(biāo)記為廢棄某個(gè)舊包加上obsoletes0能阻止 yum 順帶刪掉你不想刪的東西。一般用不上但在源比較雜的環(huán)境里是道保險(xiǎn)。4.3 啟動(dòng)、開(kāi)機(jī)自啟與版本驗(yàn)證# 啟動(dòng)服務(wù) systemctl start docker # 設(shè)開(kāi)機(jī)自啟服務(wù)器重啟后容器要能自己回來(lái) systemctl enable docker # 看服務(wù)狀態(tài)--no-pager 避免輸出被分頁(yè)截?cái)?systemctl status docker --no-pager # 只看客戶端版本 docker --version # 客戶端和服務(wù)端版本都看這個(gè)才是完整信息 docker versiondocker --version只打印一行Docker version 18.09.7, build 2d0083d那是客戶端版本服務(wù)端起沒(méi)起來(lái)它完全不管。很多人執(zhí)行完這條看到版本號(hào)就以為裝好了實(shí)際 dockerd 可能根本沒(méi)跑。docker version會(huì)分成 Client 和 Server 兩段輸出Server 段能打出來(lái)才說(shuō)明守護(hù)進(jìn)程活著。這是驗(yàn)收環(huán)節(jié)最容易糊弄過(guò)去的一步。systemctl status的輸出里如果看到Active: active (running)就正常如果是failed往下翻幾行會(huì)有具體的錯(cuò)誤原因配合journalctl -u docker -n 50 --no-pager能看到更詳細(xì)的啟動(dòng)日志。4.4 配 daemon.jsondata-root、日志與 cgroup driver裝完能跑只是及格線配置文件不改跑一陣子會(huì)出問(wèn)題。/etc/docker/daemon.json是守護(hù)進(jìn)程的主配置改完要systemctl daemon-reload systemctl restart docker。{ data-root: /data/docker, log-driver: json-file, log-opts: { max-size: 100m, max-file: 3 }, exec-opts: [native.cgroupdriversystemd], storage-driver: overlay2 }># 有網(wǎng)的機(jī)器上導(dǎo)出busybox 鏡像只有幾 MB docker save -o busybox.tar busybox:latest # 拷到目標(biāo)機(jī)器后導(dǎo)入 docker load -i busybox.tar # 用導(dǎo)入的鏡像做冒煙測(cè)試能看到輸出就說(shuō)明運(yùn)行時(shí)鏈路完整 docker run --rm busybox:latest echo docker ok--rm讓容器退出后自動(dòng)清理不留垃圾。這條命令打出來(lái)docker ok說(shuō)明鏡像加載、容器創(chuàng)建、runc 調(diào)用、網(wǎng)絡(luò)命名空間初始化整條鏈路都是通的比單純看版本號(hào)有說(shuō)服力得多。如果這一步報(bào)網(wǎng)絡(luò)相關(guān)的錯(cuò)再加--network none試一次能跑就說(shuō)明是網(wǎng)絡(luò)配置的問(wèn)題不是 docker 本身。docker info里還有個(gè)容易被忽略的字段是Cgroup Driver配了 systemd 的話這里應(yīng)該顯示systemd顯示cgroupfs說(shuō)明exec-opts沒(méi)生效。另外docker network ls應(yīng)該能看到bridge、host、none三個(gè)默認(rèn)網(wǎng)絡(luò)少一個(gè)就說(shuō)明 dockerd 初始化時(shí)出了問(wèn)題去journalctl -u docker里翻。從那以后我每次裝完麒麟的 docker都強(qiáng)制走一遍docker version的雙端對(duì)齊檢查再跑一條離線鏡像的冒煙命令兩步都過(guò)了才往生產(chǎn)環(huán)境推。這套流程不復(fù)雜但能擋掉八成「裝完了但跑不起來(lái)」的返工。希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取