Prow 是 Kubernetes 使用的云原生 CI/CD 系统(https://github.com/kubernetes/test-infra/tree/master/prow),用于管理 Kubernetes 的 Issue 和 PullRequest 以支持开源协同。Prow 通过 GitHub 事件触发 job,通过处理事件状态实现自动化的 ChatOps。
实验环境:
Linux VM-16-11-debian 4.19.0-6-amd64 #1 SMP Debian 4.19.67-2+deb10u2 (2019-11-11) x86_64 GNU/Linux Docker Version 20.10.1
Install kubectl
# 下载 kubectl
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
# 下载 kubectl.sha256
curl -LO "https://dl.k8s.io/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl.sha256"
# 校验
echo "$(<kubectl.sha256) kubectl" | sha256sum --check
# sudo 安装
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
或者用户安装
mkdir -p ~/.local/bin/kubectl
mv ./kubectl ~/.local/bin/kubectl
# and then add ~/.local/bin/kubectl to $PATH
参考文档 https://kubernetes.io/docs/tasks/tools/install-kubectl/
Install Kind
curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.10.0/kind-linux-amd64
chmod +x ./kind
mv ./kind /usr/local/bin/kind
参考文档 https://kind.sigs.k8s.io/docs/user/quick-start/#advanced
创建集群
kind create cluster
这将使用一个预编译好的节点镜像快速启动一个 Kubernetes 集群,默认集群名称为 kind
,可以使用 —name
参数指定自定义名称。
参考文档 https://kind.sigs.k8s.io/docs/user/quick-start/#installation
自定义创建集群参数
创建集群时候,可通过 —config
参数指定配置文件,示例配置见 kind-example-config。
kind create cluster --config example.yaml
可通过指定节点角色的数量配比,实现不同需求。如下面示例配置则会创建一个双 master + 三worker 节点的高可用集群
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: control-plane
- role: worker
- role: worker
- role: worker
部署 Prow
创建 prow namespace
kubectl create ns prow
GitHub 创建机器人用令牌
调试的时候可以直接用自己的 GitHub 帐号创建Token 使用,在正式使用的时候,为区分操作人,建议使用单独的机器人Github 帐号。
- Token 需要有
repo:status
和public_repo
权限 - 项目仓库需将机器人帐号加入合作者中
- 私有仓库则必须要有
repo
全部权限 - 如果是 GitHub 组织接入,则额外需要勾选
admin:org_hook
创建 GitHub Token 对应的 secret
echo "my-github-token" > ./github-token
kubectl create secret -n prow generic github-token --from-file=./github-token
创建一个用于 Github WebHook 认证的 hmac 令牌,并创建 kubernetes secret
openssl rand -hex 20 > ./secret
kubectl create secret -n prow generic hmac-token --from-file=hmac=./secret
创建集群 Role Binding
kubectl create clusterrolebinding cluster-admin-binding-"${USER}" \
--clusterrole=cluster-admin --user="${USER}"
应用 yaml 配置部署
下载 https://github.com/kubernetes/test-infra/blob/master/config/prow/cluster/starter-s3.yaml 配置,修改
- 替换 Github token:
<<insert-token-here>>
- 替换生成的 hmac token:
<< insert-hmac-token-here >>
- 替换域名:
<< your-domain.com >>
- 如果有使用证书管理器,则需更新
cert-manager.io/cluster-issuer:
- 替换目标组织/项目:
<< your_github_org >>
(如wayjam/test-repo
或an-org/test-repo
)
tide:
queries:
- labels:
- lgtm
- approved
missingLabels:
- needs-rebase
- do-not-merge/hold
- do-not-merge/work-in-progress
- do-not-merge/invalid-owners-file
orgs:
- << your_github_org >>
repos:
- wayjam/prow-test
应用了配置之后,发现部分 pods 启动失败(CrashLoopBackOff)
{"component":"prow-controller-manager","error":"tide query (index 0) is invalid: 'orgs' and 'repos' cannot both be empty","file":"prow/cmd/prow-controller-manager/main.go:123","func":"main.main","level":"fatal","msg":"Error starting config agent.","severity":"fatal","time":"2021-02-24T14:20:54Z"}
发现是有部份目标没有完全替换,重新修改配置,应用则全部 pods 可以正常启动。
配置外网访问
所有 pod 运行成功之后,上面的 starter.yaml
只包含了 ingress,但是没有包含 ingress controller,这里选择官方的 nginx ingress 作为流量入口,由于是测试,则不额外添加 LB。
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/kind/deploy.yaml
但是应用后发现 nginx pod 一直 pending,排查日志发现是由于我初始化的 kind 集群只有一个master 节点,不满足上面 yaml 配置的调度规则
Warning FailedScheduling 76s (x5 over 100s) default-scheduler 0/1 nodes are available: 1 node(s) didn't match Pod's node affinity
先把 Deployment 中的 tolerations 去掉,然后给 master 节点打上所需标签:
kubectl label node kind-control-plane ingress-ready=true
最好就是在集群初始化的时候按照 https://kind.sigs.k8s.io/docs/user/ingress/ 文档指引预先配置好集群,集群创建之后则不能再更改配置
除了节点标签之外,集群的端口还需对外暴露以提供服务,初始化集群的时候需按上面文档使用 extraPortMappings
参数指定转发的端口。
如果集群已经创建并已经部署好了服务,也像我一样不想重新创建集群,也可通过下面方法做快速端口转发。当然自行通过 Nginx 容器 link 到 kind 网络的 kind-control-plane
容器即可( nodeport 监听所在)。
root@VM-debian:~/$ kubectl -n ingress-nginx describe service ingress-nginx-controller
Name: ingress-nginx-controller
Namespace: ingress-nginx
Labels: app.kubernetes.io/component=controller
app.kubernetes.io/instance=ingress-nginx
app.kubernetes.io/name=ingress-nginx
Annotations: <none>
Selector: app.kubernetes.io/component=controller,app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx
Type: NodePort
IP Families: <none>
IP: 10.96.250.65
IPs: 10.96.250.65
Port: http 80/TCP
TargetPort: http/TCP
NodePort: http 32291/TCP
Endpoints: 10.244.0.107:80
Port: https 443/TCP
TargetPort: https/TCP
NodePort: https 32191/TCP
Endpoints: 10.244.0.107:443
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
# 将 ingress-nginx 服务的 NodePort 32291 端口映射到本地 80 端口
$ docker run -itd --name ingress --network kind -p 80:80 --link kind-control-plane zhangsean/nginx-port-proxy kind-control-plane:32291
# 将 ingress-nginx 服务的 NodePort 32191 端口映射到本地 443 端口
$ docker run -itd --name ingress-https --network kind -p 443:80 --link kind-control-plane zhangsean/nginx-port-proxy kind-control-plane:32191
配置 WebHook
首先测试公网请求是否能通:
http POST https://prow.lockthedoor.ltd/hook --verify no
到 GitHub 项目设置添加 WebHook
- Payload URL: 填入公网地址,如 https://prow.lockthedoor.ltd/hook
- Content Type:
application/json
- Secrets: 刚才随机生成的 HMAC
- Which events would you like to trigger this webhook: Send me everything
- SSL verification: 如果没有使用可信证书,则选择
Disable
新建一个 issue(如 https://github.com/wayjam/prow-test/issues/1),在评论框输入 /meow
机器人收到时间则会发送一个猫咪评论。