お題
以下をやってみただけ。本当にそれだけ。
https://cloud.google.com/docs/ci-cd/spinnaker/spinnaker-for-gcp
及び
https://cloud.google.com/solutions/continuous-delivery-spinnaker-kubernetes-engine?hl=ja
対象者
GCP使ってて、GKEで管理させたいサービスもある。
試しにSpinnaker使ってCD(継続的デリバリー)したいんだけど、自前で用意するの大変そう。
と思っている人。
前提
- GCPプロジェクト作成済み。
実践
Spinnaker on Google Cloud Platform をインストール
以下を見つつ、やってみる。
https://cloud.google.com/docs/ci-cd/spinnaker/spinnaker-for-gcp
Cloud Shell Editorを開くところまで
以下にアクセス
https://console.cloud.google.com/kubernetes/application?_ga=2.220373085.418580277.1607004980-1541468982.1603807794
「SPINNAKER FOR GOOGLE CLOUD PLATFORM に移動」ボタン押下
「続行」ボタン押下
「確認」ボタン押下
待機。。。
チュートリアルをオープン
XXXXXX@cloudshell:~/cloudshell_open/spinnaker-for-gcp/scripts/install$ cloudshell launch-tutorial provision-spinnaker.md
チュートリアルに従い、Spinnaker on GCP をインストール
画面右下の「開始」ボタン押下
書かれるがまま、コマンドを適宜Cloud Shellに打ち込んでいく。
ちなみに、最後のスクリプト実行に 10 分以上かかるかもと書いてあったけど、たしかに、けっこうな時間がかかった。。。
ようやく↓が表示された。
続いて、ステップ2
プレビューしてみる。
おー、Spinnakerだ。
はい、で、最後のステップ。
OAuthの設定をしろとあるので。
次は、OAuthクライアントIDの作成。
アプリケーションの種類は「ウェブアプリケーション」を選択するらしい。
「作成」ボタン押下
「クライアントID」と「クライアントシークレット」はコピーしておく。
チュートリアル記載の最後のコマンドを叩いたら、やはり、けっこうな時間をかけた後、先ほどの認証情報ページで承認済みのリダイレクトURIに追加すべきURIがコンソールに出力されるので、↓のように追加。
ただ、なんだかこのあたり、コマンド実行が終わってからも1時間くらい完了までに時間がかかるらしいので、待つ。
さて、1時間(実際には待ちくたびれて一晩寝かせたけど)待ち、チュートリアルに記載されていたリンク(※)からSpinnakerを開く。
※
Conclusion
Connect to your Spinnaker installation here.
はい、表示された。
ちょっと前に「ポート 8080 でプレビュー
」にて表示されたサイトと同じ。
だけど、これは、指定のGoogleアカウントでログインした状態でのみ見れるよう認証がかかった状態。
試しに別のPC(スマホとかでもいい)で(指定のGoogleアカウントで未ログイン状態)アクセスしてみても、サイトは開かない。
Spinnakerの管理
以下の手順。
https://cloud.google.com/docs/ci-cd/spinnaker/spinnaker-for-gcp#manage_spinnaker
GKEからSpinnakerアプリを開き、Cloud Shellにて接続。
spinnaker-1
リンク押下で、「次のステップ」として、いろいろやれることが載っている。
とりあえず、Spinnakerが使える状態になったので、まずはここまで。
継続的デリバリーパイプラインを作成
以下を見つつ、やってみる。
https://cloud.google.com/solutions/continuous-delivery-spinnaker-kubernetes-engine?hl=ja
まあ、Spinnakerを使えるようにするところまでは既にやってるので、厳密には↓から。
https://cloud.google.com/solutions/continuous-delivery-spinnaker-kubernetes-engine?hl=ja#create_a_cluster_for_application_deployments
サンプルアプリ用のGKEクラスタ作成
Cloud Shell使って以下を叩き込む。
ZONE=us-east1-c
gcloud config set compute/zone $ZONE
gcloud container clusters create app-cluster \
--machine-type=n1-standard-2
怒られた。
使うGCPプロジェクトをセットしてなかった。
書かれた通り、プロジェクトIDをセットすると、今度はうまくいった。
app-cluster
が出来てる。
GKEクラスタをSpinnakerに追加
以下を叩いて、聞かれたことに答えていく(基本はデフォでいいはず)だけ。
~/cloudshell_open/spinnaker-for-gcp/scripts/manage/add_gke_account.sh
あとは以下2つ。
kubectl config use-context gke_${DEVSHELL_PROJECT_ID}_${ZONE}_spinnaker-1
~/cloudshell_open/spinnaker-for-gcp/scripts/manage/push_and_apply.sh
Spinnakerを覗いてみると、いつの間にやらアプリケーションがいっぱい出来ている。
Dockerイメージのビルド
ソースコード リポジトリを作成
これも、記事に書かれている通りにひたすら打ち込む。
https://cloud.google.com/solutions/continuous-delivery-spinnaker-kubernetes-engine?hl=ja#create_your_source_code_repository
cd ~
wget https://gke-spinnaker.storage.googleapis.com/sample-app-v4.tgz
tar xzfv sample-app-v4.tgz
cd sample-app
git init
git add .
git commit -m "Initial commit"
gcloud source repos create sample-app
git config credential.helper gcloud.sh
export PROJECT=$(gcloud info --format='value(config.project)')
git remote add origin https://source.developers.google.com/p/$PROJECT/r/sample-app
git push origin master
Cloud Source Repositories に入った様子。
ビルドトリガーを構成
Versionを振ったGitタグをCloud Source RepositoriesにpushすることをトリガーにDockerイメージのビルドとContainer Registryへのpushが行われるようにする。
Spinnaker で使用するために Kubernetes マニフェストを準備
これも、記事に書かれている通りにひたすら打ち込む。
https://cloud.google.com/solutions/continuous-delivery-spinnaker-kubernetes-engine?hl=ja#prepare_your_kubernetes_manifests_for_use_in_spinnaker
export PROJECT=$(gcloud info --format='value(config.project)')
gsutil mb gs://$PROJECT-kubernetes-manifests
gsutil versioning set on gs://$PROJECT-kubernetes-manifests
sed -i s/PROJECT/$PROJECT/g k8s/deployments/*
git commit -a -m "Set project ID"
これで、CIの部分は終わりかな。
デプロイメント パイプラインの構成
パイプライン作成
やはり以下に従ってポチポチ。
https://cloud.google.com/solutions/continuous-delivery-spinnaker-kubernetes-engine?hl=ja#create_the_deployment_pipeline
spin application save --application-name sample \
--owner-email example@example.com \
--cloud-providers kubernetes \
--gate-endpoint http://localhost:8080/gate
実は今回の手順で言うと、上記のまま叩くと以下のように怒られる。
ローカルの8080ポートで開くやり方からIAP使ったインターネット公開に変えてるので。
なので、エンドポイントを直して叩く。
spin application save --application-name sample \
--owner-email example@example.com \
--cloud-providers kubernetes \
--gate-endpoint https://spinnaker-1.endpoints.[GCPプロジェクトID].cloud.goog/gate
コマンド実行からちょっとタイムラグはあった(ブラウザリロードが必要だった?)けど、出来てる。
export PROJECT=$(gcloud info --format='value(config.project)')
sed s/PROJECT/$PROJECT/g spinnaker/pipeline-deploy.json > pipeline.json
spin pipeline save --gate-endpoint https://spinnaker-1.endpoints.[GCPプロジェクトID].cloud.goog/gate -f pipeline.json
↑も、さり気なくエンドポイントを直してる。
エンドポイントは直したのだけど、でも、怒られた。
pipeline.json
を開いてみると、たしかにエラー内容の通り、3行分、キー重複してた。
とりあえず、重複してるキーを削除してリトライ。
今度は成功。
パイプラインが出来ている。よね?(Deploy
という名前で作ったのか。)
イメージをビルド
git tag v1.0.0
git push --tags
Versionタグをpushしたので、Cloud Buildに仕込んだトリガーが発動して、ビルド中。
パイプラインの実行を表示
失敗しておるし・・・。
BackendとFrontendそれぞれ同じ理由で失敗している様子。
う〜ん、自分で作ったサンプルアプリでないから、初見でピンと来ない・・・。
とりあえず、Yamlが怪しいので見てみる。。
$ vim k8s/deployments/sample-backend-canary.yaml
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
name: sample-backend-canary
spec:
replicas: 1
template:
metadata:
name: backend
labels:
app: sample
role: backend
env: canary
spec:
containers:
- name: backend
image: gcr.io/[GCPプロジェクトID]/sample-app
resources:
limits:
memory: "500Mi"
cpu: "100m"
imagePullPolicy: Always
readinessProbe:
httpGet:
path: /health
port: 8080
env:
- name: COMPONENT
value: backend
- name: VERSION
value: canary
ports:
- name: backend
containerPort: 8080
あ〜、これかな。
https://github.com/kubernetes/kubernetes/blob/release-1.16/CHANGELOG/CHANGELOG-1.16.md#deprecations-and-removals
k8sのv1.16
以降だとextensions/v1beta1
のAPIは使えない?
たしかに、GKEクラスタのバージョンは 1.16.15 になってる。(このバージョンがk8sのバージョンを表してるのでいいんだっけ・・・?)
で、apps/v1
を使えと書いてあるのでYamlを直してリトライ。
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: k8s/deployments/sample-backend-canary.yaml
modified: k8s/deployments/sample-backend-production.yaml
modified: k8s/deployments/sample-frontend-canary.yaml
modified: k8s/deployments/sample-frontend-production.yaml
以下、修正箇所の抜粋。
kind: Deployment
-apiVersion: extensions/v1beta1
+apiVersion: apps/v1
リポジトリに反映。
$ git add k8s/
$
$ git commit -m "fix apiVersion"
$
$ git push origin master
$
$ git tag -l
v1.0.0
$
$ git tag v1.0.0
fatal: tag 'v1.0.0' already exists
$
$ git tag -d v1.0.0
Deleted tag 'v1.0.0' (was 6d93856)
$
$ git push origin :v1.0.0
To https://source.developers.google.com/p/[GCPプロジェクトID]/r/sample-app
- [deleted] v1.0.0
$
$ git tag v1.0.0
$
$ git tag -l
v1.0.0
$
$ git push --tags
Total 0 (delta 0), reused 0 (delta 0)
To https://source.developers.google.com/p/[GCPプロジェクトID]/r/sample-app
* [new tag] v1.0.0 -> v1.0.0
今度は大丈夫かな。
ダメでした。。。
あ〜、Yamlに selector
が無いぞと。。。
apiVersionは直したけど、それだけじゃなくて修正後のAPIに合わせた要素を用意しないとダメか。。。
単に記事通りにことを進めてというのを試したいだけだったので、だんだん面倒になってきた。。。
が、今回の件で「へ〜、deployment書く際のAPI、v1beta1じゃなくなったんだ!」という(k8sの進化についていけてない)発見があったので、なんとか気を取り直してもう少し頑張ってみる。
以下を参考に、 selector
(だけじゃないけど)を追加してみた。
https://kubernetes.io/ja/docs/concepts/workloads/controllers/deployment/
以下、修正ファイルの1事例。
$ git diff sample-backend-canary.yaml
diff --git a/k8s/deployments/sample-backend-canary.yaml b/k8s/deployments/sample-backend-canary.yaml
index 7a4a0e4..b3a64e7 100644
--- a/k8s/deployments/sample-backend-canary.yaml
+++ b/k8s/deployments/sample-backend-canary.yaml
@@ -1,9 +1,14 @@
-kind: Deployment
apiVersion: apps/v1
+kind: Deployment
metadata:
name: sample-backend-canary
+ labels:
+ app: sample
spec:
replicas: 1
+ selector:
+ matchLabels:
+ app: sample
template:
metadata:
name: backend
さあ、今度はどうだ?
$ git add k8s/
$
$ git commit -m "add selector"
[master 2100afb] add selector
4 files changed, 24 insertions(+), 4 deletions(-)
$
$ git push origin master
Enumerating objects: 14, done.
Counting objects: 100% (14/14), done.
Delta compression using up to 4 threads
Compressing objects: 100% (8/8), done.
Writing objects: 100% (8/8), 782 bytes | 782.00 KiB/s, done.
Total 8 (delta 5), reused 0 (delta 0)
remote: Resolving deltas: 100% (5/5)
To https://source.developers.google.com/p/[GCPプロジェクトID]/r/sample-app
aaf49d9..2100afb master -> master
$
$ git tag -d v1.0.0
Deleted tag 'v1.0.0' (was aaf49d9)
$
$ git push origin :v1.0.0
To https://source.developers.google.com/p/[GCPプロジェクトID]/r/sample-app
- [deleted] v1.0.0
$
$ git tag v1.0.0
$
$ git tag -l
v1.0.0
$
$ git push --tags
Total 0 (delta 0), reused 0 (delta 0)
To https://source.developers.google.com/p/[GCPプロジェクトID]/r/sample-app
* [new tag] v1.0.0 -> v1.0.0
Spinnaker上も、先ほどのように即座に失敗していない。いけるか。
で、真ん中の「Deploy to Production?
」で手動承認の待ち状態となっているので承認すると、いよいよプロダクションへのデプロイが始まる。
INFRASTRUCTURE
->LOAD BALANCERS
の動線から、デプロイした各サービス(CanaryとProductionそれぞれのBackendとFrontend)が確認できる。
あと、Productionの方のFrontendで「DEFAULT
」をクリックすると、
接続可能なIngressのIPが表示されるのでクリップボードにコピーする。
まとめ
ただ記事に書かれている通りにやっただけではあるけど、けっこう時間がかかった。
かかったけど、、こんなポチポチやってるだけでSpinnaker使ったCI/CD環境が出来上がるとは。。。
(いや、もちろん、本当はSpinnakerの仕組みとかも含め、コマンド1つ1つ何が起きてるのかちゃんと理解はしてかないとダメなわけではあるけれど。)
そう思えば、楽・・・なのかな。