GKE Config Connectorを試す

#はじめに

GCPのリソースを、kubernetesのyamlファイルのコンフィグレーションで作成でいるAddon機能です。
https://cloud.google.com/config-connector/docs/overview

触ったことなかったので試してみます。

##Config Connectorのインストール
まずは、AddonであるConfig Connectorをインストールします。
https://cloud.google.com/config-connector/docs/how-to/install-upgrade-uninstall

GCP Identity、Workload　Identity、Namespace Modeの３種類から選択できますが、ここでは、GCP Identityで構築します。

まずは、KubernetesのRoleが作成できる権限があるかを確認します。

```
$ kubectl auth can-i create roles
yes
```

yesと表示されればOKです。

ClusterRoleBindingを作成します。自身のGoogleアカウントにCluster adminの権限を紐付けます。

```
$ kubectl create clusterrolebinding cluster-admin-binding \
> --clusterrole cluster-admin \
> --user <Google Account>
clusterrolebinding.rbac.authorization.k8s.io/cluster-admin-binding created
```

cnrm-systemという名前でGCPのサービスアカウント(GSA)を作成します。

```
gcloud iam service-accounts create cnrm-system
```

作成したGSAにroles/ownerを追加します。

```
$ gcloud projects add-iam-policy-binding <Project ID> \
> --member serviceAccount:cnrm-system@<Project ID>.iam.gserviceaccount.com \
> --role roles/owner
Updated IAM policy for project [<Project ID>].
bindings:
- members:
-略-
```

GSAのキーを作成します。

```
$ gcloud iam service-accounts keys create --iam-account \
> cnrm-system@<Project ID>.iam.gserviceaccount.com key.json
created key [36877b24272f694f8fa7a56babf3fd4363748dfe] of type [json] as [key.json] for [cnrm-system@<Project ID>.iam.gserviceaccount.com]
```

###作成したGSAのキーをKubernetesにApplyします。

Config Connectorが起動するネームスペースを作成します。

```
$ kubectl create namespace cnrm-system
namespace/cnrm-system created
```

先程作成した、GSAのキーを元にsecretを作成します。

```
$ kubectl create secret generic gcp-key --from-file key.json --namespace cnrm-system
secret/gcp-key created
```

###Installing Config Connector

インストール用のファイルをダウンロードします。

```
$ gsutil cp gs://cnrm/latest/release-bundle.tar.gz release-bundle.tar.gz
Copying gs://cnrm/latest/release-bundle.tar.gz...
- [1 files][281.1 KiB/281.1 KiB]
Operation completed over 1 objects/281.1 KiB.
```

解凍します。

```
$ tar zxvf release-bundle.tar.gz
./
./install-bundle-gcp-identity/
./install-bundle-gcp-identity/crds.yaml
./install-bundle-gcp-identity/0-cnrm-system.yaml
```

インストールします。

```
$ kubectl apply -f install-bundle-gcp-identity/
Warning: kubectl apply should be used on resource created by either kubectl create --save-config or kubectl apply
namespace/cnrm-system configured
serviceaccount/cnrm-controller-manager created
serviceaccount/cnrm-resource-stats-recorder created
serviceaccount/cnrm-webhook-manager created
clusterrole.rbac.authorization.k8s.io/cnrm-admin create
```

インストールを確認します。「pod/cnrm-controller-manager-0 condition met」と表示されればOKです。

```
$ kubectl wait -n cnrm-system \
> --for=condition=Initialized pod \
> cnrm-controller-manager-0
pod/cnrm-controller-manager-0 condition met
```

#Spannerのインスタンスを作成してみます。
https://cloud.google.com/config-connector/docs/how-to/getting-started

SpannerのAPIを有効にします。

```
gcloud services enable spanner.googleapis.com
```

Project IDと同じ名前のネームスペースを作成します。kubectl applyするときにネームスペースとしてProject IDを指定すると、指定したProject IDにGCPリソースが作成されます。

```
$ kubectl create namespace <Project ID>
namespace/<Project ID> created
```

yamlファイル作成します。

```
$ cat spanner.yaml
apiVersion: spanner.cnrm.cloud.google.com/v1beta1
kind: SpannerInstance
metadata:
  labels:
    label-one: "value-one"
  name: spannerinstance-sample
spec:
  config: regional-us-west1
  displayName: Spanner Instance Sample
  numNodes: 1
```

applyします。

```
$ kubectl apply  -f spanner.yaml -n <Project ID>
spannerinstance.spanner.cnrm.cloud.google.com/spannerinstance-sample created
```

Spannerのインスタンスが作成されます。

