この記事について
https://redash.io/help/open-source/setup
にて公開されているamiを利用してec2で作成したredashの環境をkubernetesに引っ越します。
それの作業メモです。
あまり細かいことは気にせず現在の環境と同じように動いて見えるところを目指します。
細かい部分はおいおいやりたい。
モチベーション
redashがよくハングして意外と運用が面倒なので監視体制の整っているk8s環境下に置きたかった。
(よくハングするのは使い方が悪いせいだとは思うけど)
ので、既にk8s環境を持ってる人向けですね、これのためにk8s立てるのはさすがにちょっとアレ。
流れ
ec2の中で動いてるdocker環境をk8sに移すだけ
作業
現行redash環境の把握
amiで立てたらパッと使えるので便利すぎて内部は全然把握してませんでした。
で、中身を見るとなんとdockerが動いてました。
コンテナが7つも動いていて少しびっくり。
こいつらをk8sで動かせばいいんすね、しかし既にdockerになってるとはラッキー。
ポイントになりそうな部分
とりあえずの問題はステータスを持つ部分をどうするか。
稼働中のコンテナを見ると redis
と postgres
のコンテナがあり、これらがそれに該当しそうです。
inspectしてみたところ、postgresはhostのvolumeをbindしていますが、redisはしておらず、データボリュームを面倒見てやる必要があるのはpostgresだけの様子。
作戦
- とりあえずk8s内に現行docker環境と同じようなものを作る
- postgresqlのデータを移す
これだけで無事動いたらいいなあ
作成
これを参考にしてkubernetesのmanifestを作成します。
環境変数などは深く考えずにそのまま使います。
imageのバージョンはとりあえず現環境を引き継ぎました。
configMapは現環境の/opt/redash/env
をコピーしたものです。
明らかにsecretな項目もありますがここは例なので、まあ。
数少ないポイントとしてはdocker-compose.yamlのcommand
はargs
にすること。
(entrypoint
がcommands
に相当するらしいです)
あとはdockerでhost名でやりとりしてた部分を直すこと。
nginxイメージの中にも一箇所あるので書き直したconfigMapをマウントします。
(今回は全部のコンテナを強引に一つのpodに突っ込んだのでlocalhostですがpodを独立させる場合はよしなにやる感じで)
で、このような感じになりました。
apiVersion: v1
kind: ConfigMap
metadata:
name: redash
data:
PYTHONUNBUFFERED: "0"
REDASH_LOG_LEVEL: INFO
REDASH_REDIS_URL: redis://localhost:6379/0 #localhostの部分が元はredisだった
POSTGRES_PASSWORD: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
REDASH_COOKIE_SECRET: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
REDASH_DATABASE_URL: postgresql://postgres:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@localhost/postgres #localhostの部分が以下略
REDASH_DATE_FORMAT: YYYY/MM/DD
REDASH_HOST: http://redashhost.dummy
---
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx
data:
default.conf: |
upstream redash {
server localhost:5000; #localhostの部分が云々
}
server {
listen 80 default;
gzip on;
gzip_types *;
gzip_proxied any;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
proxy_pass http://redash;
}
}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: redash
spec:
replicas: 1
selector:
matchLabels:
app: redash
template:
metadata:
labels:
app: redash
spec:
containers:
- name: server
image: redash/redash:5.0.2.b5486
envFrom:
- configMapRef:
name: redash
args:
- server
env:
- name: REDASH_WEB_WORKERS
value: "4"
- name: scheduler
args:
- scheduler
image: redash/redash:5.0.2.b5486
envFrom:
- configMapRef:
name: redash
env:
- name: QUEUES
value: celery
- name: WORKERS_COUNT
value: "1"
- name: scheduled-worker
image: redash/redash:5.0.2.b5486
envFrom:
- configMapRef:
name: redash
args:
- worker
env:
- name: QUEUES
value: "scheduled_queries,schemas"
- name: WORKERS_COUNT
value: "1"
- name: adhoc-worker
image: redash/redash:5.0.2.b5486
envFrom:
- configMapRef:
name: redash
args:
- worker
env:
- name: WORKERS_COUNT
value: "2"
- name: QUEUES
value: queries
- name: nginx
image: redash/nginx:latest
ports:
- containerPort: 80
volumeMounts:
- name: nginx-config
mountPath: /etc/nginx/conf.d
- name: redis
image: redis:3.0-alpine
- name: postgres
image: postgres:9.5.6-alpine
envFrom:
- configMapRef:
name: redash
volumes:
- name: nginx-config
configMap:
name: nginx
service
やingress
は各々の環境に都合よくやってください。
これで試しにアクセスすると500になると思います。
本来走るはずのデータベースの初期化スクリプトがパスワードとかを先に渡した都合で走らなかったとかですかね。
気にせずデータを移します。
redashで使っているデータベース名はpostgres
みたいです、意外と適当ですね。
これをdumpします。
現環境のhostで、
# docker exec [postgresのコンテナ名] pg_dump postgres -U postgres > ./datafile
とすればdumpファイルの./datafile
が出来上がるはずです。
これをscpかなんかでローカルにコピーしてから、
$ kubectl cp ./datafile -c postgres [redashのpod名]:/datafile
としてpostgresコンテナにコピーします。
コピーしたらpostgresコンテナにログインして、
# psql postgres -U postgres < /datafile
とすればデータの移行は完了。
なんとあっさりアクセスできるようになりました。
適当にごそごそ動かしてみたけど問題なさそう。
さすがはdockerですね、信者になってしまうわ。
TODO
データの永続化
このままだとpod消したらせっかく移行したデータが消えます。
hostのボリュームとか外部ボリュームを使ってなんとかしないとダメです。
私はawsを使っているのでEFSにしました。
マウントするpathは /var/lib/postgresql/data
です
監視
k8s環境に置いたことによって各コンテナのcpu使用率など基本的なメトリクスは簡単に見られるようになりました。
あとはredashのステータスの監視なのですが /status.json
にステータスを見られるエンドポイントが用意されています。
これをよしなに監視すればよいと思います。
(prometheusのexporter作った https://github.com/buildsville/redash-exporter )
containerの独立
とりあえずひとつのpodに全コンテナ詰め込みましたがこれはちょっとあんまりなのでバラバラにしたいです。
schedulerとかworkerがどういう関係なのかよくわからない…
これといって特に何もしてなさそうなnginxコンテナはおそらく不要になりそう。
liveness/readiness
とりあえずserverの/login
にhttpGetしてみたんですけどリミッターがかかってるらしく429を返すようになります。
REDASH_THROTTLE_LOGIN_PATTERN
で設定できるらしいですが別のエンドポイントにするとかtcpSocketにするとかはまあお好みで。
requests/limits
現状確認してる範囲だと、schedulerがよく暴走してcpuを食いつぶすらしいのでlimitを設定しておかないと危険です。
(schedulerの暴走はちゃんと設定してないからとか?まあそのへんはおいおい)
蛇足
もうすぐhelmのチャートがリリースされるようですよ…
https://github.com/helm/charts/pull/5071
おわり