Zeals TECH BLOG

チャットボットでネットにおもてなし革命を起こす、チャットコマース『Zeals』を開発する株式会社Zealsの技術やエンジニア文化について発信します。現在本ブログは更新されておりません。新ブログ: https://medium.com/zeals-tech-blog

Redash 分析環境のGKE移設&ver.3から7へのアップデート手順を公開

f:id:zeals-engineer:20191114231808p:plain

こんにちは、分析基盤を担当している鍵本です。
本日は Redash サーバを GKE に移設して序にバージョンアップまでしちゃいました というお話をしようと思います。

背景

Zealsでは、ユーザーの行動ログなどに紐付いた日々のKPIを確認するために Redash を、BizDevのメンバー中心に利用しております。
弊社サービス『Zeals』 は元々Microsoft Azure 上で運用していたため、Redashも当然ながらAzure上に仮想マシンを立てて構築していました。導入は1年半ほど前のことで、バージョンはなんと 3 でした。とても古いですね。

tech.zeals.co.jp

その後ZealsをGCPに移行したことから、「Redash も移行しよう」「序でだからバージョンアップもしよう」という話になりました。
実際の移行作業は2019年10月11日に完了しております。このとき安定版最新バージョンが 7 だったので、一気に 4 ランクアップさせました。

github.com

移設時のポイント

今回の移設作業で注目すべき点は以下の通りです。

  • GCP リソース作成のコード化
  • バージョン管理をしやすくするための GKE 化
  • SSL化

GCP リソース作成のコード化

VPCネットワーク、静的外部IPアドレス、GKEクラスタといった GCP のリソースは一度作った後に触る機会はさほど多くありませんが、冪等性を担保するためにそれらをコード管理するようにしました。

qiita.com

バージョン管理をしやすくするための GKE 化

Redash バージョン4 まではオンプレのサーバーか仮想マシンにインストールすることを想定したスクリプトが用意されていましたが、その後は Docker 上に構築することを前提としたスクリプトに置き換わりましたので、GKE に構築するのが適切ではないかと考えました。

SSL化

Zealsでは、これまでHTTP通信で接続しておりました。KPIに利用するデータの内容はマスキングされたものを利用しているとはいえ、この状態は非常によくありません。そのため、今回のバージョンアップから HTTPS のみのアクセスに変更しております。

移設作業の詳細

GCP リソース作成

以下のリソースを構成管理ツール Pulumi を使って行いました。

  • VPCネットワーク
  • サブネット
  • 静的外部IPアドレス
  • GKEクラスタ
  • DNS (Redash 用の A レコード登録のみ)
  • Cloud Armor

Pulumi のコードについては別の機会にご紹介しようと思います。

www.pulumi.com

GKE 環境への Redash のデプロイ

Redash バージョン 7 の環境を以下の手順に従って GKE に構築します。

マニフェストファイルの作成

スクラッチからマニフェストファイルを作成するのは大変なので、 kompose というツールを使って docker-compose.yml から作成しました。

github.com

バージョン 7 の場合には setup/docker-compose.yml がありますので、まずはこれを用いてローカルのDocker 環境で起動できるように修正しておきます。次にこの docker-conmpose.yml を作業ディレクトリにコピーし、

kompose convert

を実行すると、必要なマニフェストファイルが生成されます。

これをもとにして必要な修正を加えることで、マニフェストファイルの作成コストを最小限にしています。主な修正箇所は以下の通りです。

  • 環境変数を ConfigMap に移動
  • 必要なリソースの定義
  • nginx 用のマニフェストの削除
  • Ingress の追加
  • ManagedCertificate の追加
  • cloud_sql_proxy をサイドカーとして起動する設定を追加
  • cloud_sql_proxy 用 Secret の追加

たとえば IngressManagedCertificate のマニフェストを紹介すると以下のようになります。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress
  namespace: analytics
  annotations:
    kubernetes.io/ingress.global-static-ip-name: [LB用静的外部IP名]
    networking.gke.io/managed-certificates: [ManagedCertificate名]
spec:
  rules:
  - host: [Redash用URL]
    http:
      paths:
      - backend:
          serviceName: [Redashサービス名]
          servicePort: 5000
apiVersion: networking.gke.io/v1beta1
kind: ManagedCertificate
metadata:
  name: [ManagedCertificate名]
spec:
  domains:
  - [Redash用URL]

tech.zeals.co.jp

デプロイ

cloud_sql_proxy 用 Secret ファイルの data には Cloud KMS を利用して暗号化された credential 情報が入っています。このままでは Secret として登録できないので、デプロイ前に復号化しておきます。

kubesec decrypt -i redash/secrets/cloudsql-client-service-account.yaml

あとはマニフェストを適用するだけとなります。

kustomize build redash/overlays/prd | kubectl apply -f -

