移行無事完了した😇
Data Sourcesだけエラー出たけど、v7からv8は
REDASH_COOKIE_SECRETを移行元からコピペして
REDASH_SECRET_KEYがいらなくなったのか〜
とりあえずお疲れさん💪 https://t.co/gQ2ofdC1iV— adachin👾SRE (@adachin0817) August 26, 2020
今回社内で利用しているRedashサーバーをDockerに移行したので、軽く移行する際に気をつけることをまとめていきたいと思います。そもそもECS/Fargateに移行しようともろもろ調べた結果、簡単にはできなさそうな印象を受けたこともあり、早くv8の新機能であるカスタムアラート機能を試したい!ということから、Docker on EC2にしました。テスト含めて1週間くらいで移行完了した気がする。まずは構成から。
余談だけどv8からはDocker必須になっているので気をつけて!!
■構成
もともとRedash公式のAWS EC2 AMIから運用していました。ログインはGoogle OAuth SSOを利用しています。まずは新規でUbuntuのインスタンスを作って、その中にRedash公式シェルスクリプトを叩けば、まあなんてステキ。Dockerがインストールされて環境が簡単に出来上がります。(構築方法は以下)
AWSの一般的な構成ということもあり、以下のブログではVPSということでSSL証明書も設定していますが、ALBなのでport 80でredash_nginx_1コンテナが立ち上がればすぐにhttpsでアクセスすることができます。
アクセス制限もIP制限しているのでNginxの細かい設定は不必要。あとはRDSなのでターゲットグループから新インスタンスに向き先を変更するだけで移行完了となります。もちろんdocker-compose.ymlからPostgreSQLの部分を削除しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
version: "2" x-redash-service: &redash-service image: redash/redash:8.0.0.b32245 depends_on: - redis env_file: /opt/redash/env restart: always services: server: <<: *redash-service command: server ports: - "5000:5000" environment: REDASH_WEB_WORKERS: 4 scheduler: <<: *redash-service command: scheduler environment: QUEUES: "celery" WORKERS_COUNT: 1 scheduled_worker: <<: *redash-service command: worker environment: QUEUES: "scheduled_queries,schemas" WORKERS_COUNT: 1 adhoc_worker: <<: *redash-service command: worker environment: QUEUES: "queries" WORKERS_COUNT: 2 redis: image: redis:5.0-alpine restart: always nginx: image: redash/nginx:latest ports: - "80:80" depends_on: - server links: - server:redash restart: always |
ちなみにRedisですが、旧Redashサーバーはローカルで動いているということもあり、新環境でもEC2内で動かすようにしましたが、ElastiCacheに移行すればよかったと思う。ここらへんはサクッと移行できるのでやっておこう。
新インスタンスへの切り替えはDB dump後、以下のように対応すると良き。デフォルトのenvはバックアップ取っておいて旧サーバーのenvをコピー後にDBマイグレーションをかけたらDockerを起動しましょう。先に起動してしまうとわけがわからんことになるので。
1 2 3 4 5 6 |
# cd /opt/redash # rm env # mv newenv env # docker-compose run --rm server manage db upgrade # docker-compose up -d |
■気づいたこと
RedashはDBさえdumpしておけばいつでも復旧可能ということがわかった。Docker化いける💪
— adachin👾SRE (@adachin0817) August 21, 2020
テスト用環境で本番のDBをdumpしてrestoreすればいつでも復元可能となるので、RDS化は必須ですね。また、テスト環境も本番と同じように作ることで、次のバージョンアップも検証できるので必ず構築しておきましょう。
■ハマったところ
- docker-compose run –rm server manage db upgradeにエラー出る
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# docker-compose run --rm server manage db upgrade Starting redash_redis_1 ... done Traceback (most recent call last): File "/app/manage.py", line 9, in <module> manager() File "/usr/local/lib/python2.7/site-packages/click/core.py", line 716, in __call__ return self.main(*args, **kwargs) File "/usr/local/lib/python2.7/site-packages/flask/cli.py", line 380, in main return AppGroup.main(self, *args, **kwargs) File "/usr/local/lib/python2.7/site-packages/click/core.py", line 696, in main rv = self.invoke(ctx) File "/usr/local/lib/python2.7/site-packages/click/core.py", line 1060, in invoke return _process_result(sub_ctx.command.invoke(sub_ctx)) File "/usr/local/lib/python2.7/site-packages/click/core.py", line 1060, in invoke return _process_result(sub_ctx.command.invoke(sub_ctx)) File "/usr/local/lib/python2.7/site-packages/click/core.py", line 889, in invoke return ctx.invoke(self.callback, **ctx.params) File "/usr/local/lib/python2.7/site-packages/click/core.py", line 534, in invoke return callback(*args, **kwargs) File "/usr/local/lib/python2.7/site-packages/click/decorators.py", line 17, in new_func return f(get_current_context(), *args, **kwargs) File "/usr/local/lib/python2.7/site-packages/flask/cli.py", line 257, in decorator return __ctx.invoke(f, *args, **kwargs) File "/usr/local/lib/python2.7/site-packages/click/core.py", line 534, in invoke return callback(*args, **kwargs) File "/usr/local/lib/python2.7/site-packages/flask_migrate/cli.py", line 132, in upgrade _upgrade(directory, revision, sql, tag, x_arg) File "/usr/local/lib/python2.7/site-packages/flask_migrate/__init__.py", line 239, in upgrade command.upgrade(config, revision, sql=sql, tag=tag) File "/usr/local/lib/python2.7/site-packages/alembic/command.py", line 298, in upgrade script.run_env() File "/usr/local/lib/python2.7/site-packages/alembic/script/base.py", line 489, in run_env util.load_python_file(self.dir, "env.py") File "/usr/local/lib/python2.7/site-packages/alembic/util/pyfiles.py", line 98, in load_python_file module = load_module_py(module_id, path) File "/usr/local/lib/python2.7/site-packages/alembic/util/compat.py", line 239, in load_module_py mod = imp.load_source(module_id, path, fp) File "migrations/env.py", line 87, in <module> run_migrations_online() File "migrations/env.py", line 70, in run_migrations_online poolclass=pool.NullPool) File "/usr/local/lib/python2.7/site-packages/sqlalchemy/engine/__init__.py", line 466, in engine_from_config return create_engine(url, **options) File "/usr/local/lib/python2.7/site-packages/sqlalchemy/engine/__init__.py", line 425, in create_engine return strategy.create(*args, **kwargs) File "/usr/local/lib/python2.7/site-packages/sqlalchemy/engine/strategies.py", line 50, in create u = url.make_url(name_or_url) File "/usr/local/lib/python2.7/site-packages/sqlalchemy/engine/url.py", line 211, in make_url return _parse_rfc1738_args(name_or_url) File "/usr/local/lib/python2.7/site-packages/sqlalchemy/engine/url.py", line 270, in _parse_rfc1738_args "Could not parse rfc1738 URL from string '%s'" % name) sqlalchemy.exc.ArgumentError: Could not parse rfc1738 URL from string '"postgresql://hoge:hogeeee@hoge.xxxxxxxxxx.ap-northeast-1.rds.amazonaws.com/redash"' |
v8から以下のようにenvファイルに ""
(ダブルクォーテーション) をつけてしまうとエラーが出るので注意!消しちまおう!
1 |
REDASH_DATABASE_URL="postgresql://hoge:hogeeee@hoge.xxxxxxxxxx.ap-northeast-1.rds.amazonaws.com/redash" |
- Data Sourceがくるくる回って永遠と選択できない
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
Traceback (most recent call last): File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1612, in full_dispatch_request rv = self.dispatch_request() File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1598, in dispatch_request return self.view_functions[rule.endpoint](**req.view_args) File "/usr/local/lib/python2.7/site-packages/flask_restful/__init__.py", line 477, in wrapper resp = resource(*args, **kwargs) File "/usr/local/lib/python2.7/site-packages/flask_login/utils.py", line 228, in decorated_view return func(*args, **kwargs) File "/usr/local/lib/python2.7/site-packages/flask/views.py", line 84, in view return self.dispatch_request(*args, **kwargs) File "/app/redash/handlers/base.py", line 31, in dispatch_request return super(BaseResource, self).dispatch_request(*args, **kwargs) File "/usr/local/lib/python2.7/site-packages/flask_restful/__init__.py", line 587, in dispatch_request resp = meth(*args, **kwargs) File "/app/redash/permissions.py", line 67, in decorated return fn(*args, **kwargs) File "/app/redash/handlers/data_sources.py", line 95, in get for ds in data_sources: File "/usr/local/lib/python2.7/site-packages/sqlalchemy/orm/loading.py", line 98, in instances util.raise_from_cause(err) File "/usr/local/lib/python2.7/site-packages/sqlalchemy/util/compat.py", line 265, in raise_from_cause reraise(type(exception), exception, tb=exc_tb, cause=cause) File "/usr/local/lib/python2.7/site-packages/sqlalchemy/orm/loading.py", line 79, in instances rows = [proc(row) for row in fetch] File "/usr/local/lib/python2.7/site-packages/sqlalchemy/orm/loading.py", line 511, in _instance loaded_instance, populate_existing, populators) File "/usr/local/lib/python2.7/site-packages/sqlalchemy/orm/loading.py", line 611, in _populate_full dict_[key] = getter(row) File "/usr/local/lib/python2.7/site-packages/sqlalchemy/sql/type_api.py", line 1226, in process return process_value(impl_processor(value), dialect) File "/app/redash/models/types.py", line 28, in process_result_value return ConfigurationContainer.from_json(super(EncryptedConfiguration, self).process_result_value(value, dialect)) File "/usr/local/lib/python2.7/site-packages/sqlalchemy_utils/types/encrypted/encrypted_type.py", line 409, in process_result_value decrypted_value = self.engine.decrypt(value) File "/usr/local/lib/python2.7/site-packages/sqlalchemy_utils/types/encrypted/encrypted_type.py", line 216, in decrypt decrypted = self.fernet.decrypt(value) File "/usr/local/lib/python2.7/site-packages/cryptography/fernet.py", line 75, in decrypt return self._decrypt_data(data, timestamp, ttl) File "/usr/local/lib/python2.7/site-packages/cryptography/fernet.py", line 119, in _decrypt_data self._verify_signature(data) File "/usr/local/lib/python2.7/site-packages/cryptography/fernet.py", line 108, in _verify_signature raise InvalidToken InvalidToken |
redash_server_1に対してdocker logsをしてみると上記のエラーを発見しました。InvalidTokenと書いてあるのでenvファイルのどっかがおかしいと判断できます。
そこで REDASH_COOKIE_SECRET
とはなんぞと調べたところ、DBのdata_sourcesテーブルにある暗号化フィールドの復号化に使われるので、これは旧Redashサーバーのenvから持ってくる必要があります。また、 REDASH_SECRET_KEY
は旧RedashサーバーがDBの暗号キーとクッキーの暗号キーの値が同じということで、削除することで解決となりました。(新規構築の場合は自動で作られるのでOK)ちなみにこのキーの実態がよくわからなかったので、新規のキーをぶちこんだり、適当な値を入れたりしたのでこれはハマった…なので、このキーをなくしたら終わりですね… それでもだめな場合は REDASH_SECRET_KEY
を旧サーバーからコピーして設定してみてください。
- そもそもdocker-compose up -d でredashコンテナが立ち上がらない
1 2 3 4 5 6 7 8 9 10 |
# docker-compose up -d redash_redis_1 is up-to-date redash_adhoc_worker_1 is up-to-date redash_scheduler_1 is up-to-date redash_scheduled_worker_1 is up-to-date Creating redash_server_1 ... error ERROR: for redash_server_1 Cannot start service server: b'driver failed programming external connectivity on endpoint redash_server_1 (xxxxxxxxxx): Error starting userland proxy: listen tcp 0.0.0.0:5000: bind: address already in use' ERROR: for server Cannot start service server: b'driver failed programming external connectivity on endpoint redash_server_1 (xxxxxxxxxxx): Error starting userland proxy: listen tcp 0.0.0.0:5000: bind: address already in use' |
Redashのportは5000なのですが、datadog-agentと被っていたということで、以下のように変更することで解決。
とりあえずここらへんを気をつけていれば、すんなりと移行できると思います。今後のバージョンアップ方法もwikiに書いておいたので参考に。
■まとめ
とりあえず、バージョンアップにビビらず移行できたのは良かったけど、ECS/Fargateには移行したいところ!それにオートスケールもしていないので、クエリが詰まってCPUが100%になったらdocker-compose restart的な作業が発生すると思うので、それは後々考えよう。
0件のコメント