Google Container Engine で動作する Spring Boot アプリケーションと Google Cloud SQL との連携

スポンサーリンク

GCP! GCP!

前置き

Cloud SDK や Cloud SQL についてはこちら。
Google Compute Engine で動作する Spring Boot アプリケーションと Google Cloud SQL との連携

Docker イメージの登録

MySQL と連携する Spring Boot アプリケーションを準備しておきます。application.yml は下記のような感じ。

---
spring:
  profiles: gke
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/spring_boot_gcp
    username: user
    password: user1234
  jpa:
    hibernate:
      ddl-auto: create-drop
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQL5InnoDBDialect
  thymeleaf:
    cache: false
    mode: HTML
  messages:
    basename: i18n/messages

また、Dockerfile は下記のような感じ。

FROM ubuntu:16.04
MAINTAINER hirooka
RUN apt-get update
RUN apt-get -y install openjdk-8-jdk
ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64
ADD spring-boot-gcp-1.0.0-SNAPSHOT.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","-Dspring.profiles.active=gke","/app.jar"]

Google Cloud Platform のプロジェクト ID を PROJECT_ID とします。

Spring Boot アプリケーションをビルドし、Docker イメージをビルドし、gcloud で docker push します。

export PROJECT_ID=xxx
cp ./build/libs/spring-boot-gcp-1.0.0-SNAPSHOT.jar ./gcp/gke/
docker build --tag=gcr.io/$PROJECT_ID/spring-boot-gcp:1.0.0-SNAPSHOT ./gcp/gke/
gcloud docker -- push gcr.io/$PROJECT_ID/spring-boot-gcp:1.0.0-SNAPSHOT

Google Cloud Platform の Container Registry に Docker イメージが登録されます。

Container Engine

まず、gcloud で kubectl をインストールしておきます。

gcloud components install kubectl

クラスターを作成します。

gcloud container clusters create example-cluster

結果、Compute Engine のインスタンスが 3 つ作成されます。

Creating cluster example-cluster...done.                                                                                                                   
Created 
https://container.googleapis.com/v1/projects/xxx/zones/asia-northeast1-a/clusters/example-cluster
. kubeconfig entry generated for example-cluster. NAME ZONE MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS example-cluster asia-northeast1-a 1.6.4 x.x.x.x n1-standard-1 1.6.4 3 RUNNING

サービスアカウント

Google Cloud Platform の「IAM と管理」で、サービスアカウントを作成します。サービスアカウント名を適当に設定し、役割として「Cloud SQL」の「Client 編集者」と設定します。「新しい秘密鍵の提供」にチェックを入れ、JSON を設定して作成すると JSON ファイルがダウンロードされます。

アプリケーションが Cloud SQL インスタンスに接続できるようするための cloudsql-instance-credentials シークレットを作成します。ダウンロードした JSON ファイルを使用します。

kubectl create secret generic cloudsql-instance-credentials --from-file=credentials.json=xxx.json

アプリケーションがデータベースに接続できるようにするための cloudsql-db-credentials シークレットを作成します。ユーザー名とパスワードは、データベースに接続するためのものを設定します。

kubectl create secret generic cloudsql-db-credentials --from-literal=username=user --from-literal=password=user1234

アプリケーションのコンテナと Cloud SQL Proxy のコンテナの 2 つをデプロイします。デプロイのためのファイルは下記のような感じ。

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: spring-boot-gcp
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: spring-boot-gcp
    spec:
      containers:
        - image: gcr.io/xxx/spring-boot-gcp:1.0.0-SNAPSHOT
          name: spring-boot-gcp
          ports:
            - containerPort: 8080
              name: spring-boot-gcp
        - image: gcr.io/cloudsql-docker/gce-proxy:1.09
          name: cloudsql-proxy
          command: ["/cloud_sql_proxy", "--dir=/cloudsql",
                    "-instances=xxx:asia-northeast1:spring-boot-gcp=tcp:3306",
                    "-credential_file=/secrets/cloudsql/credentials.json"]
          volumeMounts:
            - name: cloudsql-instance-credentials
              mountPath: /secrets/cloudsql
              readOnly: true
            - name: ssl-certs
              mountPath: /etc/ssl/certs
            - name: cloudsql
              mountPath: /cloudsql
      volumes:
        - name: cloudsql-instance-credentials
          secret:
            secretName: cloudsql-instance-credentials
        - name: ssl-certs
          hostPath:
            path: /etc/ssl/certs
        - name: cloudsql
          emptyDir:

実際にデプロイします。

kubectl create -f deployment.yml

ポッドの状態を確認します。

kubectl get pods

結果、

NAME                               READY     STATUS    RESTARTS   AGE
spring-boot-gcp-3918467617-89xbq   2/2       Running   0          40s

ポッドをパブリックに公開します。

kubectl expose deployment spring-boot-gcp --type="LoadBalancer"

IP アドレスを確認します。

kubectl get services

結果、

NAME              CLUSTER-IP      EXTERNAL-IP      PORT(S)          AGE
...
spring-boot-gcp   10.xx.xx.xx   xx.xx.xx.xx   8080:30623/TCP   46s

EXTERNAL-IP の TCP:8080 に接続して Spring Boot アプリケーションが動作していれば OK です。

おわりに

クラスターを稼働させておくと Compute Engine のインスタンスが 3 つ稼働してお金がかかるので最後に削除しておきます。

kubectl delete services spring-boot-gcp
kubectl delete deployment spring-boot-gcp
gcloud container clusters delete example-cluster