kawabatas技術ブログ

試してみたことを書いていきます

【GKE】Kubernetes Service Catalog を試してみた

概要

Kubernetes Service Catalog と GCP Service Broker を使えば、CloudSQL や CloudStorage などをセットアップできるらしいので、試してみた。

用語説明

ドキュメント

Kubernetes Service Catalog とは

Kubernetes クラスタで動作するアプリケーションが、クラウドプロバイダによって提供されるデータストアサービスなどの外部管理対象ソフトウェアを簡単に使用できるようにする。

Service Broker からの外部マネージドサービスのリスト作成、プロビジョニング、バインドの方法を提供し、これらのサービスの作成方法や管理方法について詳細な知識を必要としない。

Service Broker とは

AWSGCP、Azure などのクラウドプロバイダであるサードパーティによって提供および管理される一連の管理サービスのエンドポイント。

Service Catalog を使用すると、クラスタ・オペレータは、Service Broker によって提供される管理対象サービスのリストをブラウズし、管理対象サービスのインスタンスをプロビジョニングし、バインドして Kubernetes クラスタ内のアプリケーションで使用できるようにできる。

インストール

Installing Service Catalog

Installing the Service Catalog and the Service Broker

Download the Service Catalog installer

https://github.com/GoogleCloudPlatform/k8s-service-catalog

$ go get -u github.com/cloudflare/cfssl/cmd/...

確認

$ which cfssl
/[GOのPATH]/bin/cfssl
$ which cfssljson
/[GOのPATH]/bin/cfssljson
$ go get -u github.com/GoogleCloudPlatform/k8s-service-catalog/installer/cmd/sc

確認

$ sc check
Dependency check passed. You are good to go.

GO言語の知識が必要だった。

Set RBAC Permissions on your cluster

$ kubectl create clusterrolebinding cluster-admin-binding --clusterrole=cluster-admin --user=$(gcloud config get-value account)
$ kubectl get clusterrolebinding
NAME                                                   AGE
cluster-admin                                          76d
cluster-admin-binding                                  20s

自分はオーナー権限持っているので不要だと思ったが、次のsc installでエラーになったので、必要らしい

Install the Service Catalog

$ sc install
Service Catalog installed successfully.
$ kubectl get deployment -n service-catalog
NAME                          DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
apiserver                     1         1         1            0           23s
controller-manager            1         1         1            0           22s
etcd-cluster-backup-sidecar   1         1         1            1           12s
etcd-operator                 1         1         1            1           33s

Register the Service Broker with the Service Catalog

$ gcloud auth application-default login
$ sc add-gcp-broker
The Service Broker has been added successfully.
$ kubectl get clusterservicebrokers
NAME         AGE
gcp-broker   3m

Set the role for the project service account

$ GCP_PROJECT_ID=$(gcloud config get-value project)
$ GCP_PROJECT_NUMBER=$(gcloud projects describe $GCP_PROJECT_ID --format='value(projectNumber)')
$ gcloud projects add-iam-policy-binding ${GCP_PROJECT_ID} \
>     --member serviceAccount:${GCP_PROJECT_NUMBER}@cloudservices.gserviceaccount.com \
>     --role=roles/owner

使用してみる

全て kubectl で試す

Discovering GCP services and plans

List services

$ kubectl -o 'custom-columns=SERVICE-NAME:.metadata.name,SERVICE-EXTERNAL-NAME:.spec.externalName' get clusterserviceclasses
SERVICE-NAME                           SERVICE-EXTERNAL-NAME
4197a602-3eb9-4d40-8e21-0311a7a8eecb   cloud-spanner
5dcd0ba6-8df6-4a2a-b5fd-981d0aa76803   cloud-iam-service-account
6f4e8d17-4fde-45bd-9dcf-28bcb7eeea5c   cloud-pubsub
85c5e53a-d70b-480e-afd3-737b0b1329f3   cloud-sql-mysql
8e0bbfa6-2cac-40b6-8adf-e5ee8dcbe4e8   bigquery
b1de7f2f-1e84-44ae-b4f0-2dcb613c17c9   cloud-bigtable
e9776b6c-4022-41ec-8b83-7c368ed9c270   cloud-storage

cloud memorystore にはまだ対応していないようだ

List service plans

$ kubectl -o 'custom-columns=PLAN-NAME:.metadata.name,PLAN-EXTERNAL-NAME:.spec.externalName,CLASS:.spec.clusterServiceClassRef.name' get clusterserviceplans
PLAN-NAME                              PLAN-EXTERNAL-NAME   CLASS
21198c77-9452-4bf2-8935-babacc8294cb   beta                 4197a602-3eb9-4d40-8e21-0311a7a8eecb
444fe472-aabc-4c8a-a707-1975e2e908c8   beta                 6f4e8d17-4fde-45bd-9dcf-28bcb7eeea5c
7bb7e217-2088-4455-8298-f711b09b1806   beta                 8e0bbfa6-2cac-40b6-8adf-e5ee8dcbe4e8
9f62358e-ffb4-4fc5-b7a5-90462c15ce55   beta                 85c5e53a-d70b-480e-afd3-737b0b1329f3
b8d31ff7-301c-4474-83b0-aba32a0ec2fe   beta                 b1de7f2f-1e84-44ae-b4f0-2dcb613c17c9
c5670b40-4e01-48b8-8acf-d65df714146f   beta                 e9776b6c-4022-41ec-8b83-7c368ed9c270
d6f98382-a101-401f-80df-33afe9c4b5c7   beta                 5dcd0ba6-8df6-4a2a-b5fd-981d0aa76803

