mirror of
https://github.com/lukaszraczylo/kubemirror.git
synced 2026-06-05 22:43:51 +00:00
228 lines
6.5 KiB
YAML
228 lines
6.5 KiB
YAML
# Example: Using KubeMirror with ExternalSecrets Operator
|
|
#
|
|
# This example demonstrates how to use KubeMirror to distribute secrets from
|
|
# external secret stores (1Password, Vault, AWS Secrets Manager, etc.) across
|
|
# multiple namespaces.
|
|
#
|
|
# KubeMirror automatically strips ownerReferences from mirrors, so you can use
|
|
# the standard ExternalSecrets creationPolicy: Owner without conflicts.
|
|
#
|
|
# Prerequisites:
|
|
# 1. ExternalSecrets Operator installed: https://external-secrets.io/
|
|
# 2. ClusterSecretStore configured for your secret backend
|
|
# 3. KubeMirror installed and running
|
|
#
|
|
# Apply this manifest:
|
|
# kubectl apply -f externalsecret-dockerconfig.yaml
|
|
#
|
|
# Verify:
|
|
# kubectl get externalsecret 1p-docker-config -n default
|
|
# kubectl get secret multi-registry-secret -n default
|
|
# kubectl get secrets --all-namespaces -l kubemirror.raczylo.com/mirror=true
|
|
|
|
---
|
|
apiVersion: external-secrets.io/v1
|
|
kind: ExternalSecret
|
|
metadata:
|
|
name: 1p-docker-config
|
|
namespace: default
|
|
annotations:
|
|
description: "Pulls Docker registry credentials from 1Password and mirrors to all namespaces"
|
|
spec:
|
|
# Secret backend configuration
|
|
secretStoreRef:
|
|
kind: ClusterSecretStore
|
|
name: 1password-homecluster # Replace with your ClusterSecretStore name
|
|
|
|
# Refresh interval - how often to sync from external store
|
|
refreshInterval: 24h
|
|
|
|
# Target secret configuration
|
|
target:
|
|
# Standard ExternalSecrets setting - KubeMirror automatically strips ownerReferences from mirrors
|
|
creationPolicy: Owner
|
|
|
|
# Deletion policy - what happens when ExternalSecret is deleted
|
|
# - Retain: Keep the secret (recommended with KubeMirror)
|
|
# - Delete: Remove the secret
|
|
deletionPolicy: Retain
|
|
|
|
# Name of the Kubernetes secret to create
|
|
name: multi-registry-secret
|
|
|
|
# Template for the secret - includes KubeMirror annotations
|
|
template:
|
|
type: kubernetes.io/dockerconfigjson
|
|
|
|
# Metadata to include in the created secret
|
|
metadata:
|
|
labels:
|
|
# REQUIRED: Server-side filtering label for KubeMirror
|
|
kubemirror.raczylo.com/enabled: "true"
|
|
|
|
# Optional: Additional labels
|
|
app: registry-credentials
|
|
managed-by: external-secrets
|
|
|
|
annotations:
|
|
# REQUIRED: Enable mirroring
|
|
kubemirror.raczylo.com/sync: "true"
|
|
|
|
# Target namespaces - choose one of:
|
|
# - Specific namespaces: "app1,app2,app3"
|
|
# - Pattern matching: "app-*,prod-*"
|
|
# - All namespaces: "all"
|
|
# - Labeled namespaces only: "all-labeled"
|
|
kubemirror.raczylo.com/target-namespaces: "all"
|
|
|
|
# Optional: Add description
|
|
description: "Docker registry credentials synced from 1Password"
|
|
|
|
# Docker config JSON template using ExternalSecrets templating
|
|
data:
|
|
.dockerconfigjson: |
|
|
{
|
|
"auths": {
|
|
"ghcr.io": {
|
|
"username": "{{ .ghcrUsername | toString }}",
|
|
"auth": "{{ printf "%s:%s" .ghcrUsername .ghcrPassword | b64enc }}"
|
|
},
|
|
"https://index.docker.io/v1/": {
|
|
"username": "{{ .dockerUsername | toString }}",
|
|
"auth": "{{ printf "%s:%s" .dockerUsername .dockerPassword | b64enc }}"
|
|
}
|
|
}
|
|
}
|
|
|
|
# Data mappings - what to fetch from external secret store
|
|
data:
|
|
# GitHub Container Registry credentials
|
|
- remoteRef:
|
|
key: DockerAuth/ghcrio_username
|
|
property: username # Optional: if secret has multiple properties
|
|
secretKey: ghcrUsername
|
|
|
|
- remoteRef:
|
|
key: DockerAuth/ghcrio_password
|
|
secretKey: ghcrPassword
|
|
|
|
# Docker Hub credentials
|
|
- remoteRef:
|
|
key: DockerAuth/dockerio_username
|
|
secretKey: dockerUsername
|
|
|
|
- remoteRef:
|
|
key: DockerAuth/dockerio_password
|
|
secretKey: dockerPassword
|
|
|
|
---
|
|
# Example: Using with all-labeled for opt-in mirroring
|
|
apiVersion: external-secrets.io/v1
|
|
kind: ExternalSecret
|
|
metadata:
|
|
name: 1p-database-credentials
|
|
namespace: shared-resources
|
|
spec:
|
|
secretStoreRef:
|
|
kind: ClusterSecretStore
|
|
name: 1password-homecluster
|
|
|
|
refreshInterval: 24h
|
|
|
|
target:
|
|
creationPolicy: Owner # Standard setting - KubeMirror strips ownerReferences
|
|
deletionPolicy: Retain
|
|
name: postgres-credentials
|
|
|
|
template:
|
|
type: Opaque
|
|
metadata:
|
|
labels:
|
|
kubemirror.raczylo.com/enabled: "true"
|
|
annotations:
|
|
kubemirror.raczylo.com/sync: "true"
|
|
# Only mirror to namespaces with allow-mirrors label
|
|
kubemirror.raczylo.com/target-namespaces: "all-labeled"
|
|
|
|
stringData:
|
|
# ExternalSecrets templating for connection strings
|
|
DATABASE_URL: "postgres://{{ .username }}:{{ .password }}@postgres.shared-resources.svc:5432/mydb"
|
|
DB_USER: "{{ .username }}"
|
|
DB_PASSWORD: "{{ .password }}"
|
|
|
|
data:
|
|
- remoteRef:
|
|
key: Database/postgres_username
|
|
secretKey: username
|
|
|
|
- remoteRef:
|
|
key: Database/postgres_password
|
|
secretKey: password
|
|
|
|
---
|
|
# Example namespace with allow-mirrors label (for all-labeled targeting)
|
|
apiVersion: v1
|
|
kind: Namespace
|
|
metadata:
|
|
name: production-app
|
|
labels:
|
|
# Opt-in to receive mirrored secrets
|
|
kubemirror.raczylo.com/allow-mirrors: "true"
|
|
environment: production
|
|
|
|
---
|
|
# Alternative ClusterSecretStore examples for different backends
|
|
# Uncomment and configure based on your secret backend
|
|
|
|
# # AWS Secrets Manager
|
|
# apiVersion: external-secrets.io/v1beta1
|
|
# kind: ClusterSecretStore
|
|
# metadata:
|
|
# name: aws-secrets-manager
|
|
# spec:
|
|
# provider:
|
|
# aws:
|
|
# service: SecretsManager
|
|
# region: us-west-2
|
|
# auth:
|
|
# jwt:
|
|
# serviceAccountRef:
|
|
# name: external-secrets
|
|
# namespace: external-secrets
|
|
|
|
# # HashiCorp Vault
|
|
# apiVersion: external-secrets.io/v1beta1
|
|
# kind: ClusterSecretStore
|
|
# metadata:
|
|
# name: vault-backend
|
|
# spec:
|
|
# provider:
|
|
# vault:
|
|
# server: "https://vault.example.com"
|
|
# path: "secret"
|
|
# version: "v2"
|
|
# auth:
|
|
# kubernetes:
|
|
# mountPath: "kubernetes"
|
|
# role: "external-secrets"
|
|
# serviceAccountRef:
|
|
# name: external-secrets
|
|
# namespace: external-secrets
|
|
|
|
# # Google Secret Manager
|
|
# apiVersion: external-secrets.io/v1beta1
|
|
# kind: ClusterSecretStore
|
|
# metadata:
|
|
# name: google-secret-manager
|
|
# spec:
|
|
# provider:
|
|
# gcpsm:
|
|
# projectID: "my-project-id"
|
|
# auth:
|
|
# workloadIdentity:
|
|
# clusterLocation: us-central1
|
|
# clusterName: my-cluster
|
|
# serviceAccountRef:
|
|
# name: external-secrets
|
|
# namespace: external-secrets
|