DevOps - Gitlab-CI与Kubernetes(k8s)集成之路
文章目录
1. 故事背景
如果你在使用gitlab-ci,也在使用k8s,但不知道怎么集成(就是通过gitlab-ci调用k8s),那你可以看看。 没过CET-4的我,通过google、官网和my homie,终于通了!
2. 提前准备
- 本次试验是在
CentOS 7.4 64位
系统,root
用户下进行 - Gitlab环境
- 拥有
Runner executor
为docker
的Gitlab-Runner(有Docker
执行环境即可) - Kubernetes(k8s)集群
3. 集成
3.1 新建项目
Gitlab-CI与Kubernetes的集成是项目级,每个项目都需要,为了测试,我们先新建一个项目。
这里我建的项目名叫opendata
,是一个空项目,只建一个文件.gitlab-ci.yml
,仅仅为了测试集成效果。
文件内容编辑好后,先提交一把,这个时候,gitlab-ci是肯定失败的,先忽略。
内容如下:
test:
image: domsn/kubectl-deployer
tags:
- docker
environment:
name: staging
url: https://your-domain.com
script:
- kubectl version
- kubectl get pods
关键解释:
Key | Description |
---|---|
image | 指定镜像,主要是装了kubectl |
tags | 通过这个命中Runner executor为docker的Gitlab-Runner(一般是在注册Runner的时候,填的tag) |
environment | 必须要设置,值不太重要,参考官网 |
3.2 配置Kubernetes
在gitlab里打开项目opendata
,在路径CI/CD -> Kubernetes
下,选择自建Kubernetes的模式。
需要配置5项内容:
- Kubernetes集群名称(
Kubernetes cluster name
) - API地址(
API URL
) - CA证书(
CA Certificate
) - Token
- 项目命名空间(
Project namespace (optional, unique)
)
整个集成最重要最麻烦的地方就在于填这五项内容,下面我会一项项说明:
Kubernetes集群名称(Kubernetes cluster name
)
这里和项目名称一样,填opendata
API地址(API URL
)
这里需要填k8s默认服务Kubernetes的Endpoint,而Endpoint一般是内网地址。因为我所有的机器都在阿里云的ECS,所以内网是可以直接通的。如果你不是这种情况,你也许在这里可以找到答案
登录k8s集群的机器上,执行👇命令
# 获取Endpoint
> kubectl get endpoints kubernetes -o json | jq -r '.subsets[0].ports[0].name + "://" + .subsets[0].addresses[0].ip + ":" + (.subsets[0].ports[0].port | tostring)'
https://172.32.174.43:6443
# 如果这种拿不到正常的结果,这样应该没问题
> kubectl get endpoints kubernetes
NAME ENDPOINTS AGE
kubernetes 172.32.174.43:6443 95d
# 如果还不行,最后一招,没辙了
> kubectl describe svc kubernetes
Name: kubernetes
Namespace: default
Labels: component=apiserver
provider=kubernetes
Annotations: <none>
Selector: <none>
Type: ClusterIP
IP: 10.96.0.1
Port: https443/TCP
TargetPort: 6443/TCP
Endpoints: 172.32.174.43:6443
Session Affinity: None
Events: <none>
综上所述,这里填https://172.32.174.43:6443
CA证书、Token、项目命名空间
因为这三项关系比较紧密,所以放在一起说明
按照我的认识,每个项目(或者同一类项目)会定义一个namespace
,而不放在默认的命名空间default
里。对于两个系统的集成,特别是服务提供商(k8s)都会对接口进行一系列的权限管理,不可以直接调用。
因此,我们需要做两件事。
- 在k8s里创建namespace,这里定为项目名
opendata
- 在k8s里创建一个账号,提供给gitlab-ci集成使用
新建文件01-namespace.yml
,内容如下:
---
apiVersion: v1
kind: Namespace
metadata:
name: opendata
labels:
name: opendata
创建namespace
> kubectl apply -f 01-namespace.yml
serviceaccount/opendata created
新建文件02-account.yml
,内容如下:
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: opendata
namespace: opendata
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: opendata
namespace: opendata
subjects:
- kind: ServiceAccount
name: opendata
namespace: opendata
roleRef:
kind: ClusterRole
name: cluster-admin
注:这里赋予的角色是
cluster-admin
,权限很高,在实际的使用场景,最好根据自己的权限需要,定义自己需要的Role
。譬如:我的需求是发布或者替换新的镜像,这样的话,我赋予deployment
的操作权限即可,其他操作一概不允许,可以提高k8s集群的安全性。
创建ServiceAccount
和ClusterRoleBinding
> kubectl apply -f 02-account.yml
serviceaccount/opendata created
命名空间和账号已准备就绪,找出TA的CA证书和Token吧
# 找出账号秘钥的名称
> kubectl get serviceaccount opendata -n=opendata -o json | jq -r '.secrets[0].name'
opendata-token-tzntp
# 根据上面的秘钥名称,找到CA证书
> kubectl get secret opendata-token-tzntp -n=opendata -o json | jq -r '.data["ca.crt"]' | base64 -d
-----BEGIN CERTIFICATE-----
MIICyDCCAbCgAwIBAgIBADANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDEwprdWJl
cm5ldGVzMB4XDTE4MDcwNTA2MTgxMFoXDTI4MDcwMjA2MTgxMFowFTETMBEGA1UE
AxMKa3ViZXJuZXRlczCCASIwQQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL0+
mJslbWHoZehZdpRgPE9t4TWeHBij4WLa7SMuPAz5AHnsoLqVepovdTU6XQDpS86e
LFcGJKW2+eYOQi23G9zeluySo+CTQC9CVNSoJtn5eDOKs9QVRAXi0JsccY0G7YLd
1p6nv65H4IHRsBTEg6UWWiOlvTHo+9NPnjdANIi4+b65Iid6AbON4n8xMmzEyFVY
iTgl7wRRNaQWOvjOyFgy5gRVVVFzXJ0P5JuwxyUczY91TH5zd8WrFEvaE2GzbW1b
HCIe1eZHRIGERaFT10sNp9mYSaPNuzMPuI5Fm1zx5Yvn7j+vjYpRZhzdgiAs095I
VvMK2rmfbnxVaXhJJ8ECAwEAAaMjMCAwDgYDVR0PAQH/BAQDAgKkMA8GA1UdEwEB
/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAHz0weT+Ztit6wMTZSmlkQtiO8qF
iHXNMbUN6fDSDEmZI8SL4YYeHgD5JXQOIkNdOQAG1nLUIgHEfWBU2b2zkwFmHB9x
fF/O4JAXwcR23mSGtBGf19Bonf5XalnwS0aBXIM1qD3fNY45NWFPC2zq5CsiM2pE
EjEpSQFqKLr35attktIT9UmnQJ/tkmYcDB7SMGhOy6zg7uwJzz5kV7gNJBvhUkrb
tXPI/P7Ua1t/L/j5idTaX3Bir9G93JAtkZr3RFUrwKgBVLvRIfc79JY6mm5knML0
/Tq+qC1BKcX/dest9WJXoGV1hjKma0UWoJmfBSdYMoNOtHOjoi0TQtZVm44=
-----END CERTIFICATE-----
# 根据上面的秘钥名称,找到Token
> kubectl get secret opendata-token-tzntp -n=opendata -o json | jq -r '.data.token' | base64 -d
eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdMJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJvcGVuZGF0YSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJvcGVuZGF0YS10b2tlbi10em50cCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJvcGVuZGF0YSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjdlMDk1ZmQxLWFiNjktMTFlOC05YzQ4LTAwMTYzZTBjNWQyYyIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpvcGVuZGF0YTpvcGVuZGF0YSJ2.vujCCWoogqMtPt0N6FwXOqPC9GTcAXngmdPBdOLULWAj3qsOVdLshy8Ztv88fwp_8XtfWlP9Nw78E3XLFU_rRHMI55EHbpsixy9je2Yd7Swe44qsFMA-1YoBsf78Eatlppy9CY1NWLhXICgO4czfs4UnhLfY8Wh7pjgBm8Q4AxQT9ag2wHYAz_T-2ZQj8QwFUMnesk0rPgdZ3RnqQ2Dif7nVJujyCcerp0U_yh0OACTPq62A2chZyE2yd-4G67JIYNI2ybvwfIQD1PgfUciD_t5IytbndcM-_951niYqObscvFZh2yQGL_a2Rrvn7NimmhDIWnDHi2AXPjwZLG7odw
所有的选项都已经找到值,填好,保存。
3.3 测试
条件已具备,测试一把,我们修改一下.gitlab.yml
,提交。
test:
image: domsn/kubectl-deployer
tags:
- docker
environment:
name: staging
url: https://your-domain.com
script:
- kubectl version
- kubectl get pods
- kubectl get pods --all-namespaces
如无意外,结果类似如下:
文章作者 xifan
上次更新 2018-08-30