事情起因
發(fā)現(xiàn)有一臺物理機只能連接同一個網(wǎng)段的公網(wǎng),不能訪問如百度匣距,dns服務器也ping不通,我就想裝個traceroute 看看是哪一步的原因,由于這臺機器不能聯(lián)網(wǎng),于是就打算從隔壁機器下載deb包价脾,到這個機器上安裝。于是:
# 獲取依賴笛匙,并下載
apt-rdepends traceroute | grep -v "^ " | xargs sudo apt-get download
# 打包
tar zcvf traceroute.tgz traceroute/
# 遠程復制
scp <>
# 解壓
tar zxvf traceroute.tgz
# 安裝
cd traceroute&&dpkg -i *.deb
一氣呵成侨把,問題來了,所有命令都用不了了妹孙,報錯/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)秋柄,隔壁機器跟這個機器不是同一個版本的操作系統(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
蠢正。好好好骇笔。只能怨我眼瞎。犯了這么低級的錯誤嚣崭。
更離譜的來了蜘拉,因為我是剛來這家公司,發(fā)現(xiàn)這個k8s集群的部分woker節(jié)點情況如下:
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
好巧不巧有鹿,我操作的就是這個 ubuntu 20.10旭旭。這個版本從發(fā)布到中止維護僅有9個月的時間。都是前人挖的坑啊葱跋。
此情此景持寄,我只能說 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
然而,并沒有什么用油宜。于此同時掂碱,我還手賤的打算復制一個ssh連接怜姿,好家伙,windterm
直接閃退疼燥。
那沒有辦法了沧卢,就只能去機房操作了。
首先了解一下這次操作到底都更新了哪些文件
這里使用docker的 layer 機制醉者,就能很明顯的看到那些文件發(fā)生了改變
# 運行一個ubuntu 20.10的容器
docker run -it --name ubunt-2010 -v /root:/data ubuntu:20.10 bash
# 安裝相關的包
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)
接下來另起一個窗口:
docker inspect ubuntu-2010 --format '{{.GraphDriver.Data.UpperDir}}'
# cd 到這個目錄
cd <上一步輸出結果>
# 查看哪些文件夾發(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
在啟動一個新的ubuntu 20.10的容器,對比發(fā)現(xiàn) /usr/lib/gcc/x86_64-linux-gnu
目錄是新增的撬即,新增一般影響不大立磁。主要變動就是/usr/lib/x86_64-linux-gnu
。
解決思路就是把/usr/lib/x86_64-linux-gnu
備份一下剥槐,重新復制一份過去息罗。
于是,在本地新建虛擬機才沧,裝上ubuntu 20.10的系統(tǒng)迈喉,模擬故障,使用ubuntu 20.10 desktop版本的live cd模式啟動温圆。把硬盤掛載到/mnt
目錄,嘗試恢復:
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ā)生了變動得运。查看這個文件:
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*
把這個文件也復制回去,因為原來是個軟連接锅移,這里直接簡單粗暴的把源文件復制過去了
cp /lib/x86_64-linux-gnu/ld-2.32.so /mnt/lib64/ld-linux-x86-64.so.2
chroot /mnt
根目錄轉化成功熔掺,實驗命令可以正常執(zhí)行。
于是去機房非剃,關機置逻、U盤啟動,修復文件备绽,搞定券坞。
在運行過程中又發(fā)現(xiàn),部分軟件缺少文件肺素,將/usr/lib/x86_64-linux-gnubak/
中的文件恨锚,復制但不替換回/usr/lib/x86_64-linux-gnu/
rsync -av --ignore-existing /usr/lib/x86_64-linux-gnubak/ /usr/lib/x86_64-linux-gnu/
當然,也可以在恢復/usr/lib/x86_64-linux-gnu/
時:
# 原來是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
這樣猴伶,直接覆蓋掉修改過的文件(沒試過,盲猜的)
總結
- 將
/usr/lib/x86_64-linux-gnu
替換回原操作系統(tǒng)內(nèi)容- 替換回
/lib64/ld-linux-x86-64.so.2
- 將后期增加的
/usr/lib/x86_64-linux-gnu
下的文件,增量復制回去- 執(zhí)行命令前他挎,一定要看一眼到底執(zhí)行了什么筝尾。不要閉著眼操作
- 服務器能跑,不影響業(yè)務使用雇盖,就不要管他忿等。