Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

minioのaccess-keyaccess-secretonp_cluster_secrets.tfminio-access-secretから取る #1422

Merged
merged 5 commits into from
Dec 8, 2023

Conversation

rito528
Copy link
Member

@rito528 rito528 commented Nov 19, 2023

https://discord.com/channels/237758724121427969/959299646725951580/1175598364344205412

MINIO_DEBUG_ACCESS_KEYが見つけられないというエラーが出ていたので、すでにminioのkeysecretが定義されたonp_cluster_secrets.tfから取得するように修正しました。

mcserver--common--config-secretsからkeysecretが取得できなかった原因が分からなくて、とりあえずminioのアクセス情報が定義されているところがあったのでそこから取得するようにしてみましたが、これで動くのかどうかはわかっていないのでそもそも方向性が正しいかを見てほしいです。

@rito528 rito528 requested review from kory33 and outductor November 19, 2023 06:43
@kory33
Copy link
Member

kory33 commented Nov 19, 2023

これだとまだ動きません。ちょっと長くなっちゃうんですが、何が起きているかを説明します。どう変更すれば良いかは最後に述べます。

K8s には名前空間 (namespace) の概念があり、Pod などの namespace-scoped なリソースは クラスタ / 名前空間 / リソース名 のような構造で一意特定されます。例えば、同一クラスタ内にふたつの名前空間 ns1ns2 があり、それぞれに minecraft-pod という名前で Pod があった時、ns1minecfact-podns2mimecraft-pod は全くの別物です。

さて、 Secret リソースも Pod リソースも namespace-scoped です。Pod の環境変数束縛の secretKeyRef は、その Pod から見て 同一の 名前空間内の Secret の中身を持って来いという指示です。

ところで、今の PR 毎にデバッグ環境を生やす一連の仕組みは、リソース達を PR 毎に違う名前空間に置くことで動作します。すると各名前空間に配置された Pod はそれぞれの名前空間に居る Secret を読みに行きます。しかし、Terraform から今入っている MinIO のシークレットは単一名前空間にしか置かれていません。

じゃあどうするんだよ、となるわけですが、要するに「複数名前空間に共有された Secret」の概念があれば、「デバッグ環境が使う全ての名前空間に共有された Secret」に MinIO の秘匿情報を Terraform から書き込み、それを Pod で読めば良いわけです。

この「複数名前空間に共有された Secret」を 殆ど 実現するものとして、サードパーティ製の k8s custom controller によって定義・実現している ClusterSecret があります。「殆ど」とここで言っているのは、実際には ClusterSecret は Secret ではなく、Secret を生成するためのテンプレートであるからです (配備先候補の名前空間が作られる度に、ClusterSecret の custom controller が Secret リソースを ClusterSecret の定義通りに作りに行くような感じ)。

Terraform の設定ファイルの下の方ですでに ClusterSecret を注入するようにしているので、結局、そのリソース名を適切に変更すると良いです。

@rito528
Copy link
Member Author

rito528 commented Nov 19, 2023

@kory33

なんとなく何が起きているかは把握できて、リソース名が合っているかどうかはわかりませんが修正しました。

ところで

- name: CFG_DISCORDSRV_TOKEN
valueFrom:
secretKeyRef:
name: mcserver--common--config-secrets
key: DISCORDSRV_TOKEN

ここでmcserver--common--config-secretsDISCORDSRV_TOKENが参照できているのはなぜですか?
また別の場所からmcserver-common-config-secretsDISCORDSRV_TOKENというリソースが定義されていたりしますか?

@rito528
Copy link
Member Author

rito528 commented Nov 19, 2023

と思ったんですが、多分自己解決できて、dummy-secret.yamlとやらを見つけました。

このファイルのmetadatanamemcserver--common--config-secretsとなっているからDISCORDSRV_TOKENが取得できているんですね

@kory33
Copy link
Member

kory33 commented Nov 20, 2023

ここでmcserver--common--config-secretsDISCORDSRV_TOKENが参照できているのはなぜですか?

この "./stateful-set.yaml" は同階層にある kustomization.yaml によって「実体化」されています。つまり、(ArgoCD によって実行されている1) Kustomize 2 は、"./service-monitor.yaml" + "./service.yaml" + "./stateful-set.yaml"resource によって生成し、それに namespace: seichi-debug-minecraft を付与します。ArgoCD はこうして生成された manifest をクラスタに apply し、 mcserver--debug-s1 Application のリソースとします。

つまり、この "./stateful-set.yaml" (をもとにした resource) は、常に seichi-debug-minecraft 名前空間の中に生成されます。

また別の場所からmcserver-common-config-secretsDISCORDSRV_TOKENというリソースが定義されていたりしますか?

はい、
seichi-debug-minecraft 内の mcserver--common--config-secrets Secret リソースは Terraform によって投入されており、該当の StatefulSet はこの Secret から秘匿情報を持ってきます。

このファイルのmetadatanamemcserver--common--config-secretsとなっているからDISCORDSRV_TOKENが取得できているんですね

いいえ、この dummy-secret.yamlコメント に書いてある通り、 PR 毎デバッグ環境で DiscordSRV をどう動作させるべきかが不明瞭だったので、とりあえず動作を止めるために空文字列を入れているものです。これは PR 毎デバッグ環境の名前空間内に生成される Secret なので、"./stateful-set.yaml" からは参照されません。