ここで redash/overlays/prd には production 環境用の kustomization.yaml が配置されており、その中の resources に必要なマニフェストファイルが読み込まれるよう定義されております。

データのリストア

Redash ではバージョンアップをした時にデータを整合的にするためのツールとして manage コマンドを用意してくれています。しかし残念ながらバージョン 3 から 7 へは一気に変換することができませんでした。冷静に考えたら無茶苦茶な話ですよね。そこで以下のように順を追ってやっていくことになりました。

現行サーバのデータ取得

pg_dump コマンドを使って Redash データベースのダンプを取ります。

sudo -u postgres pg_dump redash | gzip -c > redash.dump.gz

ローカルの Docker 環境での起動

ローカルの Docker 環境にバージョン3の環境を作ります。

mkdir -p ~/workspace
cd workspace
git clone -b v3.0.0 https://github.com/getredash/redash.git
cd redash
vi docker-compose.production.yml
diff --git a/docker-compose.production.yml b/docker-compose.production.yml
index f0b9812d..f1b746cd 100644
--- a/docker-compose.production.yml
+++ b/docker-compose.production.yml
@@ -7,7 +7,7 @@
 version: '2'
 services:
   server:
-    image: redash/redash:latest
+    image: redash/redash:3.0.0.b3147
     command: server
     depends_on:
       - postgres
@@ -23,7 +23,7 @@ services:
       REDASH_WEB_WORKERS: 4
     restart: always
   worker:
-    image: redash/redash:latest
+    image: redash/redash:3.0.0.b3147
     command: scheduler
     environment:
       PYTHONUNBUFFERED: 0
@@ -38,8 +38,8 @@ services:
     restart: always
   postgres:
     image: postgres:9.5.6-alpine
-    # volumes:
-    #   - /opt/postgres-data:/var/lib/postgresql/data
+    volumes:
+      - /home/kagimoto/workspace/postgres-data:/var/lib/postgresql/data
     restart: always
   nginx:
     image: redash/nginx:latest
mkdir -p /home/kagimoto/workspace/postgres-data
docker-compose -f docker-compose.production.yml run --rm server create_db
docker-compose -f docker-compose.production.yml up -d

http://localhost/ にアクセスして、Redashのログイン画面が出ることを確認します。

Docker 環境へのリストア

既存のスキーマを一旦削除します。

docker exec -i redash_postgres_1 psql -U postgres -c 'drop schema public cascade; create schema public' 

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

docker exec -it redash_postgres_1 bash
su - postgres
createuser redash --no-superuser --no-createdb --no-createrole
createdb redash --owner=redash
exit
exit

先程取得したデータをリストアします。

zcat ~/tmp/redash.dump.gz | docker exec -i redash_postgres_1 psql -U postgres redash

docker-compose.yml を編集して、現行に合った環境変数を設定し再起動します。

docker stop $(docker ps -q)
docker-compose -f docker-compose.production.yml up -d

RedashのURL を /etc/hosts に 127.0.0.1 として登録し、http://[RedashのURL]/ にアクセスして現行と同じものが表示されることを確認します。

バージョン 4 へのアップグレード

まずローカルリポジトリをアップグレードします。

docker stop $(docker ps -q)
git checkout -b v4.0.0 refs/tags/v4.0.0
vi docker-compose.production.yml

イメージのバージョンを4に変更します(差分はオリジナルからのもので、上記からの追加差分ではありませんのでご注意ください)。

diff --git a/docker-compose.production.yml b/docker-compose.production.yml
index f0b9812d..8358b5f4 100644
--- a/docker-compose.production.yml
+++ b/docker-compose.production.yml
@@ -7,7 +7,7 @@
 version: '2'
 services:
   server:
-    image: redash/redash:latest
+    image: redash/redash:4.0.1.b4038
     command: server
     depends_on:
       - postgres

manage コマンドでデータベースの修正をしてコンテナを起動します。

docker-compose -f docker-compose.production.yml run --rm server manage db upgrade
docker-compose -f docker-compose.production.yml up -d

http://[RedashのURL]/ にアクセスして画面下部に Redash 4.0.1+b4038 と表示され、バージョンが上がっていることを確認します。

バージョン 5 へのアップグレード

同様にローカルリポジトリをアップグレードします。

docker stop $(docker ps -q)
git checkout -b v5.0.0 refs/tags/v5.0.0
vi docker-compose.production.yml

イメージのバージョンを 5 に変更します(差分はオリジナルからのもので、上記からの追加差分ではありませんのでご注意ください)。

diff --git a/docker-compose.production.yml b/docker-compose.production.yml
index f0b9812d..8358b5f4 100644
--- a/docker-compose.production.yml
+++ b/docker-compose.production.yml
@@ -7,7 +7,7 @@
 version: '2'
 services:
   server:
