8
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ec2で稼働中のredash環境をkubernetesに移そう

Last updated at Posted at 2019-06-06

この記事について

https://redash.io/help/open-source/setup
にて公開されているamiを利用してec2で作成したredashの環境をkubernetesに引っ越します。

それの作業メモです。
あまり細かいことは気にせず現在の環境と同じように動いて見えるところを目指します。
細かい部分はおいおいやりたい。

モチベーション

redashがよくハングして意外と運用が面倒なので監視体制の整っているk8s環境下に置きたかった。
(よくハングするのは使い方が悪いせいだとは思うけど)

ので、既にk8s環境を持ってる人向けですね、これのためにk8s立てるのはさすがにちょっとアレ。

流れ

ec2の中で動いてるdocker環境をk8sに移すだけ

作業

現行redash環境の把握

amiで立てたらパッと使えるので便利すぎて内部は全然把握してませんでした。
で、中身を見るとなんとdockerが動いてました。
コンテナが7つも動いていて少しびっくり。
こいつらをk8sで動かせばいいんすね、しかし既にdockerになってるとはラッキー。

ポイントになりそうな部分

とりあえずの問題はステータスを持つ部分をどうするか。
稼働中のコンテナを見ると redispostgres のコンテナがあり、これらがそれに該当しそうです。
inspectしてみたところ、postgresはhostのvolumeをbindしていますが、redisはしておらず、データボリュームを面倒見てやる必要があるのはpostgresだけの様子。

作戦

  • とりあえずk8s内に現行docker環境と同じようなものを作る
  • postgresqlのデータを移す

これだけで無事動いたらいいなあ

作成

これを参考にしてkubernetesのmanifestを作成します。
環境変数などは深く考えずにそのまま使います。
imageのバージョンはとりあえず現環境を引き継ぎました。
configMapは現環境の/opt/redash/envをコピーしたものです。
明らかにsecretな項目もありますがここは例なので、まあ。

数少ないポイントとしてはdocker-compose.yamlのcommandargsにすること。
entrypointcommandsに相当するらしいです)
あとはdockerでhost名でやりとりしてた部分を直すこと。
nginxイメージの中にも一箇所あるので書き直したconfigMapをマウントします。
(今回は全部のコンテナを強引に一つのpodに突っ込んだのでlocalhostですがpodを独立させる場合はよしなにやる感じで)

で、このような感じになりました。

redash.yaml
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

serviceingressは各々の環境に都合よくやってください。

これで試しにアクセスすると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

おわり

8
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?