前言
首先说明,本人使用的mips环境,处理器是Loongson-3A3000,系统是NeoKylin7 server。所有包的构建都是在这个环境下进行,由于没有其他mips环境,并不能保证其他mips环境能行。
由于业务需求,本人需要编译mips64le环境下的k3s 1.18.19版本。网上查了查,官方提供了编译方法,但是并不支持mips环境。mips环境下,只找到用go build
直接编译的方法。于是尝试了一下,go build
直接编译出来的k3s有200MB(官方的k3s只有40-60MB),这大小差了很多。那么这个k3s能不能用呢?能用,但是如果没安装kubernets-cni并将local-host放到PATH中的话,会报错。而且这个k3s别看他有200MB,但是helm, containerd等都没包含进去。如果这些你都无所谓,那么可以不用往下看了。直接用mips的golang go build
使用就可以。但是如果你和我一样觉得很不爽,觉得这不是完整的k3s,可以继续往下。
准备
首先是编译mips版本k3s的前期准备工作,你需要一个mips的环境,以及mips的golang。如何从源码编译mips版本的golang,这里不多赘述,网上教程很多。如果你不想自己编译,也可以用我编译好的golang 1.16.5,链接放在文末。
除了golang的环境,还要对应k3s版本的源码,下载至mips环境,并解压。 解压后的k3s源码目录大致如下:
e2e LICENSE README.md
build docker-compose.yml etc main.go scripts
BUILDING.md Dockerfile.dapper go.mod Makefile tests
channel.yaml Dockerfile.manifest go.sum manifests Vagrantfile
cmd Dockerfile.test.dapper install.sh package vendor
contrib Dockerfile.test.mod.dapper k3s.service pkg vendor.go
按照官方的编译教程,在这个地方直接执行mkdir -p build/data && ./scripts/download && go generate
然后再执行make
就能编译出完整的k3s,but! mips环境不可以,因为执行make后是在docker容器中进行的编译工作,而Dockerfile.dapper中使用的ubuntu镜像,没有mips版。那么既然这个镜像不行,用mips版的其他镜像不就可以了?于是我去查了查,发现有mips版的Debian镜像和golang镜像,于是我开心的不得了,把Dockerfile进行了修改,并且发现他确实能make, but!! 还是不行。因为Debian镜像中缺少了一些依赖安装不了,并且编译过程会卡住。尝试多次无果后,我放弃了。
既然镜像编译不行,难道就真的没办法了吗? no no no, 我以前编译k8s的时候,是可以在本地进行编译的,所以为啥不直接不使用镜像,在本地编译k3s。所以我打算本地编译,在编译前先执行
mkdir -p build/data && ./scripts/download && go generate
发现这一步就错了。查看scripts/download的内容,主要是要下载一个叫k3s-root的东西,这个是k3s官方自己提供的,但是也没mips版本,所以这个也需要编译。
编译k3s-root
首先从github下载k3s-root源码,并解压到/source
这个目录(没有就创建这个目录,这个位置很重要),解压后大概如下
busybox.config Dockerfile.dapper LICENSE package README.md Vagrantfile
buildroot iptables-detect Makefile patches scripts
看上去和k3s差不多。同样的,不能用docker构件,所以查看Makefile和Dockerfile.dapper,发现就是执行了scripts/ci这个脚本。但是我们直接执行是不对的,查看scripts/build这个脚本,发现实际是编译了buildroot,这个感兴趣的可以了解一下。
在编译的时候的配置文件是/source/buildroot/${BUILDARCH}config
,但是/source/buildroot/
目录下是这样的:
[root@host30 buildroot]# ls
amd64config arm64config armconfig config ppc64leconfig
没有mips64elconfig
,所以我研究了一下buildroot后,自己添加了mips64elconfig
执行vim /source/buildroot/mips64elconfig
并添加以下内容
#
# Target options
#
BR2_ARCH_IS_64=y
BR2_ARCH_HAS_MMU_MANDATORY=y
# BR2_arcle is not set
# BR2_arceb is not set
# BR2_arm is not set
# BR2_armeb is not set
# BR2_aarch64 is not set
# BR2_aarch64_be is not set
# BR2_csky is not set
# BR2_i386 is not set
# BR2_m68k is not set
# BR2_microblazeel is not set
# BR2_microblazebe is not set
# BR2_mips is not set
# BR2_mipsel is not set
# BR2_mips64 is not set
BR2_mips64el=y
# BR2_mips64el is not set
# BR2_nds32 is not set
# BR2_nios2 is not set
# BR2_or1k is not set
# BR2_powerpc is not set
# BR2_powerpc64 is not set
#BR2_powerpc64le=y
# BR2_riscv is not set
# BR2_sh is not set
# BR2_sparc is not set
# BR2_sparc64 is not set
# BR2_x86_64 is not set
# BR2_xtensa is not set
BR2_ARCH_HAS_TOOLCHAIN_BUILDROOT=y
BR2_ARCH="mips64el"
BR2_ENDIAN="LITTLE"
BR2_GCC_TARGET_ARCH="mips64r2"
BR2_BINFMT_SUPPORTS_SHARED=y
BR2_READELF_ARCH_NAME="mips64el"
BR2_BINFMT_ELF=y
BR2_GCC_TARGET_ABI="64"
BR2_MIPS_CPU_MIPS64=y
BR2_mips_64=y
BR2_MIPS_NABI64=y
# BR2_MIPS_SOFT_FLOAT is not set
BR2_MIPS_NAN_LEGACY=y
保存后回到/source
,执行BUILDARCH=mips64el scripts/ci
。中间可能会跳出来一些选项如
choice[1]: 1
Target Architecture Variant
> 1. Generic MIPS64 (BR2_mips_64)
2. Generic MIPS64R2 (BR2_mips_64r2) (NEW)
3. Generic MIPS64R3 (BR2_mips_64r3) (NEW)
4. Generic MIPS64R5 (BR2_mips_64r5) (NEW)
5. Generic MIPS64R6 (BR2_mips_64r6) (NEW)
6. I6400 (BR2_mips_i6400) (NEW)
7. Octeon II (BR2_mips_octeon2) (NEW)
8. Octeon III (BR2_mips_octeon3) (NEW)
9. P6600 (BR2_mips_p6600) (NEW)
choice[1-9?]:
Target ABI
1. n32 (BR2_MIPS_NABI32) (NEW)
> 2. n64 (BR2_MIPS_NABI64)
根据自己实际情况选。因为我是龙芯3A3000所以选的BR2_mips_64r2和n64
然后就是漫长的等待…
等编译结束后会在/source
文件夹下多出artifacts
和dist
两个文件夹。建议先执行下/source/artifacts/mips64el/bin/ip a
如果报错如无法执行的二进制文件
,那么说明编译错了,把artifacts
,dist
和/usr/src/buildroot
删除,重新编译。如果执行没问题,那么dist
文件夹下有我们编译出来的k3s-root的tar文件。
我编译出的k3s-root-mips64le.tar会放在文末,可以直接使用
k3s 编译
回到k3s源码的根目录,执行mkdir -p build/data && go generate
。
先执行vim scripts/package
,把里面的
./package-image
./package-airgap
这两行注释掉,因为我们只编译k3s。
再执行vim scripts/download
,将其中k3s-root部分注释并改为解压自己编译的k3s-root
#curl --compressed -sfL https://github.com/rancher/k3s-root/releases/download/${ROOT_VERSION}/k3s-root-${ARCH}.tar | tar xf -
cp /source/dist/k3s-root-${ARCH}.tar .
tar xf k3s-root-${ARCH}.tar
最后执行SKIP_VALIDATE=true scripts/ci
可能遇到的问题
在编译k3s的过程中遇到了很多坑
No package 'libseccomp' found error during runc build
这个错是因为要安装libseccomp-devel
或者libseccomp-dev
,但是我的环境的源里没有,需要自己编译。
从runc releases下载libseccomp-2.5.1.tar.gz
解压后,目录如下
aclocal.m4 config.status configure.h.in include LICENSE Makefile.in stamp-h1
build-aux configure CONTRIBUTING.md libseccomp.pc m4 README.md tests
CHANGELOG configure.ac CREDITS libseccomp.pc.in Makefile SECURITY.md tools
config.log configure.h doc libtool Makefile.am src
执行
./configure
make
make install
如果过程中遇到
AUDIT_ARCH_MIPSEL64" undeclared here
这样的报错。参考issue,修改include/seccomp.h,tools/bpf.h和tools/util.h,都在合适的位置添加上
#ifndef AUDIT_ARCH_MIPSEL64
#define AUDIT_ARCH_MIPSEL64 (EM_MIPS|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
#endif
- 缺少gperf
下载源码
解压后执行
./configure
make
make install
use s.Rdev (type uint32) as type uint64
这个是在mips编译k8s也会遇到的问题。根据报错把指定文件中的(buf.Dev)
和(buf.Rdev)
分别改为(uint64(buf.Dev))
和(uint64(buf.Rdev))
就可以了。整个过程中还遇到了两个其它问题,但是由于发生时没有记录,现在忘记了。很惭愧。。
End
总之在排除了一系列的问题后,成功编译出了mips版本的k3s,大小为41MB。执行k3s server也能运行。
网盘链接
网盘中包括mips版的golang 1.16.5, k3s 1.18.19, k3s-root 0.8.1
链接:https://pan.baidu.com/s/1lH3RbBW9tiSmOd15xhOU_A
提取码:31bh