View a service plan

$ kubectl get clusterserviceplans 9f62358e-ffb4-4fc5-b7a5-90462c15ce55 -o yaml

結果は省略。ServiceInstance や ServiceBinding の parameters のドキュメントが表示された

Using a GCP Service

CloudSQL を試してみる

https://github.com/GoogleCloudPlatform/kubernetes-engine-samples/tree/master/service-catalog/cloud-sql-mysql

Provision a Cloud SQL instance

apiVersion: servicecatalog.k8s.io/v1beta1
kind: ServiceInstance
metadata:
  name: cloud-sql
  namespace: default
spec:
  clusterServiceClassExternalName: cloud-sql-mysql
  clusterServicePlanExternalName: beta
  parameters:
    instanceId: test
    region: asia-northeast1
    databaseVersion: MYSQL_5_7
    settings:
      tier: db-f1-micro
      databaseFlags:
      - name: character_set_server
        value: utf8mb4

ServiceInstance 作成時に CloudSQLのインスタンスも作成された

※ ServiceInstance を削除すると、ひもづく CloudSQL のインスタンスは削除された

Provision a service account

apiVersion: servicecatalog.k8s.io/v1beta1
kind: ServiceInstance
metadata:
  name: test-cloud-sql-service-account
  namespace: default
spec:
  clusterServiceClassExternalName: cloud-iam-service-account
  clusterServicePlanExternalName: beta
  parameters:
    accountId: test-cloud-sql-service-account
    displayName: "A service account for Cloud SQL sample"

ServiceInstance 作成時に GCP の service-account も作成された

※ ServiceInstance を削除すると、ひもづく service-account は削除された

Create a Binding to the service account Instance

apiVersion: servicecatalog.k8s.io/v1beta1
kind: ServiceBinding
metadata:
  name: test-cloud-sql-service-account
  namespace: default
spec:
  instanceRef:
    name: test-cloud-sql-service-account

Create a Binding to the Cloud SQL Instance

apiVersion: servicecatalog.k8s.io/v1beta1
kind: ServiceBinding
metadata:
  name: cloud-sql
  namespace: default
spec:
  instanceRef:
    name: cloud-sql
  secretName: test-cloudsql-instance-credentials
  parameters:
    roles:
      - roles/cloudsql.client
    serviceAccount: test-cloud-sql-service-account

CloudSQL インスタンスが立ち上がる前に実行するとエラーになる

$ kubectl get serviceinstance
NAME                             AGE
cloud-sql                        2h
test-cloud-sql-service-account   1h
$ kubectl get servicebinding
NAME                             AGE
cloud-sql                        49m
test-cloud-sql-service-account   55m

ServiceBinding 作成時に secret も作成される。

※ ServiceBinding を削除すると、ひもづく secret は削除される

$ kubectl get secret
test-cloud-sql-service-account       Opaque                                2         54m
test-cloudsql-instance-credentials   Opaque                                2         47m

作成した Cloud SQL Instance にユーザ、データベース作成

gcloud sql users create xxx cloudsqlproxy~% -i test
gcloud sql databases create xxx -i test

接続確認

確認に使用した pod の詳細は伏せる

例はこちら

Cloud Storage も試してみた

自身のアカウントで gcloud コマンドでアップデートしたかったので、defaultObjectAcl を設定した

apiVersion: servicecatalog.k8s.io/v1beta1
kind: ServiceInstance
metadata:
  name: cloud-storage
  namespace: default
spec:
  clusterServiceClassExternalName: cloud-storage
  clusterServicePlanExternalName: beta
  parameters:
    bucketId: test
    location: asia-northeast1
    storageClass: REGIONAL
    defaultObjectAcl:
    - entity: project-editors-xxxx
      role: OWNER
    - entity: project-owners-xxxx
      role: OWNER
    - entity: project-viewers-xxxx
      role: READER

バケットに対する権限を追加できなかった

自身のアカウントでオブジェクト一覧を見たかったので、ServiceBinding で作成されたサービスアカウントを使ってバケットの権限を変えるということをした

gcloud auth activate-service-account サービスアカウント --key-file サービスアカウント.json
gsutil iam set バケット権限.txt gs://test

所感

GCP のサービスアカウントを管理できるのは非常に魅力的だと思う。

GCP のリソースの設定値を管理できるのも良い。

しかし、CloudSQL の場合、ユーザ・データベース作成には結局 gcloud コマンドが必要だったり、CloudStorage の場合、バケットに関する権限が設定できないなど、少し惜しいところがある。CloudMemorystore が現在未対応ということもあり、導入するかどうかは一旦保留。