GKE中のGolangアプリケーション、gsutilを使ってCloud Storageでデータ連携を行う

GKEの中に稼働されるアプリケーションからどうやってGCPサービスにアクセスしたり、データ連携したりするか?という疑問がある方々に回答する記事をまとめました。
今回はCloud Storageサービスを使って、データ連携サンプルとして作成しました。

APIを利用して、Cloud Storage上のデータファイルと遣り取り方法があります。この方法の利点は処理スピードが良いことです。
但し、エラーハンドリングや処理ロジックなどを全て実装しないといけない。

それより簡単な方法はgsutilツールを使ってCloud Storageと遣り取りする方法があります。
gsutil は、コマンドラインから Cloud Storage にアクセスできる Python アプリケーションです。
Cloud Storageと遣り取り専用の正式なツールです。
gsutil を使用すると、次のような、バケットやオブジェクトの幅広い管理作業を行うことができます。

  • バケットの作成と削除
  • オブジェクトのアップロード、ダウンロード、削除
  • バケットとオブジェクトの一覧表示
  • オブジェクトの移動、コピー、名前変更
  • オブジェクトやバケットの ACL の編集
  • エラーハンドリングや平行

この記事はGKEにデプロイするアプリケーションはgsutilを利用するため、実装方法をサンプルとして紹介したいと思っています。

ローカル環境でこの流れを実施したら、gsutilを使えるようになります。

グーグルクラウドに接続するため、ログインを行います。
gcloud auth login

作業対象のプロジェクトを設定
gcloud config set project [PROJECT_ID]

この状態で、gsutilを使う可能となります。例えば、ストレージのバケツを全て表示するコマンド
gsutil ls -r gs://[BUCKET_NAME]

GKE中のアプリケーションの場合どうなるか?
回答は基本的にこの流れと同じです。但し、実装方法は違い点があります。
次、各項目で実装方法を紹介いたします。

2. グーグルクラウドに接続ための設定

サービスカウントを使って接続します。

まず、サービスカウント作成と接続用のaccount.jsonファイル発行を行います。
詳細の実施方法はこの記事の「サービスアカウント作成&アクセス用のaccount.jsonファイル発行
で書いていますので、ご参照をお願いします。

それから、account.jsonファイルを使ってグーグルクラウドに接続設定はこのコマンドで実施

gcloud auth activate-service-account --key-file=[ACOUNT_JSON_FILE_PATH]

3. サンプルのアプリケーション実装

下記2つ機能のアプリケーションを実装に行きます。

  • ファイル名とテキスト内容を指定してファイルをCloud Storageのバケツ中に作成する。
  • バケツ中のファイルを全てリストする。

golangとechoフレームワークを使います。

プログラムからグーグルクラウドに接続設定

execパケージを使って、gcloudツールで接続を行います。
md := exec.Command("gcloud", "auth", "activate-service-account", "--key-file="+serviceAccountKeyFile)
_, err := cmd.CombinedOutput()
if err != nil {
    return err
}

cmd = exec.Command("gcloud", "config", "set", "project", projectID)
_, err = cmd.CombinedOutput()
if err != nil {
    return err
}

ストレージのバケツにファイル作成

ioutil.TempFileで一時的にファイルを作成します。
tmpfile, err := ioutil.TempFile("", storegeFile.FileName)
if err != nil {
    return err
}
defer os.Remove(tmpfile.Name()) // clean up

if _, err := tmpfile.Write([]byte(storegeFile.Content)); err != nil {
    return err
}
if err := tmpfile.Close(); err != nil {
    return err
}

それから、gsutilでバケツにコピーします。

cmd := exec.Command("gsutil", "cp", tmpfile.Name(), storageBacketName+"/"+storegeFile.FileName)
_, err = cmd.CombinedOutput()
if err != nil {
    return err
}

ストレージのバケツのファイルを全て表示

cmd := exec.Command("gsutil", "ls", "-r", storageBacketName)
out, err := cmd.CombinedOutput()
if err != nil {
    return err
}

4. ビルド&デプロイ

Dockerイメージ

gcloudとgsutilを使うため、Dockerイメージはgoogle/cloud-sdkを使います。
alpineを使ってイメージのサイズを最低化とします。

FROM google/cloud-sdk:alpine
WORKDIR /app
COPY ./sample_app /app

ENTRYPOINT ["./sample_app"]

ビルド&デプロイ

手順まとめ
# グーグルクラウドのContainer Registryにイメージビルド
gcloud builds submit --config cloudbuild.sampleapp.yaml

# GKEのクラスタにアクセスするため、credentialsを設定
gcloud container clusters get-credentials --zone asia-northeast1-b ds-gke-small-cluster

# サービスアカウントJSONファイルを利用するため、secretボリュームを作成
kubectl create secret generic service-account-credential \
     --from-file=./secret/account.json

# アプリケーションをGKEにデプロイする
kubectl apply -f deployment.sampleapp.yaml

デプロイ後、GKE中のアプリケーションを確認

EndpointsのIPをメモして、アプリケーションにアクセスと稼働検証します。

本記事の利用ソースコードはこちら

https://github.com/itdevsamurai/gke/tree/master/usegsutil

最後まで読んで頂き、どうも有難う御座います。!

DevSamurai 橋本

弊社はGoogle Cloud Platform (GCP)のパートナーとして、製品導入やクラウドに移行、アーキテクチャ設計、システム開発などのサービスを提供しております。