-    image: redash/redash:latest
+    image: redash/redash:5.0.0.b4754
     command: server
     depends_on:
       - postgres

manage コマンドでデータベースの修正をしてコンテナを起動します。

docker-compose -f docker-compose.production.yml run --rm server manage db upgrade
docker-compose -f docker-compose.production.yml up -d

http://[RedashのURL]/ にアクセスして画面下部に Redash 5.0.0+b4754 と表示されていることを確認します。

バージョン 7 へのアップグレード

docker-compose.production.yml を退避して、ローカルレポジトリをアップグレードします。

cp docker-compose.production.yml ../
git checkout docker-compose.production.yml
docker stop $(docker ps -q)
git checkout -b master remotes/origin/master
vi setup/docker-compose.yml

※ 現在は master がバージョン 8 になっているので、v7.0.0 のタグを checkout する必要があります。

diff --git a/setup/docker-compose.yml b/setup/docker-compose.yml
index aea6369b..832b5e45 100644
--- a/setup/docker-compose.yml
+++ b/setup/docker-compose.yml
@@ -4,7 +4,7 @@ x-redash-service: &redash-service
   depends_on:
     - postgres
     - redis
-  env_file: /opt/redash/env
+  env_file: /home/kagimoto/workspace/redash/env
   restart: always
 services:
   server:
@@ -36,10 +36,10 @@ services:
     image: redis:5.0-alpine
     restart: always
   postgres:
-    image: postgres:9.5-alpine
-    env_file: /opt/redash/env
+    image: postgres:9.5.6-alpine
+    env_file: /home/kagimoto/workspace/redash/env
     volumes:
-      - /opt/redash/postgres-data:/var/lib/postgresql/data
+      - /home/kagimoto/workspace/postgres-data:/var/lib/postgresql/data
     restart: always
   nginx:
     image: redash/nginx:latest

env ファイルに必要な環境変数を全て定義しておきます。その後 manage コマンドでデータベースの修正をしてコンテナを起動します。

docker-compose -f setup/docker-compose.yml run --rm server manage db upgrade
docker-compose -f setup/docker-compose.yml up -d

http://[RedashのURL]/ にアクセスして右上のアカウント名をクリックして、メニューの一番下に Version: 7.0.0+b18042 と表示されていることを確認します。

本番環境へのデータ移行

ローカル環境の PostgreSQL サーバから Redash データベースのダンプを取得し、一部内容を修正します。

docker exec -i setup_postgres_1 pg_dump -U postgres redash > redash.dump
sed -e s/redash$/postgres/ -e 's/redash;$/postgres;/' < redash.dump > redash_v7.dump

これは Docker 環境を前提とするバージョン 5 からは、postgres データベースに Redash 用のテーブルを作成し、それに対して postgres ユーザでアクセスするように変更されたからです。上記はダンプデータに含まれているテーブルの所有者情報等を sed で書き換えているというわけです。

本番にリストアします。

kubectl exec -it --namespace=analytics $(basename $(kubectl get pod -o name -n analytics -l 'io.kompose.service==postgres')) -- psql -U postgres -c 'drop schema public cascade; create schema public'
cat redash_v7.dump | kubectl exec -it --namespace=analytics $(basename $(kubectl get pod -o name -n analytics -l 'io.kompose.service==postgres')) -- psql -U postgres postgres

/etc/hosts に登録した RedashのURL を削除し、 http://[RedashのURL]/ にアクセスして、先程ローカル環境で確認した状態と同じものが見えることを確認します。

移行後に発覚した問題

日本語での検索

バージョン 7 に移行してみたところ、検索窓でクエリやダッシュボードを日本語で検索しても想定した検索結果が得られないことがわかりました。これはバージョン 8 で修正されたようです。この記事を執筆中に正式リリースされたようなので、すぐにアップデートしようと思います。

クエリの進捗状況

バージョン 3 の場合には、誰の実行した adhoc クエリが実行中で、誰のが待ち状態なのかが管理画面からわかったのですが、どのバージョンからかはわかりませんが、そのような情報が得られなくなったようで管理者としては不便な感じを受けております。もしかしたら何か手立てがあるのかもしれません。ご存じの方がいらっしゃったら教えて下さい...!!

まとめ

今回は Redash を GKE 環境に移行し、バージョンアップしたというお話を紹介しました。定期的にバージョンアップをしていかないと、あとで苦労する ことを思い知らされた感じがします。でも GKE に移行したので、今後は気軽にバージョンアップできるんじゃないかと(勝手に)期待しています。

最後に

Zeals ではAI開発を加速させるのに必要なデータ基盤の構築を手伝ってくれるエンジニアを募集しております。ご興味がある方は、ぜひ下記募集からご応募ください。お待ちしております。

hrmos.co