最近接手了一台Ubuntu 18.04的服务器,运行新软件时突然报错/lib/x86_64-linux-gnu/libc.so.6: version 'GLIBC_2.28' not found。这台服务器因为安全原因完全断网,没法直接apt-get安装依赖,只能手动离线升级GLIBC。这种场景在企业内网环境特别常见,今天就分享一下我的完整解决过程。
GLIBC是GNU C Library的缩写,它是Linux系统最核心的库之一。Ubuntu 18.04默认安装的是GLIBC 2.27,而很多新开发的软件需要GLIBC 2.28或更高版本。在离线环境下升级GLIBC最大的挑战在于依赖链复杂,需要手动准备gcc、gmp、mpfr、mpc等十多个依赖包,任何一个环节出错都会导致编译失败。
先确认下当前系统的GLIBC版本:
bash复制ldd --version
如果输出显示是2.27,而你的软件需要2.28,那就需要继续往下看了。再检查系统支持的GLIBC版本:
bash复制strings /lib/x86_64-linux-gnu/libc.so.6 | grep GLIBC_
这个命令会列出所有已安装的GLIBC版本,如果看不到2.28,那就确认需要升级了。
因为是离线环境,所有软件包都需要提前下载好。我推荐使用清华大学的开源镜像站,速度比较稳定。需要下载的包包括:
这里有个坑要注意:mpfr的版本不能太低,我之前用mpfr-2.4.2就和glibc-2.28不兼容,建议直接用最新版。所有包下载完成后,用U盘或者内网传输工具上传到目标服务器。
建议新建一个专门的目录来存放这些源码包:
bash复制mkdir ~/glibc_upgrade && cd ~/glibc_upgrade
把下载的tar包都放到这个目录下,方便后续管理。
在编译GLIBC之前,需要先安装一些基础工具。这些工具虽然系统可能已经安装,但版本可能不符合要求。我们手动编译安装可以确保版本兼容性。
先安装gawk:
bash复制tar -xJf gawk-5.3.0.tar.xz
cd gawk-5.3.0/
./configure
make
sudo make install
同样的方法安装bison、m4和texinfo。每个工具安装完后,可以验证下版本:
bash复制bison --version
m4 --version
确保这些工具都安装成功后再继续下一步。
GLIBC 2.28需要较新版本的GCC来编译。Ubuntu 18.04自带的GCC 7.5可能会出现问题,我们需要升级到GCC 8.1。
先检查当前GCC版本:
bash复制gcc --version
如果显示是7.x版本,就需要先安装GCC 8.1。GCC的编译需要gmp、mpfr和mpc三个数学库的支持,必须按顺序先安装这三个库。
安装GMP:
bash复制tar -zxvf gmp-6.3.0.tar.gz
cd gmp-6.3.0
./configure
make
sudo make install
安装MPFR:
bash复制tar -zxvf mpfr-4.2.1.tar.gz
cd mpfr-4.2.1
./configure
make
sudo make install
安装MPC:
bash复制tar -zxvf mpc-1.0.2.tar.gz
cd mpc-1.0.2
./configure --with-gmp-include=/usr/local/include \
--with-gmp-lib=/usr/local/lib \
--with-mpfr-include=/usr/local/include \
--with-mpfr-lib=/usr/local/lib
make
sudo make install
这三个库安装完成后,就可以安装GCC了:
bash复制tar -zxvf gcc-8.1.0.tar.gz
cd gcc-8.1.0
mkdir build && cd build
../configure --prefix=/usr --enable-languages=c,c++ --disable-multilib
make -j$(nproc)
sudo make install
这个过程会比较长,建议用-j参数并行编译加快速度。安装完成后再次检查GCC版本,确认已经是8.1。
现在可以开始安装GLIBC 2.28了。先解压源码包:
bash复制tar -zxvf glibc-2.28.tar.gz
cd glibc-2.28
mkdir build && cd build
配置编译选项:
bash复制../configure --prefix=/usr \
--disable-profile \
--enable-add-ons \
--with-headers=/usr/include \
--with-binutils=/usr/bin
这里有几个关键参数需要注意:
--prefix=/usr:指定安装目录为/usr--disable-profile:禁用性能分析功能,减少依赖--enable-add-ons:启用附加组件--with-headers和--with-binutils:指定系统头文件和工具链位置开始编译:
bash复制make -j$(nproc)
编译过程中可能会遇到静态声明冲突的错误,类似这样:
code复制glibc-2.28/build/intl/plural.c:69:25: error: static declaration of '__gettextlex' follows non-static declaration
这是因为GCC版本兼容性问题,确保你已经按照前面的步骤安装了GCC 8.1,并且所有依赖库都是最新版。如果还是报错,可以尝试清理后重新配置:
bash复制make distclean
rm ./config.cache
编译成功后安装:
bash复制sudo make install
安装完成后,检查GLIBC版本:
bash复制ldd --version
现在应该显示GLIBC 2.28了。
升级完成后,建议进行全面的验证。首先检查所有关键命令是否还能正常工作:
bash复制ls
cp
bash
如果这些基本命令出现错误,可能是GLIBC升级出了问题。最坏的情况是系统无法启动,所以在生产环境升级前一定要先在测试环境验证。
另一个常见问题是动态链接库缓存没有更新,运行以下命令更新:
bash复制sudo ldconfig
如果遇到软件兼容性问题,可以通过设置LD_LIBRARY_PATH环境变量临时指定库路径:
bash复制export LD_LIBRARY_PATH=/usr/lib:/usr/local/lib
GLIBC升级是有风险的操作,务必提前准备好回滚方案。建议在升级前:
如果升级后系统出现问题,可以通过Live USB挂载系统分区,将备份的libc.so.6和ld-linux-x86-64.so.2还原到/lib/x86_64-linux-gnu/目录下。
安全方面要注意:
在完全离线的环境中管理依赖确实很麻烦,我总结了几点经验:
ldd命令查看软件依赖的库:bash复制ldd /path/to/your/program
apt-offline工具在有网的机器上生成依赖包清单,然后在离线机器上安装:bash复制sudo apt-offline set offline.sig --install-packages your-package
建立一个本地软件仓库,把常用依赖包都放进去,方便后续安装。
使用容器技术(如Docker)打包应用和所有依赖,避免直接修改系统库。