背景原因
envoy是istio数据面的核心组件,也是现在最热门的网络代理中间件之一。但是它的编译部署一直是个复杂的问题,网络上关于envoy编译环境搭建以及编译步骤的文档少之又少,就算找到一篇也不一定能过运用在新版本的envoy编译流程上(因为引入了v8内核作为wasm扩展的运行时)。
所以如果有用户需要对源码做定制修改时(比如加入自己的过滤器等),编译成为了挡在用户路上的第一支拦路虎。此外,就算使用官方提供的编译好的二进制文件,也需要glibc版本至少要满足2.18以上。这对于CentOS/RHEL 7版本的用户来说极不友好(CentOS/RHEL 7只支持glibc 2.17,冒然升级glibc可能导致系统几乎所有程序都段错误,无法运行)。
其实envoy社区提供了很多个可以直接使用的CI镜像,如果你的系统支持glibc 2.18及以上的话,可以直接使用官方提供的CI镜像来编译envoy。但是!使用envoy社区提供的镜像编译步骤,生成的envoy只是普通的envoy,是不能正常的支持istio的wasm插件扩展的,这也就是说如果你使用envoy作为istio的数据面代理的话,是不能够正常运行的(istio预置的wasm模块不能正常加载)。
那么,如何才能编译出及支持低版本glibc,又能使用wasm扩展的envoy呢?这是本文要和大家讨论的,请往下看...
主要工具链及版本
工具 | 版本 |
---|---|
git | 2.23 |
golang | 1.15+ |
gcc | 7 |
llvm + clang | 10 |
cmake | 3.17.5 |
make | 3.82 |
ninja | 1.10.2 |
bazel | 3.7.2 |
python | 3.6+ |
zlib | 1.2.3.4 |
环境准备
准备一台最小化安装的CentOS7
-
安装一些依赖
# 下面编译要用到 yum install -y wget python3 openssl-devel libcurl-devel expat-devel patch libtool libatomic
-
安装gcc 7(要用gcc编译git和llvm)
yum install centos-release-scl yum install devtoolset-7 yum install devtoolset-7-libatomic-devel # 需要使用gcc7时可以采用如下方法切换 # 1. 临时切换gcc # 1.a 新启一个bash来切换的gcc7 scl enable devtoolset-7 bash # 1.b 当前的bash切换gcc7,下面两条选择一条 source /opt/rh/devtoolset-7/enable source scl_source enable devtoolset-7 # 2. 想要每次启动都默认使用gcc7,可以放到启动配置里 echo 'source /opt/rh/devtoolset-7/enable' >> /etc/profile # 验证一下 which gcc gcc --version
-
安装git
wget https://mirrors.edge.kernel.org/pub/software/scm/git/git-2.23.0.tar.xz tar xvf git-2.23.0.tar.xz cd git-2.23.0/ make prefix=/usr/local/git all make prefix=/usr/local/git install echo "export PATH=$PATH:/usr/local/git/bin" >> /etc/profile source /etc/profile
-
安装cmake
cd ~ wget https://cmake.org/files/v3.16/cmake-3.16.0-Linux-x86_64.sh chmod +x cmake-3.16.0-Linux-x86_64.sh ./cmake-3.16.0-Linux-x86_64.sh mv ~/cmake-3.16.0-Linux-x86_64 /usr/local/ # 把cmake目录/bin加到PATH里 # 保险起见,可以把cmake软链接到/usr/bin/中,以防后面编译找不到cmake ln -s /usr/local/cmake-3.16.0-Linux-x86_64/bin/cmake /usr/bin/cmake
-
安装llvm + clang
git clone https://github.com/llvm/llvm-project.git cd llvm-project # 切换到v10版本 git checkout origin/release/10.x -b v10 mkdir build cd build # 生成Makefile cmake -G "Unix Makefiles"\ -DLLVM_ENABLE_PROJECTS="clang;libcxx;libcxxabi;lld"\ -DCMAKE_BUILD_TYPE=Release\ ../llvm # 编译 make mkdir /usr/llvm mv bin docs include lib libexec /usr/llvm/ # 最后将bin路径放到PATH中 # 还需要ldconfig配置项里加入/usr/llvm/lib echo /usr/llvm/lib > /etc/ld.so.conf.d/llvm.conf
-
安装ninja
wget https://github.com/ninja-build/ninja/releases/download/v1.10.2/ninja-linux.zip unzip ninja-linux.zip # 把解压的文件放到/usr/bin里
-
安装golang及envoy所需的bazel工具(用go写的)
wget https://golang.org/dl/go1.16.4.linux-amd64.tar.gz tar xvf go1.16.4.linux-amd64.tar.gz # 依然是添加到PATH # 然后下载所需的bazel工具 go get -u github.com/bazelbuild/buildtools/buildifier # 设置环境变量BUILDIFIER_BIN为$GOPATH/bin/buildifier go get -u github.com/bazelbuild/buildtools/buildozer # 设置环境变量BUILDOZER_BIN为$GOPATH/bin/buildozer
-
安装bazel
wget https://github.com/bazelbuild/bazel/releases/download/3.7.2/bazel-3.7.2-installer-linux-x86_64.sh chmod +x bazel-3.7.2-installer-linux-x86_64.sh ./bazel-3.7.2-installer-linux-x86_64.sh --user
(重点)编译安装gn
编译v8引擎要用到gn来生成ninja file,默认bazel下载的gn不能支持glibc 2.18以下的版本,所以就导致了在CentOS/RHEL 7系统上无法正常编译,在其他高版本glibc的系统上编译出来的envoy也无法在CentOS/RHEL 7上使用。我们需要使用自己编译的版本替换掉bazel默认下载的gn。
另外多说一句,在编译v8(wee8)的时候,其编译脚本里是会判断系统版本以及是否安装了gn的,所以只要把编译好的gn放到PATH可以找得到的地方就可以了。
```bash
git clone https://gn.googlesource.com/gn
cd gn
python build/gen.py
ninja -C out
# To run tests:
out/gn_unittests
```
编译envoy
虽然安装了llvm/clang编译器,但是envoy的编译过程可能需要用到libatomic库,所以最好gcc也切换到7
scl enable devtoolset-7 bash
到此,就是全部的编译准备工作了。接下来就可以编译envoy了,按需求不同,大体上envoy是如下两种编译方式:
a.单独的envoy
# 直接拉取envoy仓库的代码
git clone https://github.com/envoyproxy/envoy.git
cd envoy
# 执行编译
bazel build //source/exe:envoy-static
b.istio envoy
# 如果需要支持istio的wasm扩展,需要拉去istio/proxy仓库的代码来编译
git clone https://github.com/istio/proxy.git
cd proxy
make build_envoy
可以根据自己的需求来编译,编译好的二进制文件在工程目录下的bazel-bin目录中。整体编译时间较长,建议使用配置较高的机器,CPU核数与内存呈1比2配置(例如8CPU+16GB RAM)。
如有问题或不清楚的地方,望指正。转载请注明出处。