Skip to content

tools: 管理者の kubeconfig もファイルで持たず、その場で作る - #407

Merged
5ym merged 2 commits into
mainfrom
tools-admin-kubeconfig-on-the-fly
Oct 17, 2026
Merged

5ym merged 2 commits into
mainfrom
tools-admin-kubeconfig-on-the-fly

Conversation

@5ym

@5ym 5ym commented Oct 17, 2026 •

Copy link
Copy Markdown
Collaborator

管理者の kubectl / helm (tools/t.ps1 --admin) の kubeconfig を、git に置いた talos/kubeconfig.yaml (SOPS) から復号するのをやめ、読み取り用と同じく talos/secrets.yaml の Kubernetes の CA で system:masters の証明書 (1 日で切れる) をその場で作る。

  • ファイルを置かないので、書き出し・暗号化・1 年ごとの作り直しが要らない。talosconfig を保存しない方針 (docs/decisions.md) にもそろう
  • 最初は talosctl kubeconfig でもらう形にしたが、レビューの指摘どおり呼ぶたびに 1 年もつ (取り消せない) 管理者の証明書が出るので、1 日で切れる自前の証明書にした
  • 開けられる範囲は変わらない (どちらも同じ age 鍵から作れる)
  • .sops.yaml の talos/kubeconfig.yaml の規則と、README の入れ方を消す。平文の kubeconfig / talosconfig の .gitignore は残す

確かめたこと (main の checkout から、この creds.sh を差し込んで): --admin で kubectl auth can-i '*' '*' が yes、auth whoami のグループが system:masters、talosctl version が通る。読み取り用は auth can-i get secrets が no。

🤖 Generated with Claude Code

https://claude.ai/code/session_017wBP4MK6j3oBwqbn95wZ8H

os:admin の talosconfig は secrets.yaml の CA でその場で作れるので、talos/kubeconfig.yaml (SOPS) を置いて 1 年ごとに作り直す必要が無い。.sops.yaml の規則と README の入れ方を消す。

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017wBP4MK6j3oBwqbn95wZ8H
@claude

claude Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Claude finished @5ym's task in 24s —— View job


レビュー結果: 問題なし(軽微な確認事項のみ)

tools/creds.sh と関連ドキュメントの差分を読みました。

不具合

  • talosconfig() への切り出しは、元の処理と同じです。$(talosconfig …) の中で mint が die しても、代入の終了コードで親が set -e により止まります。管理者側の tc=$(talosconfig admin) も || の文脈の外にあるので、同様に止まります。
  • talosctl kubeconfig --force "$out.$$" は、存在しないパスへ書き出す使い方で問題ありません。失敗時は rm -f と die に流れます。
  • sed による行き先の差し替えは、従来と同じ処理です。
  • talos/kubeconfig.yaml への参照は、リポジトリ内にもう残っていません。.sops.yaml の規則、README、.gitignore のコメントがそろっています。

セキュリティ

  • 平文は /dev/shm(tmpfs)にだけ置き、umask 077 も維持されています。
  • git から暗号化済みの kubeconfig が無くなる分、管理資格情報の置き場が減ります。開けられる範囲は同じ age 鍵のままです。
  • 要確認(軽微): talosctl kubeconfig は呼ぶたびに Talos の管理者証明書(system:masters 相当、有効期間は Talos 既定)を新しく作ります。コンテナと一緒に消えるので実害は小さいです。ただし --admin を使うたびに、期限の長い管理者証明書が 1 つずつ増えます。現在の想定で問題ないか、意図を確認してください。

設計・テスト

  • 書き出し、暗号化、年次の作り直しの手順が要らなくなり、talosconfig を保存しない方針ともそろっています。
  • 自動テストはありません。シェルスクリプトで、PR 本文に手元での確認結果(can-i、get nodes、行き先)が書かれているので十分だと考えます。

@claude

claude Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Claude finished @5ym's task in 21s —— View job


