ProwではじめるChatOps on GitHub。
Kubernetesのtest-infraレポジトリにあるProwを試す。ProwはKubernates環境を基盤としたCIとCDのシステムである。
モチベーション
Kubernatesを追っている人であれば次のようなコメントのやり取りをGitHub上で見かけたことがあるだろう。
Enable kustomize in kubectl by Liujingfang1 · Pull Request #70875 · kubernetes/kubernetes · GitHub
/holdや/testなどのキーワードをコメント欄に入力してオペレーションを実行している。/hold cancelでラベルを取り除いたり/testでテストを実行している。入力したキーワードはWebhookで稼働しているProwのエンドポイントに送信されてGitHubイベントと合わせてProwのプラグインが実行される仕組みである。
このProwの導入手順をまとめていきプロジェクトにフィットするか検討したいというのがエントリのモチベーションである。ProwはKubernetesをはじめIstio、Knative、Prometheusなどのオーガナイゼーションにも利用されている。
Prowをデプロイする
Prowが含まれるレポジトリはkubernetes/test-infraである。
デプロイ手順はgetting_started_deploy.mdを参考に進めている。
test-infra/getting_started_deploy.md at master · kubernetes/test-infra · GitHub
gcpを利用している人であればTackleというユーティリティが用意されているので対話式にProwをセットアップできるが私はローカル(Docker For Desktop)でKubernatesを起動させているためManual deploymentを参考にすすめた。
またClusterとNamespaceはdocker-for-desktopとdefaultとしている。実際の運用ではプロジェクトに合わせた選択が求められる。
事前に準備するものを一覧にする。
- Prowを試すレポジトリ
- Botアカウント(GitHubのBot専用アカウント)
- BotアカウントのAccessToken
- ご自身のアカウントのAccessToken
Kubernatesはk8s-ci-robotというBotアカウントを使用している。
k8s-ci-robot (Kubernetes Prow Robot) · GitHub
kubernetes/test-infra をチェックアウト
1 2 |
$ git clone git@github.com:kubernetes/test-infra.git $ cd test-infra |
以降の手順はすべてtest-infraのディレクトリで行う。
GitHubとProwを連携するための準備
GitHubとProwを連携するための準備としてWebhookで送信するSecretキーを生成しSecretリソースに追加する。
1 2 |
(test-infra) $ openssl rand -hex 20 > hook_secret (test-infra) $ kubectl create secret generic hmac-token --from-file=hmac=hook_secret |
BotアカウントのGitHubアクセストークンをSecretリソースに追加する。
1 2 |
# BotアカウントのGitHubアクセストークンを`bot_oauth_secret`に保存している (test-infra) $ kubectl create secret generic oauth-token --from-file=oauth=bog_oauth_secret |
Prowのコンポーネントをデプロイする
1
|
(test-infra) $ kubectl apply -f prow/cluster/starter.yaml |
Deploymentは次のようになっている。
1 2 3 4 5 6 7 8 |
(test-infra) $ kubectl get deployments NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE deck 2 2 2 0 3m hook 2 2 2 2 3m horologium 1 1 1 1 3m plank 1 1 1 1 3m sinker 1 1 1 1 3m tide 1 1 1 1 3m |
deckがエラーになっているがOAuth Appを利用するケースのため割愛する。
test-infra/pr_status_setup.md at master · kubernetes/test-infra · GitHub
WebhookをGitHubに追加する
私の環境はローカルのためIngressにIPアドレスが割り振られないがGitHubのWebhookから叩かれるエンドポイントのhookPodはNodePortで開かれているのでngrockをつかってプロキシしている。
NodePortを確認する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
(test-infra) $ kubectl describe service hook
Name: hook
Namespace: default
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"hook","namespace":"default"},"spec":{"ports":[{"port":8888}],"sel...
Selector: app=hook
Type: NodePort
IP: 10.98.120.195
LoadBalancer Ingress: localhost
Port: <unset> 8888/TCP
TargetPort: 8888/TCP
NodePort: <unset> 31797/TCP
Endpoints: 10.1.7.24:8888,10.1.7.25:8888
Session Affinity: None
External Traffic Policy: Cluster
Events: <none> |
確認したNodePort 31797をngrockでプロキシする。
1
|
(test-infra) $ ngrok http 31797 |
Forwardingに表示されているhttps://xxxxxx.ap.ngrok.ioのURLをWebhookに利用する。
Webhookを追加するユーティリティをつかってみる
ProwにはWebhookを追加するユーティリティが用意されている。ユーティリティを使わなければ手動でGitHubからWebhookを追加すれば良い。
1 2 3 4 5 6 |
(test-infra) $ bazel run //experiment/add-hook -- \ --hmac-path=/path/to/hook_secret \ --github-token-path=/path/to/own_oauth_secret \ --hook-url https://xxxxxx.ap.ngrok.io/hook \ --repo soushin/bazel-multiprojects \ --confirm=true |
- hmac-pathには生成した
hook_secretを指定(注:絶対パス) - github-token-pathにはご自身のGitHubアクセストークンを保存した
own_oauth_secretを指定(注:絶対パス) - hook-urlにはngrockでプロキシした
https://xxxxxx.ap.ngrok.ioに/hookのエンドポイントを追加して指定 - repoにはProwを試すレポジトリを指定
実行後にINFOが次のように出力されていれば完了。
1 2 |
INFO[0000] ListRepoHooks(soushin, bazel-multiprojects) client=github INFO[0000] CreateRepoHook(soushin, bazel-multiprojects) client=github |
GitHubのSettings -> WebhooksのページにWebhookが追加されていてグリーンのチェックマークが点いていれば正常に完了。
これでKubernatesにデプロイしたProwのコンポーネントとGitHubがWebhookで連携できた。次にプラグインを追加してProwのChatOpsを体験していく。
Prowプラグインを追加する
プラグインを追加する前にProwのhookPodのログにno pluginsのエラーが確認できる。
1 2 |
hook-64448bb489-42v8b hook {"component":"hook","level":"warning","msg":"no plugins specified-- check syntax?","time":"2019-01-08T03:07:15Z"}
hook-64448bb489-42v8b hook {"component":"hook","level":"warning","msg":"no plugins specified-- check syntax?","time":"2019-01-08T03:08:15Z"} |
つまり何かしらプラグインを追加して初めてProwのChatOpsが体験できるわけだ。
Prowのプラグインはこちらにまとまっている。
Sizeプラグインを試す
SizeプラグインはPushしたコード量に応じてBotアカウントがsize/SやSize/XLなどのラベルをプルリクエストに付与してくれるプラグインである。
plugins.yamlを次のように作成する。
1 2 3 |
(test-infra) $ echo 'plugins: soushin/bazel-multiprojects: - size' > ./plugins.yaml |
soushinのbazel-multiprojectsレポジトリにsizeプラグインを有効にしている。soushinのみを指定してオーガナイゼーション全体にプラグインを有効にすることも可能である。
plugin.yamlをConfigMapに追加する。
1 2 3 |
(test-infra) $ kubectl create configmap plugins \ --from-file=plugins.yaml=plugins.yaml --dry-run -o yaml \ | kubectl replace configmap plugins -f - |
追加したConfigMapはhookPodにマウントされてプラグインが有効になる。
適当なプルリクエストを追加するとBotアカウントがSizeラベルを付与してくれる。
まとめ
- Prowの導入手順をまとめた。
- Kubernatesは1日にテストを1,000回以上実行するそうでスケーラビリティが求められる。ProwはKubernates環境で稼働するためニーズとマッチした仕組みである。
- Jenkins XはKnativeとProwを基盤に実現したサーバレスJenkinsで、Knativeというサーバレスの仕組みにProwプラグインの拡張性が組み合わさった感じなのかな、という印象を持った。
- 今回は既存のプラグインを試したが
triggerというプラグインはtestに関連していそうで非常に気になる。 - プロジェクトにマッチするか引き続きProwを触っていきたい。