feat(openbao): GX10 prod OpenBao StatefulSet (ADR-206 Phase-1)

Integrated-Raft single node, transit auto-unseal -> noc1 seal-bao
(10.0.56.10:8210, key gx10-unseal). Non-root (uid 100/gid 1000), internal
step-ca TLS listener. openbao-tls + openbao-seal secrets created out-of-band
(seal token + listener key never in git). local-path 2Gi Raft PVC.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Andrew Stoltz
2026-06-17 13:41:01 -05:00
parent 44608acae2
commit 4aad74a8aa

View File

@@ -0,0 +1,162 @@
# OpenBao GX10 prod (ADR-206 / Phase-1). Integrated Raft; transit auto-unseal -> noc1 seal-bao.
# Secrets openbao-tls (listener cert) + openbao-seal (seal stanza incl. transit token) are
# created OUT-OF-BAND (not in git): keys live in noc1/1P, never committed. ArgoCD prune:false.
apiVersion: v1
kind: Namespace
metadata:
name: openbao
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: openbao
namespace: openbao
---
apiVersion: v1
kind: Service
metadata:
name: openbao
namespace: openbao
labels:
app.kubernetes.io/name: openbao
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: openbao
ports:
- name: api
port: 8200
targetPort: 8200
- name: cluster
port: 8201
targetPort: 8201
---
apiVersion: v1
kind: ConfigMap
metadata:
name: openbao-config
namespace: openbao
data:
main.hcl: |
ui = true
disable_mlock = true
storage "raft" {
path = "/openbao/data"
node_id = "gx10-1"
}
listener "tcp" {
address = "0.0.0.0:8200"
cluster_address = "0.0.0.0:8201"
tls_cert_file = "/openbao/tls/tls.crt"
tls_key_file = "/openbao/tls/tls.key"
}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: openbao-seal-ca
namespace: openbao
data:
ca.crt: |
-----BEGIN CERTIFICATE-----
MIIBxDCCAWqgAwIBAgIRAPY357G6ow6zMAL5+4bS2kkwCgYIKoZIzj0EAwIwQDEa
MBgGA1UEChMRSUFtV29ya2luIEFDTUUgQ0ExIjAgBgNVBAMTGUlBbVdvcmtpbiBB
Q01FIENBIFJvb3QgQ0EwHhcNMjYwMzA4MTgwNzExWhcNMzYwMzA1MTgwNzExWjBA
MRowGAYDVQQKExFJQW1Xb3JraW4gQUNNRSBDQTEiMCAGA1UEAxMZSUFtV29ya2lu
IEFDTUUgQ0EgUm9vdCBDQTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJ2n04X1
JZo5Zdq/i1Idv8+fqwZyAzBh7whbqj0SWsJL8UWRabCMqYCs7+dXO0xRSzqkwFDL
x+vooOai8RgRNhajRTBDMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/
AgEBMB0GA1UdDgQWBBRnuPPQR6iM/H6vOluiU3Sygayz8jAKBggqhkjOPQQDAgNI
ADBFAiEArQK9dYPGmAZsdYnjziuFVVE5NKZUcceYvGfGC+tLXUsCIAudF2zJrCRq
3mK50ZZET/fwTkJwiEF4824mjP8p1CKM
-----END CERTIFICATE-----
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: openbao
namespace: openbao
labels:
app.kubernetes.io/name: openbao
spec:
serviceName: openbao
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: openbao
template:
metadata:
labels:
app.kubernetes.io/name: openbao
spec:
serviceAccountName: openbao
securityContext:
runAsNonRoot: true
runAsUser: 100
runAsGroup: 1000
fsGroup: 1000
containers:
- name: openbao
image: ghcr.io/openbao/openbao@sha256:e59b4c73cfce6875363d25548222819433c6ce0af9c6d3ec9ede220e905723f9
command: ["bao", "server", "-config=/openbao/config/main.hcl", "-config=/openbao/seal/seal.hcl"]
env:
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: BAO_CLUSTER_ADDR
value: "https://$(POD_IP):8201"
- name: BAO_API_ADDR
value: "https://openbao.openbao.svc.cluster.local:8200"
ports:
- name: api
containerPort: 8200
- name: cluster
containerPort: 8201
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
readinessProbe:
httpGet:
path: /v1/sys/health?standbyok=true&uninitcode=204&sealedcode=204&perfstandbyok=true&drsecondarycode=204
port: 8200
scheme: HTTPS
initialDelaySeconds: 5
periodSeconds: 10
failureThreshold: 6
volumeMounts:
- name: config
mountPath: /openbao/config
- name: seal
mountPath: /openbao/seal
- name: tls
mountPath: /openbao/tls
- name: seal-ca
mountPath: /openbao/seal-ca
- name: data
mountPath: /openbao/data
volumes:
- name: config
configMap:
name: openbao-config
- name: seal
secret:
secretName: openbao-seal
- name: tls
secret:
secretName: openbao-tls
- name: seal-ca
configMap:
name: openbao-seal-ca
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: local-path
resources:
requests:
storage: 2Gi