レビュー結果: 問題なし(PR 本文の更新のみ要確認)

最新のコミット(10a5e6c)で方式が変わっているので、前回のレビューは今の差分には当てはまりません。tools/creds.sh と関連ドキュメントを読み直しました。

不具合

  • 管理者の kubeconfig は、読み取り用と同じ mint k8s で /O=system:masters/CN=tools-admin の証明書を作ります。talosctl kubeconfig は呼んでいません。mint の失敗は die に流れ、set -e で止まります。
  • kubeconfig の書き出しは役割ごとに分けた形です。$role は admin か readonly の固定値なので、printf の引数を展開しても問題ありません。context 名は読み取り用が従来と同じ readonly@doany で、変わっていません。
  • talosconfig() への切り出しは元の処理と同じです。$(…) の中で mint が die しても、代入の終了コードで親が止まります。
  • talos/kubeconfig.yaml への参照は残っていません。.sops.yaml、README、.gitignore のコメントがそろっています。

セキュリティ

  • 平文は /dev/shm にだけ置き、umask 077 も維持されています。管理者の証明書は 1 日で切れます。
  • 前回の「talosctl kubeconfig が長い証明書を毎回出す」という懸念は、この方式変更で解消しています。
  • 要確認(軽微): system:masters の証明書は取り消せません。有効期間が 1 日なので許容できると考えます。secrets.yaml を開ける人なら CA の鍵そのものを持っているので、権限の範囲は変わりません。

設計・テスト

  • 管理者用と読み取り用が 1 つの経路にまとまり、重複が減っています。
  • 自動テストはありません。シェルスクリプトなので手元での確認が前提です。ただし、確認結果の記述が今の実装と合っていません(下記)。

要確認: PR 本文が古いです

  • 本文は「os:admin の talosctl で talosctl kubeconfig をその場でもらう」と書いていますが、実装は CA から証明書を直接作る方式です。10a5e6c で変わっています。
  • タイトルの「その場でもらう」と、「確かめたこと」も同じ状態です。「確かめたこと」は前の実装での結果に見えます。
  • 今の実装で --admin の kubectl auth can-i '*' '*' と get nodes が通ることを、もう一度確かめて本文を直してください。
  • 特に system:masters の証明書を kube-apiserver が受け付けるかは、この実装では未確認のはずです。読み取り用は同じ CA で通っているので、通る見込みは高いです。

@5ym 5ym changed the title tools: 管理者の kubeconfig もその場でもらう tools: 管理者の kubeconfig もファイルで持たず、その場で作る Oct 17, 2026
@5ym
5ym merged commit 1fd26a7 into main Oct 17, 2026
3 checks passed
@5ym
5ym deleted the tools-admin-kubeconfig-on-the-fly branch October 17, 2026 06:53
5ym added a commit that referenced this pull request Oct 17, 2026
5ym added a commit that referenced this pull request Oct 17, 2026
* bootstrap/ を Talos だけの形にする: CA を 1 枚に、Talos の上書きを正本に畳む、Namespace を先に当てる

- bootstrap/apiserver/ca.crt から k3s の CA を消す。残る 1 枚は talos/clusterconfig の kubeconfig の
  certificate-authority-data と同じもの(SHA-256 A5:76:EF:…:39:D0 で突き合わせた)
- talos/cilium-values.yaml と talos/cert-manager-values.yaml を bootstrap/ の values.yaml に畳む。
  重ねる相手の k3s が無くなったので 2 枚に分ける意味が無い。CI と同じダミーの秘密で render.sh を
  前後で回し、鍵・証明書と毎回変わる値を除いて生成物が同じことを確かめた
- cilium-drift から k3s の分岐を消す
- bootstrap-apply は Namespace を先に当てる。まっさらなクラスタでは中身と同じ apply に渡すと
  `namespaces "auth" not found` で落ちた(2026-10-17)
