背景
根据我之前写的文章 将 Net 项目升级 Core项目经验:(一)迁移Net项目为Net Core\Standard项目,我们将公司内部最核心的ORM框架迁移到net core 上面,并在window和mac操作系统上运行测试通过,在后续我们开始准备迁移web 项目到net core 上,并运行在linux系统上。
我们选择的linux不是国际上的大牌linux发行版本,而是我们国内的linux发行版-中标麒麟。在迁移的过程中遇到了太多的问题,最后花费了1个星期的时间,部署成功了。我将其中遇到的坑和走过的路记录下来,给自己和其它同学再次安装起到作用。

在此安装过程中,感谢之前的前辈写的文章,帮助我少走了很多的弯路。

最后说明,能在国内的linux发行版运行dotnet core程序,在其他的大牌linux发行版就都不是问题。

前期准备

  1. 中标麒麟高级服务器版linux
  2. 好的耐心
  3. 降火的饮料
  4. 百度和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的链接,点击下载,然后将文件复制到服务器上。

以下是我的安装步骤,里面的文件夹路径,可以安装你们自己的名字来建立,步骤如下:

  1. 在home建立NetCoreSDK 文件夹,并将上步下载好的文件复制到这个文件夹中
  2. 重命名文件为dotnet.tar.gz
  3. 在NetCoreSDK 文件夹中右键打开终端,后续输入以下命令:
  4. yum install libunwind libicu (安装libicu依赖,实际上会安装失败的,后续需要通过手动安装修复)
  5. mkdir -p /home/dotnet && tar zxf /home/NetCoreSdk/dotnet.tar.gz -C /home/dotnet (此命令首先在home下创建一个dotnet文件夹,然后解压dotnet.tar.gz文件到 home/dotnet文件中)
  6. 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
\u4f7f\u7528\u5185\u5efa specs\u3002
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/local/libexec/gcc/x86_64-unknown-linux-gnu/5.3.0/lto-wrapper
\u76ee\u6807\uff1ax86_64-unknown-linux-gnu
\u914d\u7f6e\u4e3a\uff1a../configure -enable-checking=release -enable-languages=c,c++ -disable-multilib
\u7ebf\u7a0b\u6a21\u578b\uff1aposix
gcc \u7248\u672c 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

参看以下三个链接的:

  1. CentOS 6.6 升级GCC G++
  2. 安装gcc 4.9.0
  3. linux下安装或升级GCC4.8,以支持C++11标准

虽然看我写的文章不长,但是在安装的过程中,遇到了很多的问题,主要是对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 2\u6708  25 2016 /lib64/libc-2.12.so
-rwxr-xr-x  1 root root 10736842 5\u6708  10 10:14 /lib64/libc-2.16.so
lrwxrwxrwx. 1 root root       18 7\u6708  20 2017 /lib64/libcap-ng.so.0 -> libcap-ng.so.0.0.0
-rwxr-xr-x  1 root root    21160 3\u6708   6 2014 /lib64/libcap-ng.so.0.0.0
lrwxrwxrwx. 1 root root       14 7\u6708  20 2017 /lib64/libcap.so.2 -> libcap.so.2.16
-rwxr-xr-x  1 root root    19016 2\u6708  27 2014 /lib64/libcap.so.2.16
lrwxrwxrwx. 1 root root       19 7\u6708  20 2017 /lib64/libcgroup.so.1 -> libcgroup.so.1.0.40
-rwxr-xr-x  1 root root   103096 7\u6708  24 2015 /lib64/libcgroup.so.1.0.40
-rwxr-xr-x. 1 root root   197064 2\u6708  25 2016 /lib64/libcidn-2.12.so
-rwxr-xr-x  1 root root   277593 5\u6708  10 10:14 /lib64/libcidn-2.16.so
lrwxrwxrwx  1 root root       15 5\u6708  10 10:14 /lib64/libcidn.so.1 -> libcidn-2.16.so
lrwxrwxrwx. 1 root root       17 7\u6708  20 2017 /lib64/libcom_err.so.2 -> libcom_err.so.2.1
-rwxr-xr-x  1 root root    17256 7\u6708  26 2015 /lib64/libcom_err.so.2.1
-rwxr-xr-x  1 root root    43392 2\u6708  25 2016 /lib64/libcrypt-2.12.so
-rwxr-xr-x  1 root root   163568 5\u6708  10 10:13 /lib64/libcrypt-2.16.so
lrwxrwxrwx. 1 root root       22 7\u6708  20 2017 /lib64/libcryptsetup.so.1 -> libcryptsetup.so.1.1.0
-rwxr-xr-x  1 root root    97536 10\u6708 20 2014 /lib64/libcryptsetup.so.1.1.0
lrwxrwxrwx  1 root root       16 5\u6708  10 10:14 /lib64/libcrypt.so.1 -> libcrypt-2.16.so
lrwxrwxrwx  1 root root       12 5\u6708  10 10:14 /lib64/libc.so.6 -> libc-2.16.so

上述命令参考两个网址:解决/lib64/libc.so.6: version `GLIBC_2.14' not foundLinux/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]#

继续打怪兽吧。