```
$ k describe spannerinstances.spanner.cnrm.cloud.google.com -n <Project ID> spannerinstance-sample
Name:         spannerinstance-sample
Namespace:    <Project ID>
Labels:       cnrm-lease-expiration=1583225409
              cnrm-lease-holder-id=bpf0oacinp3ib218id80
              label-one=value-one
Annotations:  cnrm.cloud.google.com/management-conflict-prevention-policy: resource
              cnrm.cloud.google.com/project-id: <Project ID>
              kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"spanner.cnrm.cloud.google.com/v1beta1","kind":"SpannerInstance","metadata":{"annotations":{},"labels":{"label-one":"value-o...
API Version:  spanner.cnrm.cloud.google.com/v1beta1
Kind:         SpannerInstance
Metadata:
  Creation Timestamp:  2020-03-03T07:50:00Z
  Finalizers:
    cnrm.cloud.google.com/finalizer
  Generation:        5
  Resource Version:  1395215
  Self Link:         /apis/spanner.cnrm.cloud.google.com/v1beta1/namespaces/<Project ID>/spannerinstances/spannerinstance-sample
  UID:               95c57ebd-5d23-11ea-bbb1-42010a80012b
Spec:
  Config:        regional-us-west1
  Display Name:  Spanner Instance Sample
  Num Nodes:     1
Status:
  Conditions:
    Last Transition Time:  2020-03-03T08:10:09Z
    Message:               The resource is up to date
    Reason:                UpToDate
    Status:                True
    Type:                  Ready
  State:                   READY
Events:
  Type    Reason    Age                  From                        Message
  ----    ------    ----                 ----                        -------
  Normal  Updating  4m12s (x2 over 24m)  spannerinstance-controller  Update in progress
  Normal  UpToDate  4m12s (x2 over 24m)  spannerinstance-controller  The resource is up to date
```

gcloudコマンドでも確認できます。

```
$ gcloud spanner instances list
NAME                    DISPLAY_NAME             CONFIG             NODE_COUNT  STATE
spannerinstance-sample  Spanner Instance Sample  regional-us-west1  1           READY
```

#落ち穂拾い

Project IDではない適当なネームスペースを作成して、Spannerのインスタンスを作成するとProject IDが違うため、Permmison Errorになります。

```
$ k create ns test-ns
namespace/test-ns created
```

```
$ k apply -f spanner.yaml -n test-ns
spannerinstance.spanner.cnrm.cloud.google.com/spannerinstance-sample created
```

ネームスペースが「Namespace:    test-ns」になってます。

```
k describe spannerinstance.spanner.cnrm.cloud.google.com/spannerinstance-sample  -n test-ns
Name:         spannerinstance-sample
Namespace:    test-ns
Labels:       label-one=value-one
Annotations:  cnrm.cloud.google.com/management-conflict-prevention-policy: resource
              cnrm.cloud.google.com/project-id: test-ns
              kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"spanner.cnrm.cloud.google.com/v1beta1","kind":"SpannerInstance","metadata":{"annotations":{},"labels":{"label-one":"value-o...
API Version:  spanner.cnrm.cloud.google.com/v1beta1
Kind:         SpannerInstance
Metadata:
  Creation Timestamp:  2020-03-03T08:15:47Z
  Generation:          2
  Resource Version:    1396563
  Self Link:           /apis/spanner.cnrm.cloud.google.com/v1beta1/namespaces/test-ns/spannerinstances/spannerinstance-sample
  UID:                 2fc68db6-5d27-11ea-bbb1-42010a80012b
Spec:
  Config:        regional-us-west1
  Display Name:  Spanner Instance Sample
  Num Nodes:     1
Status:
  Conditions:
    Last Transition Time:  2020-03-03T08:15:47Z
    Message:               Update call failed: error fetching live state: error reading underlying resource: Error reading SpannerInstance "test-ns/spannerinstance-sample": googleapi: Error 403: Caller is missing IAM permission spanner.instances.get on resource projects/test-ns/instances/spannerinstance-sample.
    Reason:                UpdateFailed
    Status:                False
    Type:                  Ready
Events:
  Type     Reason        Age                From                        Message
  ----     ------        ----               ----                        -------
  Warning  UpdateFailed  1s (x15 over 87s)  spannerinstance-controller  Update call failed: error fetching live state: error reading underlying resource: Error reading SpannerInstance "test-ns/spannerinstance-sample": googleapi: Error 403: Caller is missing IAM permission spanner.instances.get on resource projects/test-ns/instances/spannerinstance-sample.
```

#投稿内容は私個人の意見であり、所属企業・部門見解を代表するものではありません。