Helm chart (charts/bascule/): Deployment with shell sidecar container (shared jumphost model) Service (LoadBalancer/NodePort/ClusterIP) ConfigMap with auto-generated config.toml RBAC (Role + RoleBinding for pods/exec) NetworkPolicy (restrict shell egress, allow DNS + K8s API) ServiceAccount with create flag Configurable shell image (k8s-ops, net-ops, dev, minimal) Helm lint passes clean K8s backend config (bascule-core): [k8s] section: enabled, namespace, pod_name, shell_container, shell Auto-detection via POD_NAME/POD_NAMESPACE env vars (downward API) Backend priority: K8s > proxy > container > local PTY K8s exec implementation deferred to --features k8s (kube crate) SPIFFE/SPIRE auth config: [auth.spiffe] section: trust_domain, trust_bundle_path, workload_api_socket JWT-SVID token-as-password authentication pattern Implementation deferred to bascule-auth-spiffe crate Zero substrate dependencies. Default build unchanged. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
102 lines
3.2 KiB
YAML
102 lines
3.2 KiB
YAML
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: {{ include "bascule.fullname" . }}
|
|
labels:
|
|
{{- include "bascule.labels" . | nindent 4 }}
|
|
spec:
|
|
replicas: {{ .Values.replicaCount }}
|
|
selector:
|
|
matchLabels:
|
|
{{- include "bascule.selectorLabels" . | nindent 6 }}
|
|
template:
|
|
metadata:
|
|
labels:
|
|
{{- include "bascule.selectorLabels" . | nindent 8 }}
|
|
spec:
|
|
serviceAccountName: {{ include "bascule.serviceAccountName" . }}
|
|
containers:
|
|
- name: bascule
|
|
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
|
|
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
|
ports:
|
|
- name: ssh
|
|
containerPort: 2222
|
|
protocol: TCP
|
|
env:
|
|
- name: BASCULE_CONFIG
|
|
value: /etc/bascule/config.toml
|
|
- name: POD_NAME
|
|
valueFrom:
|
|
fieldRef:
|
|
fieldPath: metadata.name
|
|
- name: POD_NAMESPACE
|
|
valueFrom:
|
|
fieldRef:
|
|
fieldPath: metadata.namespace
|
|
- name: BASCULE_SHELL_CONTAINER
|
|
value: shell
|
|
{{- range .Values.extraEnv }}
|
|
- name: {{ .name }}
|
|
value: {{ .value | quote }}
|
|
{{- end }}
|
|
volumeMounts:
|
|
- name: config
|
|
mountPath: /etc/bascule
|
|
readOnly: true
|
|
{{- if .Values.hostKey.persistence }}
|
|
- name: hostkey
|
|
mountPath: /var/lib/bascule
|
|
{{- end }}
|
|
{{- if .Values.auth.authorizedKeysSecret }}
|
|
- name: authorized-keys
|
|
mountPath: /etc/bascule/keys
|
|
readOnly: true
|
|
{{- end }}
|
|
resources:
|
|
{{- toYaml .Values.resources | nindent 12 }}
|
|
livenessProbe:
|
|
tcpSocket:
|
|
port: ssh
|
|
initialDelaySeconds: 5
|
|
periodSeconds: 30
|
|
readinessProbe:
|
|
tcpSocket:
|
|
port: ssh
|
|
initialDelaySeconds: 3
|
|
periodSeconds: 10
|
|
{{- if .Values.shell.enabled }}
|
|
- name: shell
|
|
image: "{{ .Values.shell.image.repository }}:{{ .Values.shell.image.tag }}"
|
|
imagePullPolicy: {{ .Values.shell.image.pullPolicy }}
|
|
command: ["sleep", "infinity"]
|
|
resources:
|
|
{{- toYaml .Values.shell.resources | nindent 12 }}
|
|
securityContext:
|
|
allowPrivilegeEscalation: false
|
|
capabilities:
|
|
drop: ["ALL"]
|
|
add: ["SETUID", "SETGID"]
|
|
{{- end }}
|
|
volumes:
|
|
- name: config
|
|
configMap:
|
|
name: {{ include "bascule.fullname" . }}-config
|
|
{{- if .Values.hostKey.persistence }}
|
|
- name: hostkey
|
|
emptyDir: {}
|
|
{{- end }}
|
|
{{- if .Values.auth.authorizedKeysSecret }}
|
|
- name: authorized-keys
|
|
secret:
|
|
secretName: {{ .Values.auth.authorizedKeysSecret }}
|
|
defaultMode: 0600
|
|
{{- end }}
|
|
{{- with .Values.tolerations }}
|
|
tolerations:
|
|
{{- toYaml . | nindent 8 }}
|
|
{{- end }}
|
|
{{- with .Values.nodeSelector }}
|
|
nodeSelector:
|
|
{{- toYaml . | nindent 8 }}
|
|
{{- end }}
|