Merge pull request '引导 sandbox 跨集群 SPIRE 认证' (#87) from feat/sandbox-spire-bootstrap into main
yaml / yaml (push) Successful in 20s
ansible / collection-test (push) Successful in 1m15s
ansible / lint (push) Successful in 2m12s

Reviewed-on: #87
This commit was merged in pull request #87.
This commit is contained in:
2026-09-17 16:55:59 +00:00
13 changed files with 230 additions and 0 deletions
+9
View File
@@ -21,6 +21,15 @@ Root bootstrap 已完成。后续按依赖顺序分别引入:
第一阶段监控拆为 `monitoring-operator` 与依赖它的 `monitoring`,防止 VM CR 在
VictoriaMetrics Operator CRD Ready 前进入 reconciliation。
SPIRE 阶段先由 `spire-bootstrap` 安装 CRD,并声明只允许 `tokenreviews.create` 的
central Server reviewer。Agent ServiceAccount 留给后续 HelmRelease 创建,避免两个
声明方争夺同一资源。随后运行
`infrastructure/sandbox-cluster/ansible/spire-bootstrap.yml`:playbook 从 sandbox
读取 reviewer token,在内存中组成受限 kubeconfig,再通过 stdin reconcile 到 central
集群的 `spire-server/spire-external-kubeconfigs` Secret。凭据不写入仓库、日志或控制机
文件;该 Secret 准备完成后,才能启用 central external PSAT/controller-manager 和
sandbox Agent/CSI。
## 监控边界
这里只管理 sandbox LXC 内的 Kubernetes 监控,不负责 PVE 宿主监控。LXC 与宿主共享
@@ -0,0 +1,15 @@
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: spire-bootstrap
namespace: flux-system
spec:
interval: 10m
path: ./platform/sandbox-spire/bootstrap
prune: true
sourceRef:
kind: GitRepository
name: flux-system
timeout: 10m
wait: true
+1
View File
@@ -4,3 +4,4 @@ kind: Kustomization
resources:
- apps/monitoring-operator.yaml
- apps/monitoring.yaml
- apps/spire-bootstrap.yaml
+16
View File
@@ -108,6 +108,22 @@ homelab CA trust。Flux `v2.9.5` controllers 与 root sync 也由 Ansible 通过
server manifests 管理;root 使用 homelab CA 访问公开 Gitea 仓库,不保存 Git token。
集群内 workload 由 `clusters/sandbox/` 分阶段纳入 Flux。
## SPIRE 跨集群 bootstrap
Sandbox 复用 homelab 的 SPIRE Server 与 `ddupan.top` trust domain。Flux 首先安装
SPIRE CRD,并创建权限仅为 `authentication.k8s.io/tokenreviews.create` 的 reviewer。
在该 Kustomization Ready 后运行:
```bash
cd infrastructure/sandbox-cluster/ansible
ansible-playbook spire-bootstrap.yml
```
Playbook 不把 reviewer token 或生成的 kubeconfig 落盘,而是将目标 Secret manifest
通过 stdin 交给本机 homelab `k3s kubectl`。目标 Secret
`spire-server/spire-external-kubeconfigs` 由 Ansible 单独拥有;Flux 和人工操作不得写入。
第二次运行必须为零变更。
## 已验证的 Kata CI 前置条件
- Cloud Hypervisor 必须报告 `vm.info.config.memory.shared=true`;
@@ -0,0 +1,6 @@
---
sandbox_spire_bootstrap_api_server: https://10.60.0.13:6443
sandbox_spire_bootstrap_source_namespace: spire-system
sandbox_spire_bootstrap_source_secret: spire-server-token-reviewer-token
sandbox_spire_bootstrap_target_namespace: spire-server
sandbox_spire_bootstrap_target_secret: spire-external-kubeconfigs
@@ -0,0 +1,73 @@
---
- name: Wait for the sandbox SPIRE token reviewer credential
ansible.builtin.command:
argv:
- k3s
- kubectl
- --namespace
- "{{ sandbox_spire_bootstrap_source_namespace }}"
- get
- secret
- "{{ sandbox_spire_bootstrap_source_secret }}"
- --output=json
register: sandbox_spire_bootstrap_reviewer_secret
changed_when: false
retries: 60
delay: 10
until:
- sandbox_spire_bootstrap_reviewer_secret.rc == 0
- (sandbox_spire_bootstrap_reviewer_secret.stdout | from_json).data.token is defined
- (sandbox_spire_bootstrap_reviewer_secret.stdout | from_json).data['ca.crt'] is defined
no_log: true
- name: Extract the sandbox TokenReview credential data
ansible.builtin.set_fact:
sandbox_spire_bootstrap_secret_data: >-
{{ (sandbox_spire_bootstrap_reviewer_secret.stdout | from_json).data }}
no_log: true
- name: Build the restricted sandbox TokenReview kubeconfig
ansible.builtin.set_fact:
sandbox_spire_bootstrap_kubeconfig: |
apiVersion: v1
kind: Config
clusters:
- name: sandbox
cluster:
server: {{ sandbox_spire_bootstrap_api_server }}
certificate-authority-data: {{ sandbox_spire_bootstrap_secret_data['ca.crt'] }}
users:
- name: spire-server-token-reviewer
user:
token: {{ sandbox_spire_bootstrap_secret_data.token | b64decode }}
contexts:
- name: sandbox
context:
cluster: sandbox
user: spire-server-token-reviewer
current-context: sandbox
no_log: true
- name: Reconcile the central SPIRE external kubeconfig Secret
ansible.builtin.command:
argv:
- k3s
- kubectl
- apply
- --filename=-
stdin: |
apiVersion: v1
kind: Secret
metadata:
name: {{ sandbox_spire_bootstrap_target_secret }}
namespace: {{ sandbox_spire_bootstrap_target_namespace }}
type: Opaque
data:
sandbox: {{ sandbox_spire_bootstrap_kubeconfig | b64encode }}
delegate_to: localhost
become: true
register: sandbox_spire_bootstrap_target
changed_when: >-
' created' in sandbox_spire_bootstrap_target.stdout or
' configured' in sandbox_spire_bootstrap_target.stdout
no_log: true
@@ -52,3 +52,9 @@
gather_facts: false
roles:
- sandbox_flux
- name: Reconcile central SPIRE access to sandbox Kubernetes
hosts: sandbox1
gather_facts: false
roles:
- sandbox_spire_bootstrap
@@ -0,0 +1,6 @@
---
- name: Reconcile central SPIRE access to sandbox Kubernetes
hosts: sandbox1
gather_facts: false
roles:
- sandbox_spire_bootstrap
@@ -0,0 +1,31 @@
---
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: spire-crds
namespace: spire-mgmt
spec:
chart:
spec:
chart: spire-crds
interval: 1h
sourceRef:
kind: HelmRepository
name: spiffe-hardened
version: 0.6.1
driftDetection:
mode: enabled
install:
crds: CreateReplace
strategy:
name: RetryOnFailure
retryInterval: 5m
interval: 30m
releaseName: spire-crds
targetNamespace: spire-mgmt
timeout: 10m
upgrade:
crds: CreateReplace
strategy:
name: RetryOnFailure
retryInterval: 5m
@@ -0,0 +1,8 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespaces.yaml
- repository.yaml
- crds.yaml
- token-reviewer.yaml
@@ -0,0 +1,10 @@
---
apiVersion: v1
kind: Namespace
metadata:
name: spire-mgmt
---
apiVersion: v1
kind: Namespace
metadata:
name: spire-system
@@ -0,0 +1,9 @@
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: spiffe-hardened
namespace: spire-mgmt
spec:
interval: 1h
url: https://spiffe.github.io/helm-charts-hardened/
@@ -0,0 +1,40 @@
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: spire-server-token-reviewer
namespace: spire-system
---
apiVersion: v1
kind: Secret
metadata:
name: spire-server-token-reviewer-token
namespace: spire-system
annotations:
kubernetes.io/service-account.name: spire-server-token-reviewer
type: kubernetes.io/service-account-token
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: spire-server-token-reviewer
rules:
- apiGroups:
- authentication.k8s.io
resources:
- tokenreviews
verbs:
- create
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: spire-server-token-reviewer
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: spire-server-token-reviewer
subjects:
- kind: ServiceAccount
name: spire-server-token-reviewer
namespace: spire-system