こんにちは、分析基盤を担当している鍵本です。
本日は Redash サーバを GKE に移設して序にバージョンアップまでしちゃいました というお話をしようと思います。
背景
Zealsでは、ユーザーの行動ログなどに紐付いた日々のKPIを確認するために Redash を、BizDevのメンバー中心に利用しております。
弊社サービス『Zeals』 は元々Microsoft Azure 上で運用していたため、Redashも当然ながらAzure上に仮想マシンを立てて構築していました。導入は1年半ほど前のことで、バージョンはなんと 3 でした。とても古いですね。
その後ZealsをGCPに移行したことから、「Redash も移行しよう」「序でだからバージョンアップもしよう」という話になりました。
実際の移行作業は2019年10月11日に完了しております。このとき安定版最新バージョンが 7 だったので、一気に 4 ランクアップさせました。
移設時のポイント
今回の移設作業で注目すべき点は以下の通りです。
- GCP リソース作成のコード化
- バージョン管理をしやすくするための GKE 化
- SSL化
GCP リソース作成のコード化
VPCネットワーク、静的外部IPアドレス、GKEクラスタといった GCP のリソースは一度作った後に触る機会はさほど多くありませんが、冪等性を担保するためにそれらをコード管理するようにしました。
バージョン管理をしやすくするための GKE 化
Redash バージョン4 まではオンプレのサーバーか仮想マシンにインストールすることを想定したスクリプトが用意されていましたが、その後は Docker 上に構築することを前提としたスクリプトに置き換わりましたので、GKE に構築するのが適切ではないかと考えました。
SSL化
Zealsでは、これまでHTTP通信で接続しておりました。KPIに利用するデータの内容はマスキングされたものを利用しているとはいえ、この状態は非常によくありません。そのため、今回のバージョンアップから HTTPS のみのアクセスに変更しております。
移設作業の詳細
GCP リソース作成
以下のリソースを構成管理ツール Pulumi を使って行いました。
- VPCネットワーク
- サブネット
- 静的外部IPアドレス
- GKEクラスタ
- DNS (Redash 用の A レコード登録のみ)
- Cloud Armor
Pulumi のコードについては別の機会にご紹介しようと思います。
GKE 環境への Redash のデプロイ
Redash バージョン 7 の環境を以下の手順に従って GKE に構築します。
マニフェストファイルの作成
スクラッチからマニフェストファイルを作成するのは大変なので、 kompose
というツールを使って docker-compose.yml から作成しました。
バージョン 7 の場合には setup/docker-compose.yml
がありますので、まずはこれを用いてローカルのDocker 環境で起動できるように修正しておきます。次にこの docker-conmpose.yml を作業ディレクトリにコピーし、
kompose convert
を実行すると、必要なマニフェストファイルが生成されます。
これをもとにして必要な修正を加えることで、マニフェストファイルの作成コストを最小限にしています。主な修正箇所は以下の通りです。
- 環境変数を ConfigMap に移動
- 必要なリソースの定義
- nginx 用のマニフェストの削除
- Ingress の追加
- ManagedCertificate の追加
- cloud_sql_proxy をサイドカーとして起動する設定を追加
- cloud_sql_proxy 用 Secret の追加
たとえば IngressとManagedCertificate のマニフェストを紹介すると以下のようになります。
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]
デプロイ
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開発を加速させるのに必要なデータ基盤の構築を手伝ってくれるエンジニアを募集しております。ご興味がある方は、ぜひ下記募集からご応募ください。お待ちしております。