6
0

More than 1 year has passed since last update.

KubernetesでCloud Spanner Emulatorを用いたローカル開発環境を構築する

Last updated at Posted at 2021-12-21

この投稿はグレンジ Advent Calendar 2021の21日目の記事です。

Cloud Spanner Emulatorを利用して、Kubernetes上でローカル開発環境を構築します。

appコンテナからspannerコンテナへ接続するサンプルを作ってみます。
環境はHelmを使って構築していきます。

イメージ作成

Go、gcloud、spanner-cliを利用できるようにします。

build/app/Dockerfile
FROM golang:1.17.5-buster

# https://cloud.google.com/sdk/docs/quickstart-debian-ubuntu?hl=ja
RUN echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] http://packages.cloud.google.com/apt cloud-sdk main" | \
        tee -a /etc/apt/sources.list.d/google-cloud-sdk.list && \
    curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | \
        apt-key --keyring /usr/share/keyrings/cloud.google.gpg add - && \
    apt-get update -y && \
    apt-get install google-cloud-sdk -y

# https://github.com/cloudspannerecosystem/spanner-cli/releases
RUN go install github.com/cloudspannerecosystem/spanner-cli@v0.9.9
$ docker build -t app:1.0.0 build/app

Helmで環境作成

values.yaml

deployments/helm/local/values.yaml
gcloud:
  config:
    name: local

app:
  image:
    repository: app
    tag: 1.0.0

spanner:
  image:
    repository: gcr.io/cloud-spanner-emulator/emulator
    tag: 1.4.0
  ports:
    grpc:
      port: 9010
      targetPort: 9010
      protocol: TCP
    rest:
      port: 9020
      targetPort: 9020
      protocol: TCP
  instance:
    id: sample-instance
  database:
    id: sample-database

spanner

deployments/helm/local/templates/spanner-service.yaml
---
apiVersion: v1
kind: Service
metadata:
  name: spanner-service
  labels:
    app: spanner
spec:
  type: NodePort
  ports:
  {{- range $key, $value := .Values.spanner.ports }}
  - name: {{ $key }}
    port: {{ $value.port }}
    targetPort: {{ $value.targetPort }}
    protocol: {{ $value.protocol }}
  {{- end }}
  selector:
    app: spanner
deployments/helm/local/templates/spanner-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: spanner
spec:
  selector:
    matchLabels:
      app: spanner
  replicas: 1
  template:
    metadata:
      labels:
        app: spanner
    spec:
      containers:
        - name: spanner
          image: "{{ .Values.spanner.image.repository }}:{{ .Values.spanner.image.tag }}"
          ports:
            - containerPort: {{ .Values.spanner.ports.grpc.port }}
            - containerPort: {{ .Values.spanner.ports.rest.port }}

app

deployments/helm/local/templates/app-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app
spec:
  selector:
    matchLabels:
      app: app
  replicas: 1
  template:
    metadata:
      labels:
        app: app
    spec:
      containers:
        - name: app
          image: "{{ .Values.app.image.repository }}:{{ .Values.app.image.tag }}"
          workingDir: /app
          env:
            - name: SPANNER_EMULATOR_HOST
              value: "spanner-service:{{ .Values.spanner.ports.grpc.port }}"
            - name: GCLOUD_PROJECT
              value: {{ .Values.gcloud.config.name }}
            - name: SPANNER_PROJECT_ID
              value: {{ .Values.gcloud.config.name }}
            - name: SPANNER_INSTANCE_ID
              value: {{ .Values.spanner.instance.id }}
            - name: SPANNER_DATABASE_ID
              value: {{ .Values.spanner.database.id }}
          command:
            - sleep
            - infinity
          lifecycle:
            postStart:
              exec:
                command:
                  - "sh"
                  - "-c"
                  - |
                    gcloud config configurations create {{ .Values.gcloud.config.name }}
                    gcloud config set auth/disable_credentials true
                    gcloud config set project {{ .Values.gcloud.config.name }}
                    gcloud config set api_endpoint_overrides/spanner http://spanner-service:{{ .Values.spanner.ports.rest.port }}/

Spannerで利用する各種環境変数の設定とgcloudの設定コマンドを実行するようにしています。

インストール

$ helm install local deployments/helm/local

初期設定

appコンテナに接続します。

$ kubectl exec -it deploy/app -- bash

インスタンスを作成します。

# gcloud spanner instances create ${SPANNER_INSTANCE_ID} --config spanner-emulator --description "${SPANNER_INSTANCE_ID}" --nodes=1
Creating instance...done.                                                                                                                                                                                                                                    

データベースを作成します。

# gcloud spanner databases create ${SPANNER_DATABASE_ID} --instance ${SPANNER_INSTANCE_ID}
Creating database...done.                                                                                                                                                                                                                                    

確認

spanner-cliで接続します。

# spanner-cli
Connected.

テーブルを作成します。

spanner> CREATE TABLE Singers (
      ->     SingerId   INT64 NOT NULL,
      ->     FirstName  STRING(1024),
      ->     LastName   STRING(1024),
      ->     SingerInfo BYTES(MAX)
      -> ) PRIMARY KEY (SingerId);
Query OK, 0 rows affected (0.00 sec)

spanner> CREATE TABLE Albums (
      ->     SingerId     INT64 NOT NULL,
      ->     AlbumId      INT64 NOT NULL,
      ->     AlbumTitle   STRING(MAX)
      -> ) PRIMARY KEY (SingerId, AlbumId),
      -> INTERLEAVE IN PARENT Singers ON DELETE CASCADE;
Query OK, 0 rows affected (0.00 sec)

Goクライアントで接続します。

spanner_snippetsを使って書き込み、読み込みをします。

# git clone https://github.com/GoogleCloudPlatform/golang-samples.git
# cd golang-samples/spanner/spanner_snippets/

テーブルに書き込みをします。

# go run snippet.go write projects/${SPANNER_PROJECT_ID}/instances/${SPANNER_INSTANCE_ID}/databases/${SPANNER_DATABASE_ID}

テーブルから読み込みをします。

# go run snippet.go query projects/${SPANNER_PROJECT_ID}/instances/${SPANNER_INSTANCE_ID}/databases/${SPANNER_DATABASE_ID}
1 2 Go, Go, Go
2 2 Forever Hold Your Peace
1 1 Total Junk
2 1 Green
2 3 Terrified

Kubernetes環境にて、Cloud Spanner Emulatorにspanner-cliとGoクライアントで接続できることが確認できました。

参考

6
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
0