- talos-validate を bootstrap/cilium・cert-manager の変更でも走らせる(render.sh が読む)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JbmWyUB9jcBcYCnNyiGBSV

* etcd の日次スナップショットを有効にする: talos/after-migration/ から apps/k8up/ へ

k3s には talos.dev/v1alpha1 の CRD が無いので寄せてあったもの。Talos に移ったので置く。
時刻は 13:45 UTC から 13:00 UTC にずらす(13:30 に matrix の Schedule が入っていて、forget の
ロックとぶつかる)。talos/patches/etcd-backup.yaml の参照も直す。

マージされたら 1 回手で回して R2 に入ることを見る:
  kubectl -n k8up create job --from=cronjob/etcd-snapshot etcd-snapshot-first

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JbmWyUB9jcBcYCnNyiGBSV

* k3s / Ubuntu 期のものを消す: ホストのバックアップ・復元スクリプト・drift.sh とコメント

SSD は Talos で上書き済みで、戻る先のホストはもう無い。

- 消す: backup/(k3s-backup と systemd unit)、recovery/restore.sh、talos/drift.sh(Ubuntu の
  ホストと比べる道具)、docs/restore-drill.md(k3s ホストを QEMU で戻すドリル)、
  bootstrap/apiserver/authentication-config.yaml(k3s の /etc/rancher/k3s/ に置いていた写し。
  正本は talos/patches/apiserver.yaml で、理由のコメントはあちらへ移した。YAML の値は変えていない)
- notify.yaml から、ホストのスクリプトの複数経路のスナップショットを見分けるコードを消す
  (k8up も etcd も経路は 1 つなので使われない)
