SlackとKubernetesでChatOpsを構築:コンテキストスイッチを廃止して自動化を始めよう

DevOps tutorial - IT technology blog
DevOps tutorial - IT technology blog

コンテキストスイッチの高い代償

かつての私の朝は、いらだたしいパターンの繰り返しでした。Slackの通知で本番サービスが遅延していることを知り、すべてを中断してVPNを起動し、クラウドプロバイダーの認証を済ませ、kubectl get podsと打ち込み始めます。実際にログを確認できる頃には5分が経過していました。その間、Slackのインシデントスレッドには、まだ把握できていない状況へのアップデートを求めるステークホルダーからのメッセージが30件も溜まっていました。

コンテキストスイッチは生産性を著しく低下させます。ある研究によると、一度中断された集中力を元の深い状態に戻すには最大20分かかると言われています。ChatOpsは、インフラ管理をチームがすでに使用している会話ツールの中に組み込むことで、この問題を解決します。コマンドを実行するためにSlackを離れるのではなく、Slackにコマンドを持ち込むのです。

私は50以上のマイクロサービスを管理する本番環境でこのワークフローを導入してきました。その結果は一貫しており、問題解決までの時間が短縮され、透明性の高い監査ログが残るようになりました。チャンネル内の全員が、問題解決のために何が行われたかを正確に把握できるため、手動での状況報告も不要になります。

ChatOpsがギャップを埋める仕組み

ChatOpsは、専用のボットを介してSlackやTeamsなどのチャットクライアントをクラスターに接続することで機能します。Kubernetesの場合、このボットは通常クラスター内でデプロイメントとして動作し、ユーザーのメッセージとKubernetes APIの仲介役を務めます。

このセットアップは、主に以下の3つのコンポーネントで構成されます。

  • インターフェース (Slack): アクションをトリガーし、リッチにフォーマットされた通知を受け取る場所です.
  • ブリッジ (Botkube): ボットをゼロから自作することも可能ですが、Botkubeが業界標準となっています。これはSlackメッセージをKubernetesのアクションに変換するために特別に構築されたオープンソースツールです。
  • エンジン (Kubernetes API): 最終的な操作対象です。ボットはAPIサーバーにクエリを投げ、権限に基づいてデータを取得したりリソースを修正したりします。

ワークフローは非常にシンプルです。チャンネルで @Botkube get pods と入力すると、Slack APIがこれをクラスター内のBotkubeコントローラーに転送します。BotkubeはKubernetes APIに問い合わせを行い、結果をきれいなSlackブロックに整形して投稿します。これにより、個人のターミナルセッションがチーム共有の体験へと変わります。

Slackワークスペースの準備

クラスターを操作する前に、Slack側の設定を行う必要があります。これには、必要な認証トークンを生成するためのSlack Appの作成が含まれます。

  1. Slack API コンソールに移動し、新しいアプリを “From scratch”(スクラッチ)で作成します。
  2. アプリ名を K8s-Bot とし、メインのワークスペースに関連付けます。
  3. OAuth & Permissions セクションで、以下の特定の Bot Token Scopes を割り当てます:
    • app_mentions:read: ボットがコマンドを認識できるようにします。
    • chat:write: ボットがレスポンスを投稿できるようにします。
    • files:write: 長いログファイルをスニペットとして送信するために不可欠です。
  4. アプリをワークスペースにインストールします。Bot User OAuth Tokenxoxb- で始まるもの)をメモしておきます。これは後で Helm の設定に使用します。

HelmによるBotkubeのデプロイ

Helmを使用するのがBotkubeを起動する最も早い方法で、通常2分もかかりません。まずは読み取り専用(read-only)の設定から始めましょう。リソースの修正や削除の権限を与える前に、ボットの出力を確認するのがベストプラクティスです。

まず、公式リポジトリを追加します:

helm repo add botkube https://charts.botkube.io
helm repo update