Footnotes

  1. Git 上の repoUrl + pathsource に指定された ArgoCD Application は、該当フォルダの内容物によって、 Application 内に持つリソースの定義 (manifest) をどう生成すれば良いかを自動検知します。現在の ArgoCD には manifest を生成する手段が四つあり、ArgoCD は Helm を利用したテンプレーティング、 Kustomize を利用したテンプレーティング、Config Management Plugins でユーザーに定義された任意の処理を走らせる方式、ディレクトリ内の manifest をすべてそのまま利用する方式があります。例えば、mcserver--debug-s1Application リソースの source に指定されたとき、当該ディレクトリは kustomization.yaml を含んでいますから、ArgoCD は 当該ディレクトリを Kustomize を用いてテンプレーティングすれば良いと判断します。結果的に、ArgoCD は mcserver--debug-s1 を working directory に設定し、 kustomize コマンドを叩くことで Application 内に持つ manifest を生成します。

  2. kustomization.yaml の内容に基づいて manifest を生成するツールです。kustomization.yaml 内には kustomization.yaml 自体のメタデータ (apiVersion / name) に加えて、Generator と Transformer の設定が書かれます。Generator は元となる manifest を生成し、 Transformer が生成された manifest を加工します。例えば、 resources generator
    は、指定されたパスにあるファイルの内容をそのまま吐き出しますし、 patchesStrategicMerge transformer は、指定されたパスにあるファイルの内容を Generator が生成した manifest に「被せる」ようにして merge します。(参考)

- name: MINIO_ACCESS_SECRET
valueFrom:
secretKeyRef:
name: mcserver--common--config-secrets
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

うあー、どう変更すれば良いかの説明が雑過ぎて伝わってませんでした、すみません…

まず前提として、secretKeyRef.name は参照したい (同ネームスペース内の) Secret のリソース名を指しています。

したがって、ここを clustersecret に変更しても、(この StatefulSet が配置される先として指定されている) seichi-debug-minecraft-on-seichiassist-pr-{{PR番号}} 名前空間内の clustersecret という名前の Secret リソースを参照するだけで、その Secret リソースが存在しないという問題は変わりません。

ClusterSecretSecret とは別の kind 1 のリソースであり、リソース名である name を変えるだけではなく、そもそもリソースの種類から変更しなければなりません。

kubernetes_secret.minio_prod_access_secret のような kubernetes_secret リソース 2 は、Kubernetes の Secret リソースに対応してしまうので、これは望む挙動ではありません。そこで、helm_release.onp_minecraft_mariadb_monitoring_password のように、生の manifest を流し込むような helm_release Terraform リソースを用いて ClusterSecret をクラスタ内に配置することができます。

具体的な変更としては、次を行うと良いです。

  1. onp_cluster_minecraft_secrets.tf に、
resource "helm_release" "onp_minecraft_mariadb_monitoring_password" { ... }

を追加する
2. repository / chart / namespace / version既存のリソース通りに設定する
3. name は何かほかのものにする その SharedSecret が何であるかを表すような名前にすると良いです
4. set_list.value.[0] の中に SharedSecret の manifest を書く。

  • metadata.namematchNamespacedata を既存の SharedSecret から変更してください。それぞれ、SharedSecret リソース自体の名前、 Secret リソースを配備する先の名前空間のパターン、Secret に書き込む KV ペア (値は base64 エンコードされていなければならない) です。

Footnotes

  1. Kubernetes では、apiVersionkind の組が「リソースの種類」を表す識別子になっています。同一名前空間内でも、 apiVersion / kind が異なるリソースは同じ名前 name で存在することができます。例えば、minecraft という名前の Pod (コンテナなどを束ねる最小単位を表現するリソース) と minecraft という名前の ConfigMap (環境変数ペアのような、Map[<<環境変数に使えるような文字列>>, String] みたいなデータを持っているリソース) は同一名前空間内に共存できます。逆に言えば、クラスタ内のリソースは、名前空間 + apiVersion / kind + name の三つのデータで一意に特定できます。

  2. ここでの「リソース」は Terraform 上の概念であって、 Kubernetes のそれではないです

@rito528
Copy link
Member Author

rito528 commented Dec 2, 2023

とりあえず #1422 (comment) の内容に沿って(つもりで)直しました。

Terraform fmtonp_cluster_minecraft_secrets.tfで落ちているようなんですが、VSCodeのExtensionをformatterとしてそのまま使うと弾かれたりしますか?

@outductor
Copy link
Contributor

@rito528 拡張で検出できないなら普通にCLI使って差分みたらいいのでは

@outductor
Copy link
Contributor

@rito528 image
余計なスペースがあるそうです。

@rito528
Copy link
Member Author

rito528 commented Dec 8, 2023

@outductor
助かりました。
ありがとうございます!

@rito528 rito528 requested a review from kory33 December 8, 2023 15:59
Copy link
Member

@kory33 kory33 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 ありがとうございます!!!!

@kory33 kory33 merged commit d820216 into main Dec 8, 2023
2 checks passed
@kory33 kory33 deleted the fix/canNotFindMinioAccessInformation branch December 8, 2023 16:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants