この投稿はグレンジ 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クライアントで接続できることが確認できました。
参考
- Cloud Spanner Emulator
- Cloud SDK