AKARI Tech Blog

燈株式会社のエンジニア・開発メンバーによる技術ブログです

kubernetesのnamespaceをリポジトリ毎に分離してcodespaceから利用する

こんにちは、記念すべき一発目のAKARI Tech Blogですが、DXソリューション事業本部VPoEの丸尾が担当します。
一発目の記事なので、テックブログ始めました的な記事にしようと思ったのですが、普通に技術の話をしようと思います。
今回の記事では社内で運用しているkubernetes環境について、権限管理の整備をして新入社員の方が1日目からGPUを回せるようにした仕組みについてご紹介しようと思います。

背景と課題

燈では、社内における機械学習の実験環境としてGPUつきノードをkubernetesによってクラスター化して管理をしています。
あくまでも実験環境なので、多少の粗さは許容しており、最初期時は、全ユーザーがkubernetesの全リソースの全アクセス権があるような雑な権限管理をしてました。
しかし、会社の規模が大きくなるにつれ利用者が増えてきたため、適切な権限分離をする必要がありました。また、誰もがGPUを無制限に使えてしまう課題もあり、ある程度の制限が必要でした。

そこで、以下の方針を立てました。

Namespaceの分離

まず、利用プロジェクトごとにNamespaceを作成して、Namespaceごとにコンテナを作成するというフローにし、アクセスできる共有フォルダの制限やGPUの枚数の制限をNamespaceごとに制限する。(この制限はgatekeeperという技術を使っているのですが、それはまた別の機会で、、)

Codespaceによる認証

そのあと、Namespaceごとにアクセスできるユーザーを設定する。また、燈ではGithub Codespaceを利用しているという背景もあるので、Codespace上から適切な権限でアクセスする必要がある。

セットアップの簡易化

上記の環境が簡単にセットアップできるようにフローを整える必要があります。

その前に、kubernetesの認証について簡単に触れておきます。

Kubernetesにおける認証方法

クライアント証明書 方式を一般的に使います。kubernetesAPIを利用する際には ~/.kube/config に設定ファイルがあり、その中に証明書のパスなどが記述されています。

語弊を恐れずざっくり述べると、CA証明書(ca.crt)から、ユーザー側は秘密鍵(client.key)と証明書(client.crt)を作成し、kubernetesAPIのリクエスト時に、秘密鍵によってリクエストを暗号化し、証明書を提示することでユーザー本人であることを証明します。

以下には詳細なフローを記述しておきます。

sequenceDiagram
    participant Client as クライアント
    participant API as APIサーバー
    participant CA as CA証明書 (ca.crt)

    Note over Client,CA: クライアント証明書 (client.crt, client.key) 作成フロー

    Client->>CA: クライアント証明書の署名リクエスト (CSR: Certificate Signing Request)
    CA->>CA: CSRを検証しクライアント証明書を発行
    CA-->>Client: client.crt を発行して返却

    Note over Client,CA: 認証プロセスの開始

    Client->>API: HTTPSリクエスト送信 (client.keyで署名してclient.crtを提示)
    API->>CA: クライアント証明書の検証 (署名を確認)
    CA-->>API: 検証結果 (成功/失敗)
    alt 検証成功
        API->>Client: サーバー証明書を送信 (server.crtを送信)
        Client->>CA: サーバー証明書の検証 (ca.crtを使用)
        CA-->>Client: 検証結果 (成功/失敗)
        alt 検証成功
            API->>Client: 認証成功 (リクエスト処理開始)
        else 検証失敗
            API->>Client: 認証エラー (サーバー証明書無効)
        end
    else 検証失敗
        API->>Client: 認証エラー (クライアント証明書無効)
    end

改善後の運用フロー

リポジトリごとにNamespaceを作成し、そのリポジトリのCodespaceからNamespaceにアクセスできるという仕組みにすることで、リポジトリのアクセス権=Namespaceのアクセス権と揃えることができます。

一連のフローをGitHub Actionsで実現することで、設定を簡単にします。

sequenceDiagram
    participant Client as ユーザー
    participant Action as GithubActions
    participant Codespace as Codespace    
    participant K8s as Kubernetes API
    participant CA as CA証明書 (ca.crt)
    Note over Client,CA: リポジトリのセットアップ 作成フロー
    
    Client->>Actions: Kubernetesの設定要求
    Actions->>K8s: Namepsaceの作成
    Actions->>CA: 証明書の作成リクエスト
    CA->>Actions: クライアントの証明書(client.crt)の返却
    Actions->>Codespace: client.keyとclient.crtを環境変数に登録
    
    Note over Client,CA: Kubernetesへのアクセス
    Client->>Codespace: アクセス
    Codespace->>K8s: 環境変数を用いてclient.keyとclient.crtで認証

導入後

  • 以前は利用者がローカルでclient.keyとclient.crtを作る必要があったものを大きく改善した。
    • opensslのコマンドを間違えて使ったりしてデバッグが大変。
  • リポジトリのセットアップを1回だけやっておけば、利用者はcodespaceに入れば特に何もやる必要がない。
  • 残ってる課題として、ローカルからアクセスするフローをあまり確立していないので、別途確立させる必要がある。

まとめ

codespaceを使うと事前に環境変数やライブラリ等を構築できるので燈ではかなり重宝して使っており、codespaceから自社のkubernetesに接続するというトリッキーな環境について紹介してみました。
今まではkuberentesの初期設定のハードルが若干高かったのですが、今回の取り組みによって、入社1日目でもとりあえず学習を回すということが簡単にできるようになりました!

We're Hiring!

燈では、GPUを回してモデルを学習するAIエンジニアも、モデルを動かすための基盤を作るソフトウェアエンジニアも両方募集しています!
興味のある方はぜひカジュアル面談をしましょう!

akariinc.co.jp

今回の記事を書いた燈メンバー🙌

www.wantedly.com