2021/03/01

Airbrake API互換のクラッシュレポートサービスであるerrbitをk8sにデプロイ

k8smongodberrbit

概要

オープンソースであるエラーレポーティングWebアプリである、errbitをEKS上にデプロイしてみました。

The open source error catcher that’s Airbrake API compliant

今回はk8sの設定ファイルを中心にログを残しておきます。

※ mongodbはcluster構成ではなく、standaloneな構成をとっています。

※ メール送信はsendgridを利用しています。

k8s 設定ファイル

namespace

apiVersion: v1
kind: Namespace
metadata:
  name: errbit

secrets

apiVersion: v1
kind: Secret
metadata:
  name: mongodb
  namespace: errbit
type: Opaque
data:
  # mongo dbのrootユーザーのパスワード(base64する)
  root-password: XXXXXXXXXX
  # mongo dbのerrbitユーザーのパスワード(base64する)
  password: XXXXXXXXXX
---
apiVersion: v1
kind: Secret
metadata:
  name: sendgrid
  namespace: errbit
type: Opaque
data:
  # sendgridのapi secret keyを設定(base64する)
  apiKey: XXXXXXXXXX

configmaps

apiVersion: v1
kind: ConfigMap
metadata:
  name: mongodb
  namespace: errbit
data:
  username: errbit
  database: errbit
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: errbit
  namespace: errbit
data:
  mongo-url: "mongodb://errbit:XXXXXXXXXX@mongodb/errbit"

mongodb

apiVersion: v1
kind: PersistentVolume
metadata:
  name: errbit-mongodb
spec:
  storageClassName: errbit-mongodb
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  awsElasticBlockStore:
    # EBSをあらかじめ作成しておき、そのIDを使用
    volumeID: "vol-XXXXXXXXXXXXX"
    fsType: ext4
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mongodb
  namespace: errbit
spec:
  storageClassName: errbit-mongodb
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mongodb
  namespace: errbit
spec:
  strategy:
    type: RollingUpdate
  selector:
    matchLabels:
      app: mongodb
  template:
    metadata:
      name: mongodb
      labels:
        app: mongodb
    spec:
      securityContext:
        fsGroup: 1001
      containers:
        - name: mongodb
          image: docker.io/bitnami/mongodb:4.2.4-debian-10-r0
          imagePullPolicy: IfNotPresent
          securityContext:
            runAsNonRoot: true
            runAsUser: 1001
          ports:
            - name: mongodb
              containerPort: 27017
          volumeMounts:
            - name: mongodb
              mountPath: /bitnami/mongodb
              subPath: ""
          livenessProbe:
            exec:
              command:
                - mongo
                - --eval
                - "db.adminCommand('ping')"
            initialDelaySeconds: 30
            periodSeconds: 10
            timeoutSeconds: 5
            successThreshold: 1
            failureThreshold: 6
          readinessProbe:
            exec:
              command:
                - mongo
                - --eval
                - "db.adminCommand('ping')"
            initialDelaySeconds: 5
            periodSeconds: 10
            timeoutSeconds: 5
            successThreshold: 1
            failureThreshold: 6
          env:
            - name: MONGODB_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mongodb
                  key: password
            - name: MONGODB_ROOT_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mongodb
                  key: root-password
            - name: MONGODB_USERNAME
              valueFrom:
                configMapKeyRef:
                  name: mongodb
                  key: username
            - name: MONGODB_DATABASE
              valueFrom:
                configMapKeyRef:
                  name: mongodb
                  key: database
            - name: MONGODB_SYSTEM_LOG_VERBOSITY
              value: "0"
            - name: MONGODB_DISABLE_SYSTEM_LOG
              value: "no"
            - name: MONGODB_ENABLE_IPV6
              value: "no"
            - name: MONGODB_ENABLE_DIRECTORY_PER_DB
              value: "no"
      volumes:
        - name: mongodb
          persistentVolumeClaim:
            claimName: mongodb
---
apiVersion: v1
kind: Service
metadata:
  name: mongodb
  namespace: errbit
spec:
  type: ClusterIP
  ports:
    - name: mongodb
      port: 27017
      targetPort: mongodb
  selector:
    app: mongodb

errbit

apiVersion: apps/v1
kind: Deployment
metadata:
  name: errbit
  namespace: errbit
spec:
  replicas: 1
  selector:
    matchLabels:
      app: errbit
  template:
    metadata:
      name: errbit
      labels:
        app: errbit
    spec:
      containers:
        - name: openproject
          image: errbit/errbit:v0.9.0
          env:
            - name: PORT
              value: "8080"
            - name: RACK_ENV
              value: "production"
            - name: MONGO_URL
              valueFrom:
                configMapKeyRef:
                  name: errbit
                  key: mongo-url
            - name: GOOGLE_AUTHENTICATION
              value: "false"
            - name: GITHUB_AUTHENTICATION
              value: "false"
            - name: EMAIL_DELIVERY_METHOD
              value: smtp
            - name: ERRBIT_EMAIL_FROM
              value: '[email protected]'
            - name: SMTP_SERVER
              value: "smtp.sendgrid.net"
            - name: SMTP_PORT
              value: '2525'
            - name: SMTP_USERNAME
              value: 'apikey'
            - name: SMTP_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: sendgrid
                  key: apiKey
            - name: SMTP_DOMAIN
              value: 'errbit.your-domain.com'
            - name: ERRBIT_HOST
              value: 'errbit.your-domain.com'
            - name: ERRBIT_PROTOCOL
              value: 'https'
            - name: ERRBIT_PORT
              value: '443'
          ports:
            - containerPort: 8080
              name: http
          livenessProbe:
            httpGet:
              path: /robots.txt
              port: 8080
            initialDelaySeconds: 60
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 60
            failureThreshold: 6
---
apiVersion: v1
kind: Service
metadata:
  name: errbit
  namespace: errbit
spec:
  ports:
    - name: http
      port: 8080
      targetPort: http
  selector:
    app: errbit

初期化

errbitのコンテナにログイン(kubectl exec <pod-name> -n errbit -- /bin/sh)して、以下のコマンドを実行して
初回ログインユーザー・パスワードを取得します。

bundle exec rake errbit:bootstrap

nginx

deploymentは割愛しますが、errbit serviceに対してproxyするnginxのDockerを作成して、デプロイします。
secretでデプロイしたtlsの設定ファイルを使用してSSLを有効にします。

apiVersion: v1
kind: Service
metadata:
  name: nginx
  namespace: errbit
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
spec:
  type: LoadBalancer
  ports:
    - name: http
      port: 80
      targetPort: http
    - name: https
      port: 443
      targetPort: https
  selector:
    app: nginx

これらのdeploy後に、内部DNSにCNAMEレコードを追加して対応完了です。

以上になります。
特に詰まる事なく、割とサクッとデプロイできました。