背景
根据我之前写的文章 将 Net 项目升级 Core项目经验:(一)迁移Net项目为Net CoreStandard项目,我们将公司内部最核心的ORM框架迁移到net core 上面,并在window和mac操作系统上运行测试通过,在后续我们开始准备迁移web 项目到net core 上,并运行在linux系统上。
我们选择的linux不是国际上的大牌linux发行版本,而是我们国内的linux发行版-中标麒麟。在迁移的过程中遇到了太多的问题,最后花费了1个星期的时间,部署成功了。我将其中遇到的坑和走过的路记录下来,给自己和其它同学再次安装起到作用。
在此安装过程中,感谢之前的前辈写的文章,帮助我少走了很多的弯路。
最后说明,能在国内的linux发行版运行dotnet core程序,在其他的大牌linux发行版就都不是问题。
前期准备
- 中标麒麟高级服务器版linux
- 好的耐心
- 降火的饮料
- 百度和google
上面几点是必备的,因为在我的安装过程中,没有网上写的帖子那么两三步,一帆风顺的就部署成功了,我从开始部署到测试成功总共花费了一个星期的时间,我的之前文章也可能在下次部署同样的环境,会有所不同的问题。
安装 .NET Core
根据Net Core 微软linux推荐的方式安装,只有redhat,centos,ubuntu,debian,fedora 等大牌的linux发行版安装,可以看微软的文章来查看支持的linux和安装方式Get started with .NET in 10 minutes,对于国内的linux发行版,没有明确的指示。 我使用是中标麒麟系统,根据命令的方式,类似redhat的发行版,但是根据redhat的安装方式,无法安装。所以支持采取最原始的方式来安装,压缩包安装。
采用压缩包安装方式
下载dotnet压缩包,打开dotnet linux官网下载地址 选择linux run app,到写文章的时候,目前是2.0.7版本,有个 install .net core runtime 2.0.7Package .tar.gz download的链接,点击下载,然后将文件复制到服务器上。
以下是我的安装步骤,里面的文件夹路径,可以安装你们自己的名字来建立,步骤如下:
- 在home建立NetCoreSDK 文件夹,并将上步下载好的文件复制到这个文件夹中
- 重命名文件为dotnet.tar.gz
- 在NetCoreSDK 文件夹中右键打开终端,后续输入以下命令:
- yum install libunwind libicu (安装libicu依赖,实际上会安装失败的,后续需要通过手动安装修复)
- mkdir -p /home/dotnet && tar zxf /home/NetCoreSdk/dotnet.tar.gz -C /home/dotnet (此命令首先在home下创建一个dotnet文件夹,然后解压dotnet.tar.gz文件到 home/dotnet文件中)
- ln -s /home/dotnet/dotnet /usr/local/bin (此命令是创建软链接的,可以使得dotnet命令注册到全局,在任何文件夹中都能识别dotnet 命令)
以上步骤,是我在参考Linux安装.Net core 环境并运行项目 这篇文章,根据自己服务器的情况在做的。
然后输入 dotnet --info来验证是否成功
dotnet --info
安装成功后,验证
输入 dotnet --info
出现错误提示:/usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.18' not found
错误:libstdc++.so.6: version `GLIBCXX_3.4.18' not found
原因是系统的gcc 版本太低,查询了下系统gcc的版本显示 4.4.7
gcc -v
查看gcc现有的版本库,
[root@gumis02 ~]# strings /usr/lib64/libstdc++.so.6 | grep GLIBC
GLIBCXX_3.4
GLIBCXX_3.4.1
GLIBCXX_3.4.2
GLIBCXX_3.4.3
GLIBCXX_3.4.4
GLIBCXX_3.4.5
GLIBCXX_3.4.6
GLIBCXX_3.4.7
GLIBCXX_3.4.8
GLIBCXX_3.4.9
GLIBCXX_3.4.10
GLIBCXX_3.4.11
GLIBCXX_3.4.12
GLIBCXX_3.4.13
GLIBC_2.3
GLIBC_2.2.5
GLIBC_2.3.2
GLIBCXX_FORCE_NEW
显示没有GLIBCXX_3.4.18 的库,所以我们需要升级GCC 的版本。中标麒麟的linux系统的包管理不是特别好用,在网上能找到各种包安装的,如rpm 包,yun install 等等都安装不了,在中标麒麟的系统上都没有用。所以最后只能采用源代码方式来编译安装。
gcc的所有版本源代码在 gun公司的gcc ftp上都有,最新的版本是8.1。根据我后续的经验,不要选择太高的版本,我选择的是5.3.0这个版本。
使用如下命令:
wget http://ftp.gnu.org/gnu/gcc/gcc-5.3.0/gcc-5.3.0.tar.gz
tar -xf gcc-5.3.0.tar.gz
cd gcc-5.3.0
./contrib/download_prerequisites
如使用wget命令下载不了,可以用浏览器下载,然后解压是一样的。
使用./contrib/download_prerequisites 会自己检测依赖的包安装,如果网络不好会下载失败,导致安装不了,需要手动下载三个依赖包。参考 安装gcc。
依赖的这三个文件,download_prerequisites文件,里面写的着依赖什么文件。
下载 gmp-4.3.2.tar.bz2 、mpc-0.8.1.tar.gz、mpfr-2.4.2.tar.bz2。这三个文件都可以在gcc ftp上找到。 下好了,将三个文件复制到gcc-5.3.0 文件夹中,执行以下命令:
tar -jxvf gmp-4.3.2.tar.bz2
tar -zxvf mpc-0.8.1.tar.gz
tar -jxvf mpfr-2.4.2.tar.bz2
ln -sf gmp-4.3.2 gmp
ln -sf mpc-0.8.1 mpc
ln -sf mpfr-2.4.2 mpfr
接着可以开始编译安装了:
mkdir gcc-build-6.4.0
cd gcc-build-6.4.0
../configure -enable-checking=release -enable-languages=c,c++ -disable-multilib
make j4
make install
最后查看gcc 版本验证是否成功。
[root@gumis02 ~]# gcc -v
u4f7fu7528u5185u5efa specsu3002
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/local/libexec/gcc/x86_64-unknown-linux-gnu/5.3.0/lto-wrapper
u76eeu6807uff1ax86_64-unknown-linux-gnu
u914du7f6eu4e3auff1a../configure -enable-checking=release -enable-languages=c,c++ -disable-multilib
u7ebfu7a0bu6a21u578buff1aposix
gcc u7248u672c 5.3.0 (GCC)
[root@gumis02 ~]# strings /usr/lib64/libstdc++.so.6 | grep GLIBC
GLIBCXX_3.4
GLIBCXX_3.4.1
GLIBCXX_3.4.2
GLIBCXX_3.4.3
GLIBCXX_3.4.4
GLIBCXX_3.4.5
GLIBCXX_3.4.6
GLIBCXX_3.4.7
GLIBCXX_3.4.8
GLIBCXX_3.4.9
GLIBCXX_3.4.10
GLIBCXX_3.4.11
GLIBCXX_3.4.12
GLIBCXX_3.4.13
GLIBCXX_3.4.14
GLIBCXX_3.4.15
GLIBCXX_3.4.16
GLIBCXX_3.4.17
GLIBCXX_3.4.18
GLIBCXX_3.4.19
GLIBCXX_3.4.20
GLIBCXX_3.4.21
GLIBC_2.3
GLIBC_2.2.5
GLIBC_2.3.2
GLIBCXX_FORCE_NEW
GLIBCXX_DEBUG_MESSAGE_LENGTH
[root@gumis02 ~]# ^C
参看以下三个链接的:
虽然看我写的文章不长,但是在安装的过程中,遇到了很多的问题,主要是对linux系统不熟悉,然后网上有很多的文章都很顺利,轻描淡写就安装成功了,我是在遇到了各种问题后,总结了自己的判断,觉得上面三个文章的链接解决了大部分的东西。 我安装gcc的时间用了1天半的时间,国产的linux还有很多路要走。
为什么我选择了gcc 5.3.0版本,其他的版本我也试过,试了三个版本(6.1.0, 6.4.0,7.3.0)都没有安装成功,各有各的问题,最终选择比较靠近4.4.7版本的时间点 5.3.0版本安装成功了,其主要原因可能是中标麒麟的linux内核版本不高,很多新的库都会编译不成功,缺少东西。
**注意: **
安装gcc 很有可能会导致你的linux系统启动不了,请慎重。
最后验证结果,输入 dotnet --info
出现新的错误提示:libc.so.6: version `GLIBC_2.14' not found。 下一步就是来解决这个错误
错误: libc.so.6: version `GLIBC_2.14' not found
原因是系统的glibc版本太低,软件编译时使用了较高版本的glibc引起的。
查看系统glibc支持的版本
[root@gumis02 dotnet]# strings /lib64/libc.so.6 |grep GLIBC_
GLIBC_2.2.5
GLIBC_2.2.6
GLIBC_2.3
GLIBC_2.3.2
GLIBC_2.3.3
GLIBC_2.3.4
GLIBC_2.4
GLIBC_2.5
GLIBC_2.6
GLIBC_2.7
GLIBC_2.8
GLIBC_2.9
GLIBC_2.10
GLIBC_2.11
GLIBC_2.12
GLIBC_PRIVATE
可以看到系统默认是2.12,需要安装更高的版本。
同样,没有办法利用rpm或yum install来安装,只能手工源代码的方式安装。
在安装glibc库的时候,是非常危险的,请谨慎处理,一不小心就系统运行不了。
最开始我选择了安装 2.14这个版本的glibc库,但是因为在上一步中,我安装了gcc 5.3.0版本,会在编译时提示 gcc old. 所以我选择了其他的版本来安装。在安装glibc库各种版本都失败,直道选择了 2.16.0这个版本才安装成功,每次安装重试都需要1到2个小时,非常的耗时间:
下载glibc 2.16.0 源代码,没有通过wget命令来下载,用此命令一直显示报错下载不了,之后用浏览器下载了,
需要下载两个文件:glibc-2.16.0.tar.gz 和
glibc-ports-2.16.0.tar.gz .
下载好,然后执行以下命令来安装:
tar -xvf glibc-2.16.0.tar.gz
tar -xvf glibc-ports-2.16.0.tar.gz
mv glibc-ports-2.16.0 glibc-2.16.0/ports
mkdir glibc-build-2.16.0
cd glibc-build-2.16.0
../glibc-2.16.0/configure --prefix=/usr --disable-profile --enable-add-ons --with-headers=/usr/include --with-binutils=/usr/bin
make
make install
其中在make的时候可能会提示一个错误,LD_LIBRARY_PATH 的一个错误,原因LD_LIBRARY_PATH系统变量的值,不能是:结尾,需要执行以下命令查看和修复
[root@gumis02 PublishOutput]# echo $LD_LIBRARY_PATH
/opt/dmdbms/bin
[root@gumis02 PublishOutput]# export LD_LIBRARY_PATH=/opt/dmdbms/bin
[root@gumis02 PublishOutput]#
然后再执行 make install.
如果安装成功,看下glibc的共享库:
可以看到2.12的旧库文件还在,多了2.16版本的库文件,而且软链接文件全部指向了2.16版本
[root@gumis02 DemoNetCore]# ll /lib64/libc*
-rwxr-xr-x 1 root root 1926520 2u6708 25 2016 /lib64/libc-2.12.so
-rwxr-xr-x 1 root root 10736842 5u6708 10 10:14 /lib64/libc-2.16.so
lrwxrwxrwx. 1 root root 18 7u6708 20 2017 /lib64/libcap-ng.so.0 -> libcap-ng.so.0.0.0
-rwxr-xr-x 1 root root 21160 3u6708 6 2014 /lib64/libcap-ng.so.0.0.0
lrwxrwxrwx. 1 root root 14 7u6708 20 2017 /lib64/libcap.so.2 -> libcap.so.2.16
-rwxr-xr-x 1 root root 19016 2u6708 27 2014 /lib64/libcap.so.2.16
lrwxrwxrwx. 1 root root 19 7u6708 20 2017 /lib64/libcgroup.so.1 -> libcgroup.so.1.0.40
-rwxr-xr-x 1 root root 103096 7u6708 24 2015 /lib64/libcgroup.so.1.0.40
-rwxr-xr-x. 1 root root 197064 2u6708 25 2016 /lib64/libcidn-2.12.so
-rwxr-xr-x 1 root root 277593 5u6708 10 10:14 /lib64/libcidn-2.16.so
lrwxrwxrwx 1 root root 15 5u6708 10 10:14 /lib64/libcidn.so.1 -> libcidn-2.16.so
lrwxrwxrwx. 1 root root 17 7u6708 20 2017 /lib64/libcom_err.so.2 -> libcom_err.so.2.1
-rwxr-xr-x 1 root root 17256 7u6708 26 2015 /lib64/libcom_err.so.2.1
-rwxr-xr-x 1 root root 43392 2u6708 25 2016 /lib64/libcrypt-2.12.so
-rwxr-xr-x 1 root root 163568 5u6708 10 10:13 /lib64/libcrypt-2.16.so
lrwxrwxrwx. 1 root root 22 7u6708 20 2017 /lib64/libcryptsetup.so.1 -> libcryptsetup.so.1.1.0
-rwxr-xr-x 1 root root 97536 10u6708 20 2014 /lib64/libcryptsetup.so.1.1.0
lrwxrwxrwx 1 root root 16 5u6708 10 10:14 /lib64/libcrypt.so.1 -> libcrypt-2.16.so
lrwxrwxrwx 1 root root 12 5u6708 10 10:14 /lib64/libc.so.6 -> libc-2.16.so
上述命令参考两个网址:解决/lib64/libc.so.6: version `GLIBC_2.14' not found 和 Linux/CentOS 升级C基本运行库CLIBC的注意事项(当想解决GLIBC_2.x找不到的编译问题)
安装成功后,查看:
[root@gumis02 dotnet]# strings /lib64/libc.so.6 |grep GLIBC_
GLIBC_2.2.5
GLIBC_2.2.6
GLIBC_2.3
GLIBC_2.3.2
GLIBC_2.3.3
GLIBC_2.3.4
GLIBC_2.4
GLIBC_2.5
GLIBC_2.6
GLIBC_2.7
GLIBC_2.8
GLIBC_2.9
GLIBC_2.10
GLIBC_2.11
GLIBC_2.12
GLIBC_2.13
GLIBC_2.14
GLIBC_2.15
GLIBC_2.16
GLIBC_PRIVATE
到此执行 dotnet --info 显示正常了。
[root@gumis02 DemoNetCore]# dotnet --info
Microsoft .NET Core Shared Framework Host
Version : 2.0.7
Build : 2d61d0b043915bc948ebf98836fefe9ba942be11
[root@gumis02 DemoNetCore]#
到此,终于将dotnet 环境安装成功了。
后续
我们将在此环境部署我在上一篇文章将 Net 项目升级 Core项目经验:(三)迁移后的Net Standard版本的类库测试和多平台项目实测的例子。
预告一下:
开心的将写好的控制台程序放到系统上执行,然而结果告诉了我,我还是太年轻了,报错。
首先将用vs发布一下,然后把文件放到中标麒麟的系统上,在文件夹打开终端,执行 dotnet **.dll,结果如下:
[root@gumis02 PublishOutput]# dotnet Beyondbit.ConsoleFrameworkNetStandard.IntegrationTests.dll
Failed to load ufffd=l, error: libunwind.so.8: cannot open shared object file: No such file or directory
Failed to bind to CoreCLR at '/home/dotnet/shared/Microsoft.NETCore.App/2.0.7/libcoreclr.so'
[root@gumis02 PublishOutput]#
继续打怪兽吧。