0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Redisシークレット生成、ArgoCD Helmで掘り下げてみる

Last updated at Posted at 2025-07-04

Argo CD Redis パスワード生成プロセス

このドキュメントは、Argo CD を使用している際に、Redis パスワードの Secret が Helm テンプレートには存在しないにもかかわらず Secret が生成される現象について、その疑問を解決するために作成されました。

redis-secret-init Job が argocd admin redis-initial-password コマンドを通じてパスワードを生成することを知り、kubectl コマンドなしでどのように Secret が作成されるのか、その内部動作を詳細に分析した結果を説明します。


Argo CD で使用される Redis の初期パスワードは、argocd admin redis-initial-password というコマンドを通じて生成されます。このプロセスは通常、redis-secret-init という Job によって自動的に実行され、全体の流れは以下の通りです。

  1. コマンド実行: ユーザーが argocd admin redis-initial-password コマンドを実行します。
  2. Kubernetes クラスター接続: Go 言語で書かれた client-go ライブラリを使用して、Kubernetes API サーバーと通信する準備をします。
  3. パスワード Secret の確認: argocd-redis-initial-password という名前の Secret が既に存在するかを確認します。
  4. パスワード生成と Secret の保存:
    • 存在しない場合: 16 桁のランダムなパスワードを生成し、password というキーで Secret に保存します。
    • 既に存在する場合: このステップをスキップし、既存の Secret をそのまま使用します。
  5. 最終確認: Secret とその中の password キーが正しく存在するかを再度検証し、結果を出力します。

詳細プロセス: コードと関数の流れ

1段階: コマンド定義と Kubernetes フラグ設定

プログラムが開始されると、まずユーザーが入力したコマンドを処理する準備をします。

  • ファイル: cmd/argocd/commands/admin/redis_initial_password.go
  • 主要関数: NewRedisInitialPasswordCommand()

この関数は、redis-initial-password コマンドの名前、説明、および実行ロジックを定義します。重要な部分は、Kubernetes クラスター接続に必要な情報を受け取るために、kubectl に似たコマンドラインフラグ(例: --kubeconfig, --namespace)を設定することです。

  • 関連関数: cli.AddKubectlFlagsToCmd(&command)
  • ファイル: util/cli/cli.go
  • 役割: この関数は、client-go ライブラリの clientcmd パッケージを活用して、ユーザーが入力した --kubeconfig などのフラグ値を読み取り、Kubernetes クラスター接続設定を構成する ClientConfig インターフェースを生成します。kubectl コマンドを直接実行するのではなく、Go コード内で Kubernetes と通信する準備を完了します。
// redis_initial_password.go
func NewRedisInitialPasswordCommand() *cobra.Command {
    var clientConfig clientcmd.ClientConfig
    command := cobra.Command{
        Use:   "redis-initial-password",
        Short: "Ensure the Redis password exists, creating a new one if necessary.",
        Run: func(_ *cobra.Command, _ []string) {
            // 2段階からのロジックがここに含まれます。
        },
    }
    // Kubernetes接続のためのフラグを設定し、clientConfigを初期化します。
    clientConfig = cli.AddKubectlFlagsToCmd(&command)
    return &command
}

2段階: Kubernetes クライアントの生成

コマンドの実際の実行ロジック(Run 関数)が開始されると、1段階で準備された clientConfig を使用して、Kubernetes API サーバーと通信できるクライアントを生成します。

  • ファイル: cmd/argocd/commands/admin/redis_initial_password.go
  • 主要コード:
// Run 関数内部
// 1. clientConfigから名前空間とクラスター接続情報を取得します。
namespace, _, err := clientConfig.Namespace()
config, err := clientConfig.ClientConfig()

// 2. 上記の情報に基づいて、実際のAPIリクエストを送信できるKubernetesクライアントを生成します。
kubeClientset := kubernetes.NewForConfigOrDie(config)

kubeClientset オブジェクトは、Go コードで Kubernetes のリソース(Secret、Pod など)を照会、作成、変更、削除できる強力なツールとなります。


3段階: パスワード生成と Secret 作成要求

次に Redis パスワードを格納する Secret を作成します。

  • ファイル: cmd/argocd/commands/admin/redis_initial_password.go
  • 主要コード:
// 1. ランダムパスワードの生成
// generateRandomPassword() 関数は、数字、大文字小文字の英字、ハイフン(-)を組み合わせて16桁の文字列を作成します。
randomPassword, err := generateRandomPassword()

// 2. Secretオブジェクトの定義
// 生成されたパスワードを'password'キーに格納し、'argocd-redis-initial-password'という名前のSecret構造体を作成します。
secret := &corev1.Secret{
    ObjectMeta: metav1.ObjectMeta{
        Name:    common.RedisInitialCredentials, // "argocd-redis-initial-password"
        Namespace: namespace,
    },
    Data: map[string][]byte{
        common.RedisInitialCredentialsKey: []byte(randomPassword), // key: "password"
    },
}

// 3. Secret作成APIの呼び出し
// 2段階で作成したkubeClientsetを使用して、KubernetesにSecret作成を要求します。
_, err = kubeClientset.CoreV1().Secrets(namespace).Create(context.Background(), secret, metav1.CreateOptions{})

// もしSecretが既に存在する場合(apierrors.IsAlreadyExists(err))、エラーとして処理せずにスキップします。
if err != nil && !apierrors.IsAlreadyExists(err) {
    errors.CheckError(err)
}

4段階: 最終確認と結果出力

最後に、Secret が意図通りに正しく生成されたかを確認します。このプロセスは、Secret が元々存在していたか、新しく作成されたかに関係なく常に実行されます。

  • ファイル: cmd/argocd/commands/admin/redis_initial_password.go
  • 主要コード:
// 1. Secret取得APIの呼び出し
// Kubernetes APIサーバーに該当Secret情報を再度要求します。
secret, err = kubeClientset.CoreV1().Secrets(namespace).Get(context.Background(), redisInitialCredentials, metav1.GetOptions{})
errors.CheckError(err)

// 2. Secretデータキーの確認
// 取得したSecretのデータ内に'password'キーが存在するかを確認します。
if _, ok := secret.Data[redisInitialCredentialsKey]; ok {
    fmt.Println("Password secret is configured properly.")
} else {
    // キーが存在しない場合、エラーを発生させてプログラムを終了します。
    errors.Fatal(errors.ErrorGeneric, fmt.Sprintf("key %s doesn't exist in secret %s.", redisInitialCredentialsKey, redisInitialCredentials))
}

このように、argocd admin redis-initial-password コマンドは、kubectl を直接呼び出す代わりに、client-go ライブラリを通じて Kubernetes API と直接通信し、Redis パスワードを含む Secret を安定して生成および管理する役割を果たします。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?