事情起因
發(fā)現(xiàn)有一臺(tái)物理機(jī)只能連接同一個(gè)網(wǎng)段的公網(wǎng),不能訪問如百度,dns服務(wù)器也ping不通,我就想裝個(gè)traceroute 看看是哪一步的原因,由于這臺(tái)機(jī)器不能聯(lián)網(wǎng),于是就打算從隔壁機(jī)器下載deb包,到這個(gè)機(jī)器上安裝。于是:
# 獲取依賴,并下載
apt-rdepends traceroute | grep -v "^ " | xargs sudo apt-get download
# 打包
tar zcvf traceroute.tgz traceroute/
# 遠(yuǎn)程復(fù)制
scp <>
# 解壓
tar zxvf traceroute.tgz
# 安裝
cd traceroute&&dpkg -i *.deb
一氣呵成,問題來了,所有命令都用不了了,報(bào)錯(cuò)/lib/x86_64-linux-gnu/libc.so.6: version 'GLIBC_2.30' not found (required by /lib/x86_64-linux-gnu/libselinux.so.1)
后來發(fā)現(xiàn),隔壁機(jī)器跟這個(gè)機(jī)器不是同一個(gè)版本的操作系統(tǒng),而且這些安裝包里包含:gcc-6-base_6.0.1-0ubuntu1_amd64.deb libc6_2.23-0ubuntu11.3_amd64.deb libgcc1_1%3a6.0.1-0ubuntu1_amd64.deb traceroute_1%3a2.0.21-1_amd64.deb。好好好。只能怨我眼瞎。犯了這么低級(jí)的錯(cuò)誤。
更離譜的來了,因?yàn)槲沂莿倎磉@家公司,發(fā)現(xiàn)這個(gè)k8s集群的部分woker節(jié)點(diǎn)情況如下:
OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
Ubuntu 18.04.1 LTS 4.15.0-147-generic docker://19.3.13
Ubuntu 16.04.3 LTS 4.4.0-210-generic docker://19.3.13
Ubuntu 16.04.2 LTS 4.4.0-210-generic docker://19.3.13
Ubuntu 16.04.3 LTS 4.4.0-210-generic docker://17.9.0
Ubuntu 16.04.3 LTS 4.4.0-210-generic docker://19.3.13
Ubuntu 16.04.2 LTS 4.4.0-210-generic docker://18.6.0
Ubuntu 16.04.2 LTS 4.4.0-62-generic docker://19.3.13
Ubuntu 16.04.2 LTS 4.4.0-62-generic docker://18.6.0
Ubuntu 16.04.3 LTS 4.4.0-91-generic docker://19.3.13
Ubuntu 18.04.4 LTS 4.15.0-192-generic docker://19.3.11
Ubuntu 18.04.4 LTS 4.15.0-156-generic docker://19.3.12
Ubuntu 20.04.5 LTS 5.4.0-125-generic containerd://1.6.12
Ubuntu 20.10 5.8.0-63-generic docker://20.10.6
Ubuntu 20.04.5 LTS 5.4.0-125-generic docker://20.10.18
好巧不巧,我操作的就是這個(gè) ubuntu 20.10。這個(gè)版本從發(fā)布到中止維護(hù)僅有9個(gè)月的時(shí)間。都是前人挖的坑啊。
此情此景,我只能說 k8s 牛逼,不挑食。
言歸正傳。現(xiàn)在什么命令都用不了。
自救過程
現(xiàn)在已經(jīng)打開的ssh是沒有斷開的,但是新的ssh已經(jīng)連接不了了。根據(jù)網(wǎng)上的方法:
上傳20.10用的glibc版本的 libc-2.32.so
LD_PRELOAD=/home/sysuser/libc-2.32.so ls
然而,并沒有什么用。于此同時(shí),我還手賤的打算復(fù)制一個(gè)ssh連接,好家伙,windterm直接閃退。
那沒有辦法了,就只能去機(jī)房操作了。
首先了解一下這次操作到底都更新了哪些文件
這里使用docker的 layer 機(jī)制,就能很明顯的看到那些文件發(fā)生了改變
# 運(yùn)行一個(gè)ubuntu 20.10的容器
docker run -it --name ubunt-2010 -v /root:/data ubuntu:20.10 bash
# 安裝相關(guān)的包
cd /data/traceroute
dpkg -i *.deb
# 發(fā)現(xiàn)問題與線上問題一致
root@ubuntu-2010:/data/traceroute# ls
ls: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.28' not found (required by ls)
ls: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.30' not found (required by /lib/x86_64-linux-gnu/libselinux.so.1)
root@ubuntu-2010:/data/traceroute# cp
cp: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.25' not found (required by cp)
cp: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.28' not found (required by cp)
cp: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.30' not found (required by /lib/x86_64-linux-gnu/libselinux.so.1)
接下來另起一個(gè)窗口:
docker inspect ubuntu-2010 --format '{{.GraphDriver.Data.UpperDir}}'
# cd 到這個(gè)目錄
cd <上一步輸出結(jié)果>
# 查看哪些文件夾發(fā)生了改變
tree
# 這里發(fā)現(xiàn)很多文件都改變了,于是只看看哪些目錄
tree -d
.
├── data
├── etc
│ └── ld.so.conf.d
├── usr
│ ├── lib
│ │ ├── gcc
│ │ │ └── x86_64-linux-gnu
│ │ │ ├── 6
│ │ │ └── 6.0.0 -> 6
│ │ └── x86_64-linux-gnu
│ │ ├── audit
│ │ └── gconv
│ ├── lib64
│ └── share
│ ├── doc
│ │ ├── gcc-6-base
│ │ └── libc6
│ └── lintian
│ └── overrides
└── var
├── cache
│ └── debconf
├── lib
│ └── dpkg
│ ├── info
│ ├── triggers
│ └── updates
└── log
在啟動(dòng)一個(gè)新的ubuntu 20.10的容器,對(duì)比發(fā)現(xiàn) /usr/lib/gcc/x86_64-linux-gnu目錄是新增的,新增一般影響不大。主要變動(dòng)就是/usr/lib/x86_64-linux-gnu。
解決思路就是把/usr/lib/x86_64-linux-gnu備份一下,重新復(fù)制一份過去。
于是,在本地新建虛擬機(jī),裝上ubuntu 20.10的系統(tǒng),模擬故障,使用ubuntu 20.10 desktop版本的live cd模式啟動(dòng)。把硬盤掛載到/mnt目錄,嘗試恢復(fù):
mv /mnt/usr/lib/x86_64-linux-gnu /mnt/usr/lib/x86_64-linux-gnubak
cp -rp /usr/lib/x86_64-linux-gnu /mnt/usr/lib
chroot /mnt
發(fā)現(xiàn)chroot不過去,懷疑是仍然有問題。于是,發(fā)現(xiàn)lib64下的ld-linux-x86-64.so.2文件也發(fā)生了變動(dòng)。查看這個(gè)文件:
ll /lib64/ld-linux-x86-64.so.2
lrwxrwxrwx 1 root root 32 Sep 15 2020 /lib64/ld-linux-x86-64.so.2 -> /lib/x86_64-linux-gnu/ld-2.32.so*
把這個(gè)文件也復(fù)制回去,因?yàn)樵瓉硎莻€(gè)軟連接,這里直接簡(jiǎn)單粗暴的把源文件復(fù)制過去了
cp /lib/x86_64-linux-gnu/ld-2.32.so /mnt/lib64/ld-linux-x86-64.so.2
chroot /mnt
根目錄轉(zhuǎn)化成功,實(shí)驗(yàn)命令可以正常執(zhí)行。
于是去機(jī)房,關(guān)機(jī)、U盤啟動(dòng),修復(fù)文件,搞定。
在運(yùn)行過程中又發(fā)現(xiàn),部分軟件缺少文件,將/usr/lib/x86_64-linux-gnubak/中的文件,復(fù)制但不替換回/usr/lib/x86_64-linux-gnu/
rsync -av --ignore-existing /usr/lib/x86_64-linux-gnubak/ /usr/lib/x86_64-linux-gnu/
當(dāng)然,也可以在恢復(fù)/usr/lib/x86_64-linux-gnu/時(shí):
# 原來是mv,改為cp
cp -rp /mnt/usr/lib/x86_64-linux-gnu /mnt/usr/lib/x86_64-linux-gnubak
cp -rp /usr/lib/x86_64-linux-gnu/* /mnt/usr/lib/x86_64-linux-gnu
這樣,直接覆蓋掉修改過的文件(沒試過,盲猜的)
總結(jié)
- 將
/usr/lib/x86_64-linux-gnu替換回原操作系統(tǒng)內(nèi)容- 替換回
/lib64/ld-linux-x86-64.so.2- 將后期增加的
/usr/lib/x86_64-linux-gnu下的文件,增量復(fù)制回去- 執(zhí)行命令前,一定要看一眼到底執(zhí)行了什么。不要閉著眼操作
- 服務(wù)器能跑,不影響業(yè)務(wù)使用,就不要管他。