- apps/・talos/・bootstrap/ のコメントから「k3s 期は…」「Ubuntu 期は…」を外し、
  今も効いている理由だけ残す。talos/patches/*.yaml はコメントだけで、値は変えていない
  (CI と同じダミーの秘密で render.sh が通ることを確かめた)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JbmWyUB9jcBcYCnNyiGBSV

* 建て直しの手順を Talos → Talos に書き直す: recovery/README.md を入口にし、migration-day.md を畳む

2026-10-17 に実機で通した順をそのまま手順にした。migration-day.md(1 回きりの移行の手順)のうち
今も効くもの(ISO の起動、apply-config の前に見るもの、Argo CD の待ち方、疎通確認の表、
詰まったときに見るところ)はここへ移して消す。

踏んだもの(理由は手順の横と道具の中に書いた):
- J:COM 側の PC からは 10.10.0.4(eno4)にしか届かない。kubeconfig の server を差し替える
- render.sh は出力先を丸ごと消す。kubeconfig は ~/.kube/config に取り直す
- USB は STATE / EPHEMERAL / u-local-path が ready になってから抜く
- bootstrap apply の nodePort は Gateway の Service ができてからでないと当たらない(もう 1 回流す)
- k8up の資格情報が Infisical から来るので、Infisical だけは手元の restic で直接戻す
  (recovery/infisical.sh)。DROP SCHEMA public は max_locks_per_transaction が足りず落ちるので
  old_public に退けて流し、あとで分けて消す
- DB を戻すと Infisical の Kubernetes auth の CA が古いクラスタのものに戻る。PATCH して operator を
  蹴り直す(recovery/infisical.sh ca / infisical-ca.mjs)
- k8up の Restore は root で、数字だけの ID は引用符で。バイナリは kubectl exec -i の標準入力で
  流さない(SQLite の末尾が欠けた)。Argo CD の selfHeal が replicas を戻すので application-controller
  を止めてから。Forgejo を先に。matrix は --restore-backup で 1 回起こす(recovery/pv.sh)

pv.sh と infisical.sh は当日使った道具から namespace とスナップショット ID の決め打ちを外したもの。
引数にした形ではまだ流していない。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JbmWyUB9jcBcYCnNyiGBSV

* 文書を Talos だけの形に圧縮する: 済んだ移行の段取りと k3s 期の比較を落とし、理由だけ残す

- ROADMAP: 済んだ Phase 2 を 1 行の記録にし、残りを Phase 2.5(Z440)と Phase 3 に。
  前のホストのスナップショット(host=main)はもう誰も forget しないことを Phase 3 に足した
- talos/README.md: 入れ方は recovery/ へ寄せ、組み立てと当て直しだけに。描くたびに変わる値
  (Hubble の CA と証明書、infisical の postgres-password)が差分に出ても害が無いことを当て直しの横に書いた
- docs/talos.md: メディアの作り方(移行当日の手順への参照)と、Ubuntu のホストの上で QEMU を回す
  手順を落とす。モジュールが名前の順に読まれる件を作法の表に足した
- docs/decisions.md: k3s 期と Talos 期の比較表、HelmChart CRD から Application への移し方、
  Traefik の切り替えの段取りを落とし、今の形を縛っている理由だけ残す
- bootstrap/README.md・apps/k8up/README.md・router.md・cloudflare-tokens.md・tools/README.md・
  README.md・z440-migration.md から k3s / Ubuntu の手順と /etc/k3s-backup/env を外す

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JbmWyUB9jcBcYCnNyiGBSV

* AdGuard の使われていない PVC adguardhome-ssl を消す

DoT の証明書は cert-manager の Secret(adguard-dot-tls)を同じ名前のボリューム adguardhome-ssl で
マウントしていて、同名の PVC はどの Pod も使っていない(Traefik の acme-watcher が書き出していた頃の残り)。
local-path は使う Pod が付くまで bind しないので、建て直しのあとは Pending のままで、
2026-10-17 の Restore で初めて bind した。中身は古い証明書だけ。

Argo CD の prune で PVC と PV(Delete)が消える。restic の /data/adguardhome-ssl は残る
(通知はスナップショットが途切れてから 8 日鳴る)。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JbmWyUB9jcBcYCnNyiGBSV

* 建て直しの手順を tools/creds.sh(#403・#405)に合わせる

kubectl / talosctl の資格情報と行き先(10.10.0.4)は t.ps1 が用意するようになったので、
--talosconfig・-n/-e・kubeconfig の取り直しと server の差し替えを手順から外し、
--admin のシェルで打つ形にする。upgrade-k8s は既定でクラスタの endpoint(10.0.0.2)に行くので
--endpoint https://10.10.0.4:6443 を渡す。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JbmWyUB9jcBcYCnNyiGBSV

* 建て直し: talos/kubeconfig.yaml が無いときに作る場所を 4 に書く

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JbmWyUB9jcBcYCnNyiGBSV

* 建て直し: 管理者の kubeconfig もその場で作る形(#407)に合わせる

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JbmWyUB9jcBcYCnNyiGBSV

* recovery: 流し直しに耐えるようにする(レビューの指摘)

- pv.sh stop は控えがあれば書き直さない(2 回目で「元は 0」を控えてしまう)。start は控えを使ったら消す
- pv.sh pgload は psql が落ちたらダンプを消さずに残す
- infisical.sh db は old_public が残っていれば止まる、流し込んだあと users が 0 なら Infisical を起こさない
- infisical.sh ca は port-forward が /api/status に答えるまで待つ

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JbmWyUB9jcBcYCnNyiGBSV

* recovery: 道具がまだ引数の形で流していないことを入口に書く

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JbmWyUB9jcBcYCnNyiGBSV

* bootstrap-apply: Namespace が見つからなければ止める / pv.sh: 経路が無いときに分かるように言う(レビューの指摘)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JbmWyUB9jcBcYCnNyiGBSV

* infisical.sh db: ダンプを取れてから public を退ける(レビューの指摘)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JbmWyUB9jcBcYCnNyiGBSV

* infisical.sh db: 手元のダンプはどこで落ちても消す

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JbmWyUB9jcBcYCnNyiGBSV

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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.

1 participant