Screwdriver.cdとは
1より
Screwdriver.cdはYahoo! (現在はOathの一部)が開発しているCI/CDツールです。
元々社内向けプロダクトだったものをOSS化に伴い、大規模な利用に耐えうる設計で作り直したものになります。2
日本ではYahoo! JAPAN Tech Conference 2018で紹介されました。
コンセプトの概要や、特徴については下記のリンクを参考にしてみてください。
http://docs.screwdriver.cd/ja/about/
このページの目標
できるだけ少ない設定で、GKE上のScrewdriver.cdで何らかのビルドが実行できることを目指します。
準備
GCPで以下のものを作成します。
- Screwdriver.cdが動作するKubernetes(GKE)
- Screwdriver.cdがArtifacts(ビルドのログなど)の保存に使用するCloud Storage
- Screwdriver.cdがBuild情報などを保存に使用するCloud SQL
今回はそれぞれが何ぞや、ということの詳しい紹介は割愛します。
Kubernetes
Screwdriver.cdのコア部分を動作させつつ、ビルドの実行も行うKubernetesを構築します。
GKEの画面に行って、クラスタの作成からぽちぽちと作れば大丈夫です。
名前はscrewdriver、ゾーンはasia-northeast1-aを、クラスタのバージョンは1.8.6-gke.0(執筆時の最新)を選択しました。
また、Cloud StorageとCloud SQLに繋がるよう設定します。
「その他」を展開し、アクセス範囲の「各APIにアクセス権を設定」を選択します。
そうすると他のGCPのサービスの一覧が出てくるので、Cloud StorageとCloud SQLを「有効」にします。
残りはデフォルトで作成しました。
Cloud Console上の「接続」からkubectlで構築したクラスタに接続できることを確認できれば準備完了です。
Cloud Storage
Screwdriver.cdはArtifactsの保存にS3互換のStorageを利用できます。
Google Cloud Storageも設定をすることで、S3互換のAPIが利用できるようになります。
以下のような設定でCloud Storageを作成しました。
「設定」から「相互運用性」タブを開き、「新しいキーを作成」を押し、キーとシークレットを払い出しました。
このキーとシークレットを後で利用します。
Cloud SQL
Screwdriver.cdは各種情報の保存にsequelizeがサポートしているDBが利用できます。
今回はCloud SQLでMySQLを作成して利用します。
以下のような設定でMySQLのインスタンスを作成しました(パスワードは説明用に生成したもので、これはもちろん使用していません)
Screwdriver.cdで使用するデータベースも作成しておきましょう。
次に、Google Kubernetes Engineから接続するを参考に、GKEからCloud SQLに繋がるようにします。
Screwdriver.cdのAPIのPodにsidecarとしてCloud SQL Proxyのコンテナを立ち上げ、APIのコンテナはそこ経由でCloud SQLと接続します。
ページの通りに進めていき、INSTANCE_CONNECTION_NAME
さえ控えておけば今回は大丈夫なはずです。
参考に、自分が設定した際のログを貼っておきます(一部マスクしています)。
$ gcloud sql users create sd-proxyuser cloudsqlproxy~% --instance=screwdriver
Creating Cloud SQL user...done.
Created user [sd-proxyuser].
$ gcloud sql instances describe screwdriver | grep connectionName
connectionName: <tk3fftk_connection_name>:asia-northeast1:screwdriver
$ kubectl create secret generic cloudsql-instance-credentials --from-file=credentials.json=<tk3fftk_credentials>.json
secret "cloudsql-instance-credentials" created
$ kubectl create secret generic cloudsql-db-credentials --from-literal=username=sd-proxyuser
secret "cloudsql-db-credentials" created
これらの設定やSecretは後ほど設定に利用します。
最後に、Google Cloud SQL APIにアクセスしてAPIが有効になっているかを確認してください。
Screwdriver.cdの構築
Screwdriver.cdは主に以下の3つのコンポーネントから構成されています。利用しているバージョンも併記しています。
- API (v0.5.185)
- UI (v1.0.213)
-
Store (v2.2.2, ログや成果物をS3互換ストレージに保存するAPIを持つ)
ビルドキューを使用する場合には、ここにQueue(Redis)とWorkerが追加されるのですが、今回は使用しないのでこの3つを構築します。
これらは全てDocker Imageとしてビルドされています(Docker Hub)
以下のリポジトリにKubernetesにapplyするYAMLファイルを置いてあります。
https://github.com/tk3fftk/config-examples/tree/gke
このリポジトリは、screwdriver-cd-test/config-examplesをforkしており、GKEで動かすために設定を変更・追加したものになります。
手順
今回は全てnamespace: default
で進めていきます。
ServiceAccountとClusterRole, ClusterRoleBinding作成
まず、ビルドに利用するServiceAccountを作成します。
$ kubectl apply -f serviceaccounts/sd-build.yaml
$ kubectl get sa
NAME SECRETS AGE
default 1 14d
sd-build 1 14d
次にビルド用Podを作成するためのClusterRoleを作成します。
が、GKEのk8sクラスタに対して、ClusterRoleを作成する権限をデフォルトでは持っていないので、まずは自分が操作するための権限を作成します。(参考)
$ gcloud info | grep Account
Account: [your-mail@hoge.com]
$ kubectl create clusterrolebinding cluster-admin-binding --clusterrole=cluster-admin --user=your-mail@hoge.com
clusterrolebinding "cluster-admin-binding" created
これで、ビルド用Podを作成するClusterRoleとClusterRoleBindingが作成できます。以下を実行して作成します。
$ kubectl apply -f roles.yaml
clusterrole "cluster-writer" created
clusterrole "cluster-reader" created
$ kubectl apply -f roleBinding.yaml
clusterrolebinding "cluster-write" created
clusterrolebinding "cluster-read" created
rolebinding "sd-build-write" created
Ingress作成
Ingressを利用してAPI,UI,Storeのアクセスを振り分けます。
Ingressについて詳しくはGCPドキュメントかKubernetesドキュメントをご覧ください。
以下を実行しIngressを作成します。
ADDRESSが設定されるまで時間がかかるので、その間に次の作業を行います。
$ kubectl apply -f services/sd-ingress.yaml
$ kubectl get ing
NAME HOSTS ADDRESS PORTS AGE
sd-ingress * xx.xx.xx.xx 80 5d
Secret作成
Screwdriver.cd内で使う各種漏らすとまずいパスワードなどをKubernetesのSecretとして作成します。
sd-secrets.yaml
内の値を埋めていきます。
jwt_private:
jwt_public:
scm_settings:
cookie_pass:
encryption_pass:
s3_key_id:
s3_key_secret:
jwt_private, jwt_public
JWTに署名するための秘密鍵と、署名を検証するための公開鍵です。
以下のコマンドを実行して生成します。
$ openssl genrsa -out jwt.pem 2048
$ openssl rsa -in jwt.pem -pubout -out jwt.pub
これらをbase64エンコードしてsd-secrets.yaml
に追加します。
$ cat jwt.pem | base64
$ cat jwt.pub | base64
scm_settings
scm-settings.json
を埋めてbase64エンコードします。
secret
はwebhooks署名用のパスワードを生成して記入してください。
oauthClientSecret
とoauthClientId
に関しては、GitHub OAuth Appsで作成したものを記入してください。
また、このときCallback URLは、Ingressに割り当てられたアドレスを利用して以下のように設定してください(まだアドレスがなければ割り当てられてから)。
username
とemail
は今はこのままでも構いません。
先ほどと同様にscm-settings.json
をbase64エンコードして、sd-secrets.yaml
に追加します。
cookie_pass, encryption_pass
セッションデータを暗号化するためのパスワードと、Screwdriver.cdのSECRETを暗号化するためのパスワードです。
32文字以上の文字列をmkpasswd
などで生成して、base64エンコードしてsd-secrets.yaml
に追加します。
s3_key_id, s3_key_secret
Cloud Storage 作成時に取得したキーとシークレットをbase64エンコードしてsd-secrets.yaml
に追加します。
このとき、改行コードが末尾に入らないように注意してください。
$ echo -n "YOUR-S3-KEYID" | base64
Secret作成
以下を実行してSecretを作成します。これらはPodに環境変数としてマウントされて利用されます。
$ kubectl apply -f sd-secrets.yaml
API, UI, StoreのYAML書き換えと作成
API
services/api.yaml
の# TODO: ~~~
とコメントが入っている部分を修正していきます。
- L61: Cloud SQL設定時に取得した
INSTANCE_CONNECTION_NAME
を-instances
フラグに設定します。 - L117: 以下のコマンドで出力されるtoken名を設定します。これはServiceAccount作成時に生成されるもののはず。
$ kubectl get secrets | grep sd-build-token
sd-build-token-ffm4q kubernetes.io/service-account-token 3 14d
- L126, 128, 130: IPアドレスをご自分のIngressのIPアドレスに書き換えます。
これらが済んだらapplyします。
$ kubectl apply -f services/api.yaml
UI
IPアドレスをご自分のIngressのIPアドレスに書き換え、のみ必要です。
これが済んだらapplyします。
$ kubectl apply -f services/ui.yaml
Store
- L70: Cloud Storageを作成したRegionに修正します。
- L72: 作成したBucket名に修正します。
- L79, 81: IPアドレスをご自分のIngressのIPアドレスに書き換えます。
これらが済んだらapplyします。
$ kubectl apply -f services/store.yaml
確認
以下のように、全てRunningになれば完了です。
$ kubectl get po
NAME READY STATUS RESTARTS AGE
sdapi-767cc944b6-m5cqs 2/2 Running 0 3d
sdstore-7ccf8d6fb7-tp6gt 1/1 Running 0 5d
sdui-855dd58447-pmmk4 1/1 Running 0 5d
Buildを動かしてみる
こちらのNode.jsのリポジトリをBuildしてみます。
https://github.com/tk3fftk/screwdriver-cd-nodejs-test
Screwdriver.cdではGitHubの権限を利用して操作の制限をかけているため、こちらを使う場合はforkしてお試しください。
IngressのIPアドレスにブラウザでアクセスすると、以下のようなScrewdriver.cdのUIが表示されるはずです。
右上のえんぴつアイコンを押して新しいパイプラインを作成します。
作成前にGitHubのOAuth認証を求められるので許可してください。
GitHubからSSHのGit URLを取得してきてペーストします。
以下のようなパイプラインのページにリダイレクトされます(ビルドはまだないと思います)
Startボタンを押してページの更新を行う3と、以下のように青いアイコンが表示されるのでこれをクリックします。
ビルドページが表示されるので、祈りながらビルドが通るのを待ちます。
これでこのページの目的である、「GKE上のScrewdriver.cdで何らかのビルドが実行できること」は達成されました。
まとめ
- GCPのプロダクトを使用して、GKE上でScrewdriver.cdを動作させ、ビルドを実行してみました。
注
- Screwdriver.cdは現在も開発が頻繁に行われているため、執筆当時のバージョンより少し古いバージョンのScrewdriver.cdを動かしています。そのため、最新のバージョンを動かすためには設定の追加などが必要な場合があります。
- GKEのIngressを使って同一IPアドレスで無理やり動かしている形になっています。[api,cd,store].screwdriver.cdのようにドメインを取得してIngressで割り振る形のほうが設計者の意図した形だと思うのでおすすめです。
- ビルドのログが最初しか表示されない状態のようでした。こちらはちょっと原因を調査します。
開発をウォッチしたい方は…
-
v1.0.223以降のバージョンのUIでは、Start後に自動更新がされるようになっています。 ↩