阿里云 Serverless Kubernetes 让您无需管理和维护集群与服务器,即可快速创建 Kuberentes 容器应用,并且根据应用实际使用的 CPU 和内存资源量进行按需付费。使用 Serverless Kubernetes,您可以专注于设计和构建应用程序,而不是管理运行应用程序的基础设施。它基于阿里云弹性计算基础架构,并且完全兼容 Kuberentes API 的解决方案,充分结合了虚拟化资源带来的安全性、弹性和 Kubernetes 生态。
由此定位,这种集群是很适合用来跑CI流程场景的。CI触发时创建对应资源,CI结束后销毁对应的资源。目前Serverless Kubernetes集群尚在公测当中,或多或少有一些不友好的体验,比如:
- 不支持
Role
,RoleBinding
。 - 不能自定义
CoreDNS
/Kube-DNS
配置。 - 不能使用
docker-in-docker
方式构建镜像。 - 不支持
PersistentVolume
和PersistentVolumeClaim
。
以上提及的四点就是本次部署Runner时需要解决的需求。
不支持 Role,RoleBinding
在触发CI流程时,Runner会在Kubenertes集群中创建对应的Pod进行CI,在不支持自定义 Role
,RoleBinding
的情况下,也就只有使用阿里云提供的kubeconfig
文件了,将对应值粘贴到对应字段创建Secret
,这里不再累述。最后Runner会引用到这个Secret
。
apiVersion: v1
kind: Secret
metadata:
name: kubernetes-admin-cert
type: kubernetes.io/tls
data:
ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUq......
tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUR......
tls.key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQp......
不能自定义CoreDNS/Kube-DNS配置
自定义CoreDNS/Kube-DNS配置是为了让集群内部应用不通过公网访问同一VPC下的其他应用直接通过内网即可,比如Gitlab,Harbor等。
解决方式一:
阿里云官方提供的解决方案是使用privateZone。但本文不介绍这种方式,为什么呢?这是一个谜一样的问题,这里不做深入探讨。
解决方式二:
👋注意:该方法Serverless Kubernetes集群尚不支持,未来将会支持,故现在解决此问题只能用方式一。
让Runner所生成的Pod使用HostAliases。但是官方提供的Runner并不支持这个功能,那就直接优化源码吧,优化详情参见此次提交。
不能使用docker-in-docker方式构建镜像
解决方式:
使用kaniko进行镜像构建,这里我们将官方镜像中的可执行文件复制到自己的CI镜像中即可使用。
FROM gcr.io/kaniko-project/executor:v0.9.0
FROM registry.cn-hangzhou.aliyuncs.com/choerodon-tools/cibase:0.7.0
COPY --from=0 /kaniko/executor /usr/local/bin/kaniko
这是我build好可直接食用的镜像:
registry.cn-hangzhou.aliyuncs.com/setzero/gitlab-ci-slaver:0.1.0
待友好解决的问题:
- Harbor界面不显示镜像信息issues,但如果原本就有该镜像的仓库那么是可以正常显示的。疑是Harbor版本太低的问题,目前使用的是v1.4.0。
- 执行kaniko后会出现
Deleting filesystem...
操作,导致执行完kaniko后不能再执行其他命令,在CI中可以再分出一个stage
来规避这个问题。
不支持 PV 和 PVC
在CI时我们需要缓存一些可复用的文件,或者上一job所产生的文件下个job会用到。
解决方式一:
先部署minio,minio通过nfs volume方式挂载nas,然后在.gitlab-ci.yml
文件中使用cache
和artifacts
关键字。但本文不介绍这种方式,为什么呢?这是一个谜一样的问题,这里不做深入探讨。
相关资料:
解决方式二:
让Runner所生成的Pod使用nfs volume方式挂载nas,但是官方提供的Runner并不支持这个功能,那就直接优化源码吧,优化详情参见此次MR,故将这次CI生成的二进制文件覆盖官方原有的就行。
FROM gitlab/gitlab-runner:alpine-v11.8.0
ADD https://gitlab.com/TimeBye/gitlab-runner/-/jobs/174588999/artifacts/raw/out/binaries/gitlab-runner-linux-amd64 /usr/bin/gitlab-ci-multi-runner
RUN chmod +x /usr/bin/gitlab-ci-multi-runner
这是我build好可直接食用的镜像:
registry.cn-hangzhou.aliyuncs.com/setzero/gitlab-runner:alpine-v11.8.1
后记
优化Runner后的配置示例
concurrent = 3
check_interval = 0
[[runners]]
name = "runner"
url = "https://gitlab.com/"
token = "2b388a2636d35b9d141348e972706b"
executor = "kubernetes"
output_limit = 51200
environment = ["CHART_REPOSITORY=http://chart.com",
"SONAR_URL=http://sonarqube.com"]
[runners.kubernetes]
host = "https://abcde.serverless-1.kubernetes.cn-shanghai.aliyuncs.com:6443"
cert_file = "/etc/gitlab-runner/tls.crt"
key_file = "/etc/gitlab-runner/tls.crt"
ca_file = "/etc/gitlab-runner/ca.crt"
namespace = "default"
pull_policy = "always"
cpu_limit = "2"
cpu_request = "2"
memory_limit = "4Gi"
memory_request = "4Gi"
service_cpu_limit = "1"
service_cpu_request = "1"
service_memory_limit = "2Gi"
service_memory_request = "2Gi"
helper_cpu_limit = "250m"
helper_cpu_request = "250m"
helper_memory_limit = "512Mi"
helper_memory_request = "512Mi"
helper_image = "gitlab/gitlab-runner-helper:x86_64-3fff1dcf"
[runners.kubernetes.pod_annotations]
# "k8s.aliyun.com/enable-eip" = "true"
[runners.kubernetes.host_aliases]
"127.0.0.1" = [ "foo.local", "bar.local" ]
"127.0.0.2" = [ "oof.local", "rab.local" ]
[runners.kubernetes.volumes]
[[runners.kubernetes.volumes.nfs]]
name = "runner-cache"
mount_path = "/cache"
server = "abcde-map64.cn-shanghai.nas.aliyuncs.com"
nfs_path = "/runner/cache-pv"
[[runners.kubernetes.volumes.nfs]]
name = "runner-maven"
mount_path = "/root/.m2"
server = "abcde-map64.cn-shanghai.nas.aliyuncs.com"
nfs_path = "/runner/maven-pv"
[[runners.kubernetes.volumes.secret]]
name = "docker-registry-secret"
mount_path = "/root/.docker"
read_only = false
[runners.kubernetes.volumes.secret.items]
"config.json" = "config.json"