次に、values.yaml ファイルを作成します。このファイルで、ボットがどのチャンネルをリッスンし、どのKubernetesイベントを監視するかを定義します。

# values.yaml
communications:
  'default-group':
    slack:
      enabled: true
      channel: 'devops-alerts'
      token: 'ここにトークンを入力'

settings:
  clusterName: 'prod-cluster-01'
  allowInsecureStateless: true

executors:
  'k8s-read-only':
    botkube/kubectl:
      enabled: true
      config:
        rbac:
          group: system:read-only
      namespaces:
        include: ["default", "production"]

sources:
  'k8s-events':
    botkube/kubernetes:
      enabled: true
      config:
        resources:
          - name: v1/pods
            events: [create, delete, error]
          - name: apps/v1/deployments
            events: [update, error]

専用のネームスペースにチャートをインストールします:

helm install botkube botkube/botkube \
  --namespace botkube \
  --create-namespace \
  -f values.yaml

実践シナリオ:チャットからのデバッグ

/invite @K8s-Bot でボットをチャンネルに招待したら、基本的な確認作業でターミナルを使う必要はもうありません。日々のワークフローがどのように変わるか、3つの例を挙げます。

1. インスタント・ヘルスチェック

開発者から「ステージング環境が重い」という報告があった場合、推測する必要はありません。ボットに聞くだけです。

@Botkube kubectl get pods -n production

ボットは即座にステータス一覧を返します。ポッドが OOMKilledCrashLoopBackOff になっていれば、数分ではなく数秒でボトルネックを特定できます。

2. チームでのログ解析

通常、ログは一人のターミナルの中に閉じ込められがちです。ChatOpsを使えば、問題が発生しているサービスの最新100行のログを直接スレッドに引き出すことができます:

@Botkube kubectl logs deployment/api-gateway --tail=100

Botkubeはこれらのログをテキストスニペットとしてアップロードします。これにより、バックエンドチーム全員が同時にスタックトレースを確認でき、集団での迅速な診断が可能になります。

3. プロアクティブなイベント通知

YAMLで sources を設定したため、ボットは早期警告システムとして機能します。デプロイメントがヘルスチェックに失敗した瞬間に通知をプッシュします。多くの場合、正式な監視ツールが重大アラートを出す前に、Slackの通知を見て調査を開始することができます。

RBACによるクラスターのセキュリティ保護

セキュリティは、ChatOpsの導入において最も懸念される点です。Slackアカウントの乗っ取りや、誤ったコマンドによって本番環境のネームスペースが消去されるような事態は避けなければなりません。ここでKubernetesのロールベースアクセス制御 (RBAC) が重要になります。

最初の設定では、ボットを system:read-only にマッピングしました。将来的にボットにポッドの再起動などを許可したい場合は、許可するアクションを制限した専用の ClusterRole を作成してください:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: botkube-restarter
rules:
- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["get", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: botkube-restarter-binding
subjects:
- kind: ServiceAccount
  name: botkube
  namespace: botkube
roleRef:
  kind: ClusterRole
  name: botkube-restarter
  apiGroup: rbac.authorization.k8s.io

厳格な境界線を定義することで、人的ミスによる致命的な事故のリスクを抑えつつ、自動化のスピードを享受できます。

最後に

Kubernetesの運用をSlackに持ち込むことは、単なる利便性以上の意味があります。それはチーム全体の認知負荷を下げることにつながります。ログやステータス確認がインシデントを議論する場所と同じ場所に存在することで、開発 (Dev) と運用 (Ops) の間の壁はついに崩れ始めます。

まずは読み取り専用の権限から始めて信頼を築きましょう。チームが慣れてきたら、CI/CDのロールバックのトリガーや自動スケーリングなど、より高度な機能をチャットから実行することを検討してみてください。ターミナルは、日常的な状況確認のためではなく、より深い思考が必要な作業のために使うべきです。

Share: