业务需求

  1. Go项目中引入了RocksDB
  2. 本地编译正常,且能够运行
  3. 需要CICD编译并部署在K8S上
  4. 编译需要调用C编译器

现状

  1. CICD 的runner是Ubuntu
  2. runner环境干净,没有其他任何依赖安装

CICD遇到的问题

  1. 缺少依赖,Runner不支持yum,需要apt安装

  2. 编译后的代码需要静态编译,否则会报错 Not a valid dynamic program

    #.gitlab-ci.yml
    build:
    	stage: verify-build-test
    	extends: .go-cache
    	tags:
    		- golang
    	before_script:
    		- export GOPROXY=https://goproxy.xmxdev.com
    		- export GONOSUMDB=git.gametaptap.com
    		- go env
    		- mkdir -p /opt/tapad/bs-thirdparty/
    		- mkdir -p bin
    		- mkdir -p logs
    		- mkdir -p data
    		- mkdir -p resources
    			#这里注意git clone的的时候需要单独申请部署用户名与秘钥,保证能够成功clone下来 
    		- git clone https://{username}:{password}@git.com/ad/thirdparty #这里隐藏重要参数
    			#移动第三方依赖到指定目录
    		- mv -f bs-thirdparty /opt/tapad/
    			#这些都是调试信息 可以不用
    		- ls /opt/tapad/
    		- ls /opt/tapad/bs-thirdparty
    		- ls /opt/tapad/bs-thirdparty/include
    		- cat go.mod
    			#安装rocksdb依赖
    		- apt-get update
    		- apt-get install -y libsnappy-dev zlib1g-dev libbz2-dev liblz4-dev libzstd-dev libgflags-dev
    		- wget https://github.com/facebook/rocksdb/archive/v6.15.5.tar.gz
    		- mv v6.15.5.tar.gz rocksdb-6.15.5.tar.gz
    		- tar xvzf rocksdb-6.15.5.tar.gz
    		# 这里使用static_lib实现静态编译rocksdb依赖
    		- make -C ./rocksdb-6.15.5 -j8 static_lib
    		- make -C ./rocksdb-6.15.5 install
    		#下面这条命令不知道有没有用
    		- CGO_CFLAGS="-I/builds/tapad/bs-sstmanager/rocksdb-6.15.5/include"  CGO_LDFLAGS="-L/builds/tapad/bs-sstmanager/rocksdb-6.15.5 -lrocksdb -lstdc++ -lm -lz -lbz2 -lsnappy -llz4 -lzstd"  go get github.com/tecbot/gorocksdb
    
    
    	#Makefile
    	.PHONY: sstmanager dummy_kvplugin 
    	BS_THIRDPARTY=/opt/tapad/bs-thirdparty
    	BS_THIRDPARTY_INCLUDE=$(BS_THIRDPARTY)/include
    	BS_THIRDPARTY_LIBS=$(BS_THIRDPARTY)/libs
    	
    	ARCH=$(shell uname)
    	
    	BUILD_DIR=$(shell pwd)
    	
    	build: sstmanager dummy_kvplugin 
    	
    	ifeq ($(ARCH), Linux)
    	CGO_CFLAGS+=-I $(BS_THIRDPARTY_INCLUDE)
    	CGO_LDFLAGS+=-L $(BS_THIRDPARTY_LIBS) -Wl,-rpath=$(BS_THIRDPARTY_LIBS) -lstdc++ -lm -lrocksdb -lz -lbz2 -lsnappy -llz4 -lzstd
    	CI_CD += GOOS=linux GOARCH=amd64 CGO_ENABLED=1  
    	#CGO_ENABLED需要开启,否则无法使用C编译器
    	CI_CD_BUILD += -ldflags "-linkmode \"external\" -extldflags \"-static\"" 
    	#这里是实现静态编译的关键,一定要注意引号,转义斜杠的使用
    	endif
    
    	sstmanager:
    		cd cmd/sstmanager && CGO_CFLAGS="${CGO_CFLAGS}" CGO_LDFLAGS="${CGO_LDFLAGS}" ${CI_CD} go mod tidy #这句话可能不需要
    		cd cmd/sstmanager && CGO_CFLAGS="${CGO_CFLAGS}" CGO_LDFLAGS="${CGO_LDFLAGS}" ${CI_CD} go build ${CI_CD_BUILD} -o  $(BUILD_DIR)/bs-sstmanager
    
    	#解析后的命令
    	#cd cmd/sstmanager && CGO_CFLAGS="-I /opt/tapad/bs-thirdparty/include" CGO_LDFLAGS="-L /opt/tapad/bs-thirdparty/libs -Wl,-rpath=/opt/tapad/bs-thirdparty/libs -lstdc++ -lm -lrocksdb -lz -lbz2 -lsnappy -llz4 -lzstd" GOOS=linux GOARCH=amd64 CGO_ENABLED=1 go build -ldflags "-linkmode \"external\" -extldflags \"-static\"" -o  /builds/tapad/bs-sstmanager/bs-sstmanager
    
    

遇到的坑

  1. makefile里面的一条语句是一个命令,且目录切换不会影响下一条语句,因此需要连续运行的命令用&&连接为一行,否则可能/bin/sh: 2: build: not found,也可能是我换行语法写的不正确.
  2. makefile和cicd中的命令不要换行,否则会出现运行错误
  3. CGO_ENABLED=1必需开启,且要加入参数-ldflags "-linkmode \"external\" -extldflags \"-static\""以实现静态编译,注意转义
  4. 使用static_lib参数实现rocksdb静态编译
  5. runner中的git clone需要添加账号密码或部署秘钥
  6. 如果CGO_ENABLED=0,那么与C的依赖就会丢失,报错undefined: gorocksdb.DB等错误

参考文献

  1. https://juejin.cn/post/6844903619527983111
Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