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
をチェックアウト
$ git clone git@github.com:kubernetes/test-infra.git $ cd test-infra
以降の手順はすべてtest-infra
のディレクトリで行う。
GitHubとProwを連携するための準備
GitHubとProwを連携するための準備としてWebhookで送信するSecretキーを生成しSecretリソースに追加する。
(test-infra) $ openssl rand -hex 20 > hook_secret (test-infra) $ kubectl create secret generic hmac-token --from-file=hmac=hook_secret
BotアカウントのGitHubアクセストークンをSecretリソースに追加する。
# BotアカウントのGitHubアクセストークンを`bot_oauth_secret`に保存している (test-infra) $ kubectl create secret generic oauth-token --from-file=oauth=bog_oauth_secret
Prowのコンポーネントをデプロイする
(test-infra) $ kubectl apply -f prow/cluster/starter.yaml
Deploymentは次のようになっている。
(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から叩かれるエンドポイントのhook
PodはNodePortで開かれているのでngrockをつかってプロキシしている。
NodePortを確認する。
(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でプロキシする。
(test-infra) $ ngrok http 31797
Forwardingに表示されているhttps://xxxxxx.ap.ngrok.io
のURLをWebhookに利用する。
Webhookを追加するユーティリティをつかってみる
ProwにはWebhookを追加するユーティリティが用意されている。ユーティリティを使わなければ手動でGitHubからWebhookを追加すれば良い。
(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が次のように出力されていれば完了。
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のhook
Podのログにno plugins
のエラーが確認できる。
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を次のように作成する。
(test-infra) $ echo 'plugins: soushin/bazel-multiprojects: - size' > ./plugins.yaml
soushin
のbazel-multiprojects
レポジトリにsizeプラグインを有効にしている。soushin
のみを指定してオーガナイゼーション全体にプラグインを有効にすることも可能である。
plugin.yamlをConfigMapに追加する。
(test-infra) $ kubectl create configmap plugins \ --from-file=plugins.yaml=plugins.yaml --dry-run -o yaml \ | kubectl replace configmap plugins -f -
追加したConfigMapはhook
Podにマウントされてプラグインが有効になる。
適当なプルリクエストを追加するとBotアカウントがSizeラベルを付与してくれる。
まとめ
- Prowの導入手順をまとめた。
- Kubernatesは1日にテストを1,000回以上実行するそうでスケーラビリティが求められる。ProwはKubernates環境で稼働するためニーズとマッチした仕組みである。
- Jenkins XはKnativeとProwを基盤に実現したサーバレスJenkinsで、Knativeというサーバレスの仕組みにProwプラグインの拡張性が組み合わさった感じなのかな、という印象を持った。
- 今回は既存のプラグインを試したが
trigger
というプラグインはtestに関連していそうで非常に気になる。 - プロジェクトにマッチするか引き続きProwを触っていきたい。