概要
Cloud Storage FUSEを使用して、Google Kubernetes Engine(以下、GKE)で動いてるコンテナ内のディレクトリにGoogle Cloud Storage(以下、GCS)のバケットをマウントすることを目指します。
WordPressのuploadsディレクトリなど、コンテナ間で共有したいリソースがある時に便利です。
GCP側の準備
プロジェクトを作成
コンソール画面などからプロジェクトを作成します。
今回は説明のためexampleというプロジェクト名であると仮定しています。
バケットの作成
Cloud SDKかGCPコンソール画面でバケットを作成します。
バケット名やプロジェクト名は他ユーザも含めて全プロジェクトでユニークなので、
名前が被った場合は違うバケット名を試してください。
クラスタ作成
コマンドで作成を行います。
重要なのは--scopesオプションで、必ずstorage-rwかstorage-fullを指定してください。
他のオプションはお好みで大丈夫です。
$ gcloud container clusters create example-cluster \
--machine-type f1-micro \
--scopes storage-full
Cloud Storage FUSEのインストール
ベースイメージを元に、FUSEがインストールされたイメージを作っていきます。
基本的には公式ドキュメントの手順に従って準備をしていきます。
ベースイメージ
今回は例としてphp:5.6-apacheを使用します。
他のイメージを使用する場合は、コマンドが異なる場合がございますのでご注意ください。
ベースイメージOSのバージョン名を確認
公式ドキュメントの通り、lsb_releaseコマンドを使用してOSバージョン名を確認します。
# docker run -it php:5.6-apache /bin/bash
# apt-get install -y lsb-release
# lsb_release -c -s
jessie
Apacheのユーザ名を確認
Apacheのユーザ名(=FUSEを使用するユーザ名)を確認します。
 .
 .
 .
# These need to be set in /etc/apache2/envvars
User ${APACHE_RUN_USER}
Group ${APACHE_RUN_GROUP}
 .
 .
 .
/etc/apache2/envvarsで定義されている環境変数が指定されているようですので、コメントに書いてあるファイルを確認します。
 .
 .
 .
: ${APACHE_RUN_USER:=www-data}
export APACHE_RUN_USER
: ${APACHE_RUN_GROUP:=www-data}
export APACHE_RUN_GROUP
 .
 .
 .
Apacheのユーザはwww-dataであることがわかりました。
Dockerfileを用意する
gcsfuseのパッケージURLを指定する際に、先程確認したOSバージョン名を使用します。
後ほどApacheユーザーでFUSEを使用するため、sudoもインストールしておきます。
私はvimをApacheの設定を確認するためにインストールしていますが、必須ではございません。
また、fuseグループを作成し、apacheのユーザをfuseグループに追加します。
末尾ではENTRYPOINTを指定しています。
ここで実行するスクリプトの詳細は後述します。
FROM php:5.6-apache
WORKDIR /path/to/DocumentRoot
# gcsfuse-[バージョン名]を指定する
RUN echo "deb http://packages.cloud.google.com/apt gcsfuse-jessie main" | tee /etc/apt/sources.list.d/gcsfuse.list
RUN curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
RUN groupadd fuse
RUN usermod -aG fuse www-data
RUN apt-get update -y && apt-get install -y \
    gcsfuse \
    sudo \
    vim
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod a+x /usr/local/bin/entrypoint.sh
EXPOSE 80 443
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
ENTRYPOINTを指定
この例では、ドキュメントルートをGCSにマウントしていますが、他のディレクトリでももちろん構いません。
Apacheユーザとして、gcsfuseコマンドを実行しないと、ページにアクセスした際に、403エラーが出てしまう可能性があります。
# !/bin/bash
source /etc/apache2/envvars
chown -R www-data:www-data *
sudo -u www-data gcsfuse example-bucket ./
exec apache2 -D FOREGROUND
イメージファイルのビルド・プッシュ
イメージをビルドし、GCPのContainer Registryにプッシュします。
docker build -f ./Dockerfile -t example_image:0.0.0 .
docker tag example_image:0.0.0 gcr.io/example/example_image:0.0.0
gcloud docker -- push gcr.io/example/example_image:0.0.0
k8sの設定ファイルを用意
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: example
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: example
        tier: frontend
        environment : production
    spec:
      containers:
        - image: gcr.io/example/example_image:0.0.0
          imagePullPolicy: Always
          name: example
          ports:
            - containerPort: 80
              name: example
          securityContext:
            privileged: true
---
apiVersion: v1
kind: Service
metadata:
  name: example
  labels:
    app: example
spec:
  selector:
    app: example
    tier: frontend
    environment : production
  type: LoadBalancer
  ports:
    - port: 80
      protocol: TCP
      targetPort: 80
GKEにデプロイする
$ gcloud container clusters get-credentials example-cluster --project example
$ kubectl create -f example.yaml
GKEクラスタに接続して外部IPを確認
$ kubectl get svc example
上のコマンドを実行することで表示されるEXTERNAL IPを確認します。
確認
GCSにindex.htmlをアップし、ブラウザからhttp://[確認したEXTERNAL IP]/にアクセスします。
アップした内容が表示されたら成功です。
なお、GKEにデプロイするのに少し時間がかかる(イメージのプル時間とエントリポイントの実行時間)ため、表示されない場合は少し時間を置いてからアクセスしましょう。