diff --git a/manifests/charts/base/templates/agentcube-router.yaml b/manifests/charts/base/templates/agentcube-router.yaml index 6a23874b..9e4410e6 100644 --- a/manifests/charts/base/templates/agentcube-router.yaml +++ b/manifests/charts/base/templates/agentcube-router.yaml @@ -23,7 +23,30 @@ spec: {{- toYaml . | nindent 8 }} {{- end }} containers: + {{- if .Values.spire.enabled }} + - name: spiffe-helper + image: "{{ .Values.spire.spiffeHelper.image.repository }}:{{ .Values.spire.spiffeHelper.image.tag }}" + imagePullPolicy: {{ .Values.spire.spiffeHelper.image.pullPolicy }} + args: + - "-config" + - "/etc/spiffe-helper/spiffe-helper.conf" + volumeMounts: + - name: spiffe-helper-config + mountPath: /etc/spiffe-helper + readOnly: true + - name: spire-agent-socket + mountPath: /run/spire/sockets + readOnly: true + - name: spire-certs + mountPath: {{ .Values.spire.spiffeHelper.certDir }} + {{- end }} - name: agentcube-router + {{- if .Values.spire.enabled }} + volumeMounts: + - name: spire-certs + mountPath: {{ .Values.spire.spiffeHelper.certDir }} + readOnly: true + {{- end }} image: "{{ .Values.router.image.repository }}:{{ .Values.router.image.tag }}" imagePullPolicy: {{ .Values.router.image.pullPolicy }} ports: @@ -61,6 +84,18 @@ spec: port: {{ .Values.router.service.targetPort }} initialDelaySeconds: 1 periodSeconds: 2 + {{- if .Values.spire.enabled }} + volumes: + - name: spire-agent-socket + hostPath: + path: /run/spire/sockets + type: DirectoryOrCreate + - name: spiffe-helper-config + configMap: + name: spiffe-helper-config + - name: spire-certs + emptyDir: {} + {{- end }} --- apiVersion: v1 diff --git a/manifests/charts/base/templates/rbac-router.yaml b/manifests/charts/base/templates/rbac-router.yaml index 76823bd9..4f3ecc06 100644 --- a/manifests/charts/base/templates/rbac-router.yaml +++ b/manifests/charts/base/templates/rbac-router.yaml @@ -1,31 +1,29 @@ -{{- if .Values.router.rbac.create }} -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ .Values.router.serviceAccountName | default "agentcube-router" }} - namespace: {{ .Release.Namespace }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: {{ .Values.router.serviceAccountName | default "agentcube-router" }} - namespace: {{ .Release.Namespace }} -rules: - - apiGroups: [""] - resources: ["secrets"] - verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - name: {{ .Values.router.serviceAccountName | default "agentcube-router" }} - namespace: {{ .Release.Namespace }} -subjects: - - kind: ServiceAccount - name: {{ .Values.router.serviceAccountName | default "agentcube-router" }} - namespace: {{ .Release.Namespace }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: {{ .Values.router.serviceAccountName | default "agentcube-router" }} -{{- end }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.router.serviceAccountName | default "agentcube-router" }} + namespace: {{ .Release.Namespace }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ .Values.router.serviceAccountName | default "agentcube-router" }} + namespace: {{ .Release.Namespace }} +rules: + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "create"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ .Values.router.serviceAccountName | default "agentcube-router" }} + namespace: {{ .Release.Namespace }} +subjects: + - kind: ServiceAccount + name: {{ .Values.router.serviceAccountName | default "agentcube-router" }} + namespace: {{ .Release.Namespace }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ .Values.router.serviceAccountName | default "agentcube-router" }} diff --git a/manifests/charts/base/templates/spire/cluster-spiffe-ids.yaml b/manifests/charts/base/templates/spire/cluster-spiffe-ids.yaml new file mode 100644 index 00000000..c0b84d5a --- /dev/null +++ b/manifests/charts/base/templates/spire/cluster-spiffe-ids.yaml @@ -0,0 +1,45 @@ +{{- if .Values.spire.enabled }} +# Prerequisite: spire.spiffe.io CRDs must be present in the cluster before these resources can be created. +# The spire-controller-manager sidecar registers them automatically on first boot. +# For a fresh cluster, run: kubectl apply -f https://github.com/spiffe/spire-controller-manager/releases/download/v{{ .Values.spire.controllerManager.image.tag }}/crds.yaml +# Router registration +apiVersion: spire.spiffe.io/v1alpha1 +kind: ClusterSPIFFEID +metadata: + name: {{ .Release.Name }}-agentcube-router +spec: + spiffeIDTemplate: "spiffe://{{ .Values.spire.trustDomain }}/ns/{{ "{{ .PodMeta.Namespace }}" }}/sa/{{ "{{ .PodSpec.ServiceAccountName }}" }}" + podSelector: + matchLabels: + app: agentcube-router + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: {{ .Release.Namespace }} + +--- +# WorkloadManager registration +apiVersion: spire.spiffe.io/v1alpha1 +kind: ClusterSPIFFEID +metadata: + name: {{ .Release.Name }}-agentcube-workload-manager +spec: + spiffeIDTemplate: "spiffe://{{ .Values.spire.trustDomain }}/ns/{{ "{{ .PodMeta.Namespace }}" }}/sa/{{ "{{ .PodSpec.ServiceAccountName }}" }}" + podSelector: + matchLabels: + app: workloadmanager + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: {{ .Release.Namespace }} + +--- +# PicoD (Sandbox) registration - namespace-agnostic +apiVersion: spire.spiffe.io/v1alpha1 +kind: ClusterSPIFFEID +metadata: + name: {{ .Release.Name }}-agentcube-sandbox +spec: + spiffeIDTemplate: "spiffe://{{ .Values.spire.trustDomain }}/sa/{{ "{{ .PodSpec.ServiceAccountName }}" }}" + podSelector: + matchLabels: + app: picod +{{- end }} diff --git a/manifests/charts/base/templates/spire/rbac.yaml b/manifests/charts/base/templates/spire/rbac.yaml new file mode 100644 index 00000000..0741cec9 --- /dev/null +++ b/manifests/charts/base/templates/spire/rbac.yaml @@ -0,0 +1,114 @@ +{{- if .Values.spire.enabled }} +# --- SPIRE Server --- +# Also used by the Controller Manager sidecar running in the same pod +apiVersion: v1 +kind: ServiceAccount +metadata: + name: spire-server + namespace: {{ .Release.Namespace }} + labels: + app: spire-server +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ .Release.Name }}-spire-server + labels: + app: spire-server +rules: + # Required for k8s_psat NodeAttestor to validate projected service account tokens + - apiGroups: ["authentication.k8s.io"] + resources: ["tokenreviews"] + verbs: ["create"] + # Required for k8s_psat NodeAttestor to query pod identity during attestation + - apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list", "watch"] + # Required for node attestation and registration entry management + - apiGroups: [""] + resources: ["nodes"] + verbs: ["get", "list", "watch"] + # Required by Controller Manager sidecar to watch and sync ClusterSPIFFEID CRDs + - apiGroups: ["spire.spiffe.io"] + resources: ["clusterspiffeids", "clusterfederatedtrustdomains", "clusterstaticentries"] + verbs: ["get", "list", "watch", "create", "update", "patch"] + - apiGroups: ["spire.spiffe.io"] + resources: ["clusterspiffeids/status", "clusterfederatedtrustdomains/status", "clusterstaticentries/status"] + verbs: ["get", "update", "patch"] + # Required by Controller Manager sidecar to resolve namespaces for namespaceSelector + - apiGroups: [""] + resources: ["namespaces", "endpoints"] + verbs: ["get", "list", "watch"] + # Required by Controller Manager sidecar for leader election + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "list", "watch", "create", "update", "patch"] + - apiGroups: [""] + resources: ["events"] + verbs: ["create", "patch"] + # Required by Controller Manager sidecar to manage its webhook certificate + - apiGroups: ["admissionregistration.k8s.io"] + resources: ["validatingwebhookconfigurations"] + verbs: ["get", "list", "watch", "create"] + - apiGroups: ["admissionregistration.k8s.io"] + resources: ["validatingwebhookconfigurations"] + resourceNames: ["{{ .Release.Name }}-spire-controller-manager-webhook"] + verbs: ["update", "patch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ .Release.Name }}-spire-server + labels: + app: spire-server +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ .Release.Name }}-spire-server +subjects: + - kind: ServiceAccount + name: spire-server + namespace: {{ .Release.Namespace }} +--- + +# --- SPIRE Agent --- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: spire-agent + namespace: {{ .Release.Namespace }} + labels: + app: spire-agent +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ .Release.Name }}-spire-agent + labels: + app: spire-agent +rules: + # Required for k8s workload attestor to query pod metadata from kubelet + - apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list"] + # Required for workload attestation to resolve node information and proxy requests to kubelet + - apiGroups: [""] + resources: ["nodes", "nodes/proxy"] + verbs: ["get", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ .Release.Name }}-spire-agent + labels: + app: spire-agent +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ .Release.Name }}-spire-agent +subjects: + - kind: ServiceAccount + name: spire-agent + namespace: {{ .Release.Namespace }} +{{- end }} + diff --git a/manifests/charts/base/templates/spire/spiffe-helper-config.yaml b/manifests/charts/base/templates/spire/spiffe-helper-config.yaml new file mode 100644 index 00000000..a1a9cd5b --- /dev/null +++ b/manifests/charts/base/templates/spire/spiffe-helper-config.yaml @@ -0,0 +1,19 @@ +{{- if .Values.spire.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: spiffe-helper-config + namespace: {{ .Release.Namespace }} + labels: + app: spiffe-helper +data: + spiffe-helper.conf: | + agent_address = "/run/spire/sockets/agent.sock" + cmd = "" + cmd_args = "" + cert_dir = "{{ .Values.spire.spiffeHelper.certDir }}" + renew_signal = "SIGHUP" + svid_file_name = "{{ .Values.spire.spiffeHelper.certFileName }}" + svid_key_file_name = "{{ .Values.spire.spiffeHelper.keyFileName }}" + svid_bundle_file_name = "{{ .Values.spire.spiffeHelper.bundleFileName }}" +{{- end }} diff --git a/manifests/charts/base/templates/spire/spire-agent.yaml b/manifests/charts/base/templates/spire/spire-agent.yaml new file mode 100644 index 00000000..ddda667c --- /dev/null +++ b/manifests/charts/base/templates/spire/spire-agent.yaml @@ -0,0 +1,113 @@ +{{- if .Values.spire.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: spire-agent-config + namespace: {{ .Release.Namespace }} + labels: + app: spire-agent +data: + agent.conf: | + agent { + data_dir = "/run/spire/data" + log_level = "INFO" + server_address = "spire-server.{{ .Release.Namespace }}.svc.cluster.local" + server_port = "{{ .Values.spire.server.service.port }}" + socket_path = "/run/spire/sockets/agent.sock" + trust_domain = "{{ .Values.spire.trustDomain }}" + insecure_bootstrap = {{ .Values.spire.agent.insecureBootstrap | default false }} # Set true only when intentionally bootstrapping without a pre-existing trust bundle + } + + plugins { + NodeAttestor "k8s_psat" { + plugin_data { + cluster = "{{ .Values.spire.clusterName }}" + } + } + + KeyManager "memory" { + plugin_data {} + } + + WorkloadAttestor "k8s" { + plugin_data { + skip_kubelet_verification = {{ .Values.spire.agent.skipKubeletVerification | default false }} # Set true only in dev scenarios with self-signed kubelets + } + } + } + +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: spire-agent + namespace: {{ .Release.Namespace }} + labels: + app: spire-agent +spec: + selector: + matchLabels: + app: spire-agent + template: + metadata: + labels: + app: spire-agent + spec: + serviceAccountName: spire-agent + hostPID: true # Required for workload attestation (process identity) + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet + containers: + - name: spire-agent + image: "{{ .Values.spire.agent.image.repository }}:{{ .Values.spire.agent.image.tag }}" + imagePullPolicy: {{ .Values.spire.agent.image.pullPolicy }} + args: ["-config", "/run/spire/config/agent.conf"] + volumeMounts: + - name: spire-agent-socket + mountPath: /run/spire/sockets + - name: spire-config + mountPath: /run/spire/config + readOnly: true + - name: spire-token + mountPath: /var/run/secrets/tokens + env: + - name: MY_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + livenessProbe: + exec: + command: + - /opt/spire/bin/spire-agent + - healthcheck + - -socketPath + - /run/spire/sockets/agent.sock + initialDelaySeconds: 15 + periodSeconds: 60 + readinessProbe: + exec: + command: + - /opt/spire/bin/spire-agent + - healthcheck + - -socketPath + - /run/spire/sockets/agent.sock + initialDelaySeconds: 5 + periodSeconds: 10 + resources: + {{- toYaml .Values.spire.agent.resources | nindent 12 }} + volumes: + - name: spire-agent-socket + hostPath: + path: /run/spire/sockets # Workload API socket shared with pods on this node + type: DirectoryOrCreate + - name: spire-config + configMap: + name: spire-agent-config + - name: spire-token + projected: + sources: + - serviceAccountToken: + audience: spire-server # Projected token for k8s_psat node attestation + expirationSeconds: 7200 + path: spire-agent +{{- end }} diff --git a/manifests/charts/base/templates/spire/spire-controller-manager.yaml b/manifests/charts/base/templates/spire/spire-controller-manager.yaml new file mode 100644 index 00000000..a017af87 --- /dev/null +++ b/manifests/charts/base/templates/spire/spire-controller-manager.yaml @@ -0,0 +1,31 @@ +{{- if .Values.spire.enabled }} +# Controller Manager ConfigMap +# The Controller Manager runs as a sidecar in the spire-server StatefulSet +apiVersion: v1 +kind: ConfigMap +metadata: + name: spire-controller-manager-config + namespace: {{ .Release.Namespace }} + labels: + app: spire-controller-manager +data: + spire-controller-manager.yaml: | + apiVersion: spire.spiffe.io/v1alpha1 + kind: ControllerManagerConfig + metrics: + bindAddress: 127.0.0.1:8082 + health: + healthProbeBindAddress: :8083 + leaderElection: + leaderElect: true + resourceName: spire-controller-manager + resourceNamespace: {{ .Release.Namespace }} + spireServerSocketPath: "/tmp/spire-server/private/api.sock" + clusterName: {{ .Values.spire.clusterName }} + trustDomain: {{ .Values.spire.trustDomain }} + validatingWebhookConfigurationName: {{ .Release.Name }}-spire-controller-manager-webhook + ignoreNamespaces: + - kube-system + - kube-public + - local-path-storage +{{- end }} diff --git a/manifests/charts/base/templates/spire/spire-server.yaml b/manifests/charts/base/templates/spire/spire-server.yaml new file mode 100644 index 00000000..58b064fc --- /dev/null +++ b/manifests/charts/base/templates/spire/spire-server.yaml @@ -0,0 +1,191 @@ +{{- if .Values.spire.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: spire-server-config + namespace: {{ .Release.Namespace }} + labels: + app: spire-server +data: + server.conf: | + server { + bind_address = "0.0.0.0" + bind_port = "{{ .Values.spire.server.service.port }}" + socket_path = "/tmp/spire-server/private/api.sock" + trust_domain = "{{ .Values.spire.trustDomain }}" + data_dir = "/run/spire/data" + + ca_ttl = "{{ .Values.spire.server.ca.ttl }}" + default_x509_svid_ttl = "{{ .Values.spire.server.ca.x509SvidDefaultTtl }}" + } + + plugins { + DataStore "sql" { + plugin_data { + database_type = "{{ .Values.spire.server.dataStore.type }}" + connection_string = "{{ .Values.spire.server.dataStore.connectionString }}" + } + } + + NodeAttestor "k8s_psat" { + plugin_data { + clusters = { + "{{ .Values.spire.clusterName }}" = { + service_account_allow_list = [ + "{{ .Release.Namespace }}:spire-agent" + ] + } + } + } + } + + KeyManager "disk" { + plugin_data { + keys_path = "/run/spire/data/keys.json" + } + } + } + +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: spire-server + namespace: {{ .Release.Namespace }} + labels: + app: spire-server +spec: + replicas: 1 + selector: + matchLabels: + app: spire-server + serviceName: spire-server-headless + template: + metadata: + labels: + app: spire-server + spec: + serviceAccountName: spire-server + containers: + - name: spire-server + image: "{{ .Values.spire.server.image.repository }}:{{ .Values.spire.server.image.tag }}" + imagePullPolicy: {{ .Values.spire.server.image.pullPolicy }} + args: ["-config", "/run/spire/config/server.conf"] + ports: + - name: grpc + containerPort: {{ .Values.spire.server.service.port }} + protocol: TCP + volumeMounts: + - name: spire-config + mountPath: /run/spire/config + readOnly: true + - name: spire-data + mountPath: /run/spire/data + - name: spire-server-socket + mountPath: /tmp/spire-server/private + livenessProbe: + exec: + command: + - /opt/spire/bin/spire-server + - healthcheck + initialDelaySeconds: 15 + periodSeconds: 60 + readinessProbe: + exec: + command: + - /opt/spire/bin/spire-server + - healthcheck + initialDelaySeconds: 5 + periodSeconds: 10 + resources: + {{- toYaml .Values.spire.server.resources | nindent 12 }} + # Controller Manager runs as a sidecar, sharing the SPIRE Server's API socket + - name: spire-controller-manager + image: "{{ .Values.spire.controllerManager.image.repository }}:{{ .Values.spire.controllerManager.image.tag }}" + imagePullPolicy: {{ .Values.spire.controllerManager.image.pullPolicy }} + args: + - -config + - /etc/spire-controller-manager/spire-controller-manager.yaml + ports: + - name: https + containerPort: 9443 + protocol: TCP + - name: health + containerPort: 8083 + protocol: TCP + volumeMounts: + - name: spire-server-socket + mountPath: /tmp/spire-server/private + readOnly: false + - name: controller-manager-config + mountPath: /etc/spire-controller-manager + readOnly: true + livenessProbe: + httpGet: + path: /healthz + port: health + initialDelaySeconds: 15 + periodSeconds: 60 + readinessProbe: + httpGet: + path: /readyz + port: health + initialDelaySeconds: 5 + periodSeconds: 10 + resources: + {{- toYaml .Values.spire.controllerManager.resources | nindent 12 }} + volumes: + - name: spire-config + configMap: + name: spire-server-config + - name: spire-server-socket + emptyDir: {} # Shared between SPIRE Server and Controller Manager for API socket + - name: controller-manager-config + configMap: + name: spire-controller-manager-config + volumeClaimTemplates: + - metadata: + name: spire-data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + +--- +apiVersion: v1 +kind: Service +metadata: + name: spire-server-headless + namespace: {{ .Release.Namespace }} + labels: + app: spire-server +spec: + clusterIP: None + ports: + - name: grpc + port: {{ .Values.spire.server.service.port }} + targetPort: {{ .Values.spire.server.service.port }} + protocol: TCP + selector: + app: spire-server + +--- +apiVersion: v1 +kind: Service +metadata: + name: spire-server + namespace: {{ .Release.Namespace }} + labels: + app: spire-server +spec: + type: {{ .Values.spire.server.service.type }} + ports: + - name: grpc + port: {{ .Values.spire.server.service.port }} + targetPort: {{ .Values.spire.server.service.port }} + protocol: TCP + selector: + app: spire-server +{{- end }} diff --git a/manifests/charts/base/templates/spire/validating-webhook.yaml b/manifests/charts/base/templates/spire/validating-webhook.yaml new file mode 100644 index 00000000..045f242d --- /dev/null +++ b/manifests/charts/base/templates/spire/validating-webhook.yaml @@ -0,0 +1,42 @@ +{{- if .Values.spire.enabled }} +# Service to expose the Controller Manager webhook (which runs as a sidecar in spire-server pod) +apiVersion: v1 +kind: Service +metadata: + name: spire-controller-manager-webhook + namespace: {{ .Release.Namespace }} + labels: + app: spire-server +spec: + type: ClusterIP + ports: + - name: https + port: 443 + targetPort: 9443 + protocol: TCP + selector: + app: spire-server +--- +# The ValidatingWebhookConfiguration object patched by the Controller Manager +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: {{ .Release.Name }}-spire-controller-manager-webhook + labels: + app: spire-controller-manager +webhooks: + - name: spire-controller-manager-webhook.spiffe.io + clientConfig: + service: + name: spire-controller-manager-webhook + namespace: {{ .Release.Namespace }} + path: /validate-spire-spiffe-io-v1alpha1-clusterspiffeid + rules: + - apiGroups: ["spire.spiffe.io"] + apiVersions: ["v1alpha1"] + operations: ["CREATE", "UPDATE"] + resources: ["clusterspiffeids"] + sideEffects: None + failurePolicy: Ignore + admissionReviewVersions: ["v1", "v1beta1"] +{{- end }} diff --git a/manifests/charts/base/templates/workloadmanager.yaml b/manifests/charts/base/templates/workloadmanager.yaml index 04d84df0..5a02bc98 100644 --- a/manifests/charts/base/templates/workloadmanager.yaml +++ b/manifests/charts/base/templates/workloadmanager.yaml @@ -21,7 +21,30 @@ spec: {{- toYaml . | nindent 8 }} {{- end }} containers: + {{- if .Values.spire.enabled }} + - name: spiffe-helper + image: "{{ .Values.spire.spiffeHelper.image.repository }}:{{ .Values.spire.spiffeHelper.image.tag }}" + imagePullPolicy: {{ .Values.spire.spiffeHelper.image.pullPolicy }} + args: + - "-config" + - "/etc/spiffe-helper/spiffe-helper.conf" + volumeMounts: + - name: spiffe-helper-config + mountPath: /etc/spiffe-helper + readOnly: true + - name: spire-agent-socket + mountPath: /run/spire/sockets + readOnly: true + - name: spire-certs + mountPath: {{ .Values.spire.spiffeHelper.certDir }} + {{- end }} - name: workloadmanager + {{- if .Values.spire.enabled }} + volumeMounts: + - name: spire-certs + mountPath: {{ .Values.spire.spiffeHelper.certDir }} + readOnly: true + {{- end }} image: "{{ .Values.workloadmanager.image.repository }}:{{ .Values.workloadmanager.image.tag }}" imagePullPolicy: {{ .Values.workloadmanager.image.pullPolicy }} ports: @@ -57,6 +80,18 @@ spec: port: {{ .Values.workloadmanager.service.port }} initialDelaySeconds: 5 periodSeconds: 5 + {{- if .Values.spire.enabled }} + volumes: + - name: spire-agent-socket + hostPath: + path: /run/spire/sockets + type: DirectoryOrCreate + - name: spiffe-helper-config + configMap: + name: spiffe-helper-config + - name: spire-certs + emptyDir: {} + {{- end }} --- apiVersion: v1 diff --git a/manifests/charts/base/values.yaml b/manifests/charts/base/values.yaml index 25a07979..4690aeb1 100644 --- a/manifests/charts/base/values.yaml +++ b/manifests/charts/base/values.yaml @@ -31,9 +31,7 @@ router: memory: 128Mi config: {} extraEnv: [] - serviceAccountName: "" - rbac: - create: false + serviceAccountName: "agentcube-router" # AgentCube Workload Manager workloadmanager: @@ -63,3 +61,70 @@ volcano: repository: ghcr.io/volcano-sh/vc-agent-scheduler pullPolicy: IfNotPresent tag: "latest" + +# SPIRE Configuration (Internal Workload Identity) +spire: + enabled: false + trustDomain: "cluster.local" + clusterName: "agentcube-cluster" + spiffeHelper: + # Configuration for the spiffe-helper sidecar which automatically fetches and rotates mTLS certificates + image: + repository: ghcr.io/spiffe/spiffe-helper + tag: "0.8.0" + pullPolicy: IfNotPresent + # Directory inside workload pods where the sidecar will deliver the certificates + certDir: "/run/spire/certs" + # Desired file names for the SVID certificate, private key, and root trust bundle + certFileName: "svid.pem" + keyFileName: "svid_key.pem" + bundleFileName: "svid_bundle.pem" + server: + image: + repository: ghcr.io/spiffe/spire-server + tag: "1.12.0" + pullPolicy: IfNotPresent + service: + type: ClusterIP + port: 8081 + ca: + ttl: "24h" + x509SvidDefaultTtl: "1h" + dataStore: + type: "sqlite3" + connectionString: "/run/spire/data/datastore.sqlite3" + resources: + limits: + cpu: 200m + memory: 512Mi + requests: + cpu: 50m + memory: 128Mi + agent: + # For local dev clusters (kind/minikube), override with: --set spire.agent.insecureBootstrap=true --set spire.agent.skipKubeletVerification=true + insecureBootstrap: false + skipKubeletVerification: false + image: + repository: ghcr.io/spiffe/spire-agent + tag: "1.12.0" + pullPolicy: IfNotPresent + resources: + limits: + cpu: 200m + memory: 256Mi + requests: + cpu: 50m + memory: 64Mi + controllerManager: + image: + repository: ghcr.io/spiffe/spire-controller-manager + tag: "0.6.4" + pullPolicy: IfNotPresent + resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 50m + memory: 64Mi +