Kubernetes

kubectl get secret postgres-credentials -o jsonpath="{.data}" | jq 'to_entries | .[] | "\(.key): \(.value | @base64d)"'

kubectl create secret generic azure-secrets --from-env-file <(jq -r "to_entries|map(\"\(.key)=\(.value|tostring)\")|.[]" azure-credentials.json)

Operator mit Helm installieren

helm repo add external-secrets https://charts.external-secrets.io
helm install external-secrets external-secrets/external-secrets

Erstellung eines Azure Service Principals

provider "azurerm" {
  features {}
}

provider "kubernetes" {
  config_path = "~/.kube/config"
}

provider "azuread" {
  tenant_id = data.azurerm_client_config.current.tenant_id
}

data "azurerm_client_config" "current" {}

resource "azuread_application" "eso_app" {
  display_name = "external-secrets-operator"
}

resource "azuread_service_principal" "eso_sp" {
  application_id = azuread_application.eso_app.application_id
}

resource "azuread_service_principal_password" "eso_sp_password" {
  service_principal_id = azuread_service_principal.eso_sp.id
  value                = random_password.sp_password.result
  end_date             = "2099-01-01T00:00:00Z"
}

resource "random_password" "sp_password" {
  length  = 32
  special = true
}

resource "azurerm_role_assignment" "kv_role_assignment" {
  principal_id   = azuread_service_principal.eso_sp.id
  role_definition_name = "Key Vault Secrets User"
  scope          = azurerm_key_vault.example.id
}

# Optional: Erstelle ein JSON-Dokument im Azure SDK-Format (wie azure-credentials.json)
locals {
  azure_credentials = jsonencode({
    clientId     = azuread_service_principal.eso_sp.application_id
    clientSecret = azuread_service_principal_password.eso_sp_password.value
    tenantId     = data.azurerm_client_config.current.tenant_id
    subscriptionId = data.azurerm_client_config.current.subscription_id
    activeDirectoryEndpointUrl = "https://login.microsoftonline.com"
    resourceManagerEndpointUrl = "https://management.azure.com/"
    activeDirectoryGraphResourceId = "https://graph.windows.net/"
    sqlManagementEndpointUrl = "https://management.core.windows.net:8443/"
    galleryEndpointUrl = "https://gallery.azure.com/"
    managementEndpointUrl = "https://management.core.windows.net/"
  })
}

# Kubernetes Secret für Service Principal erstellen
resource "kubernetes_secret" "azure_secrets" {
  metadata {
    name      = "azure-secrets"
    namespace = "default"
  }

  data = {
    "azure-credentials.json" = base64encode(local.azure_credentials)
  }
}

Erklärung der Ressourcen:

  • azuread_application: Erstellt die Azure AD Anwendung, die den Service Principal repräsentiert.
  • azuread_service_principal: Erstellt den Service Principal für die Anwendung.
  • azuread_service_principal_password: Erstellt ein Kennwort (Client Secret) für den Service Principal.
  • azurerm_role_assignment: Weist dem Service Principal die Rolle Key Vault Secrets User für den Zugriff auf den Key Vault zu.
  • kubernetes_secret: Erstellt ein Kubernetes Secret, das die Azure-Anmeldeinformationen im azure-credentials.json-Format speichert. Das JSON wird mithilfe der local-Variable generiert.

Oder per CLI:

$ az ad sp create-for-rbac --name "external-secrets-operator" --sdk-auth > azure-credentials.json

$ kubectl create secret generic azure-secrets --from-env-file <(jq -r "to_entries|map(\"\(.key)=\(.value|tostring)\")|.[]" azure-credentials.json)

Secretstore anlegen

apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
  name: example-secret-store
spec:
  provider:
    azurekv:
      tenantId: "xxxxx-xxx-xxxx-xxxx-xxxxxxx"
      vaultUrl: "https://xxxxx.vault.azure.net"
      authSecretRef:
        clientId:
          name: azure-secrets
          key: clientId
        clientSecret:
          name: azure-secrets
          key: clientSecret

Externalsecret anlegen

apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: example-external-secret
spec:
  refreshInterval: 1h
  secretStoreRef:
    kind: SecretStore
    name: example-secret-store

  target:
    name: secret-to-be-created
    creationPolicy: Owner

  data:
  - secretKey: secret-key
    remoteRef:
      key: secret-key

Helm Repo hinzufügen

helm repo add jetstack https://charts.jetstack.io --force-update
helm install \
  cert-manager jetstack/cert-manager \
  --namespace cert-manager \
  --create-namespace \
  --version v1.15.3 \
  --set crds.enabled=true

ClusterIssuer konfigurieren

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: ta@example.com
    privateKeySecretRef:
      name: example-issuer-account-key
    solvers:
    - http01:
        ingress:
          ingressClassName: nginx

Prerequisites: kubebuilder

Neues Projekt initialisieren:

kubebuilder init --owner tasanger --domain sidecar-demo.ta.vg --repo sidecar-demo
$ kubectl api-resources | grep Pod
pods                              po           v1                                          true         Pod
podtemplates                                   v1                                          true         PodTemplate
horizontalpodautoscalers          hpa          autoscaling/v2                              true         HorizontalPodAutoscaler
pods                                           metrics.k8s.io/v1beta1                      true         PodMetrics
poddisruptionbudgets              pdb          policy/v1                                   true         PodDisruptionBudget

Es wird keine neue Ressource benötigt, daher wird nur der Controller erstellt:

$ kubebuilder create api --group core --version v1 --kind Pod
INFO Create Resource [y/n]                        
n
INFO Create Controller [y/n]                      
y
INFO Writing kustomize manifests for you to edit... 
INFO Writing scaffold for you to edit...          
INFO internal/controller/suite_test.go            
INFO internal/controller/pod_controller.go        
INFO internal/controller/pod_controller_test.go   
INFO Update dependencies:
$ go mod tidy           

Edit pod_controller.go

func (r *PodReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
	l := log.FromContext(ctx)

	// TODO(user): your logic here
	pod := &corev1.Pod{}
	if err := r.Get(ctx, req.NamespacedName, pod); err != nil {
		return ctrl.Result{}, client.IgnoreNotFound(err)

	}

	l.Info("Pod", "Name", pod.Name, "Namespace", pod.Namespace)

	return ctrl.Result{}, nil
}

eine launch.json im Verzeichnis .vscode erstellen

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Launch Package",
            "type": "go",
            "request": "launch",
            "mode": "auto",
            "program": "./cmd"
        }
    ]
}

Wenn sich Ihre main.go Datei im Verzeichnis cmd befindet, müssen Sie sicherstellen, dass der Build-Prozess dieses Verzeichnis berücksichtigt. Hier sind einige Schritte, um sicherzustellen, dass alles richtig konfiguriert ist:

Anpassen der VSCode Debug-Konfiguration: Passen Sie die launch.json in Ihrem .vscode-Verzeichnis an, um sicherzustellen, dass das cmd-Verzeichnis verwendet wird:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Launch",
            "type": "go",
            "request": "launch",
            "mode": "auto",
            "program": "${workspaceFolder}/cmd",
            "env": {},
            "args": [],
            "showLog": true,
            "trace": "verbose"
        }
    ]
}
kubectl rollout restart deployment/subgraph-pbf

Synopsis

Manage the rollout of one or many resources.

Valid resource types include:

  • deployments
  • daemonsets
  • statefulsets
kubectl rollout SUBCOMMAND

Examples

  # Rollback to the previous deployment
  kubectl rollout undo deployment/abc
  
  # Check the rollout status of a daemonset
  kubectl rollout status daemonset/foo
  
  # Restart a deployment
  kubectl rollout restart deployment/abc
  
  # Restart deployments with the 'app=nginx' label
  kubectl rollout restart deployment --selector=app=nginx
kubectl get --raw "/apis/external.metrics.k8s.io/v1beta1/namespaces/*/nginx_ingress_controller_per_second" | jq .

Dieser Modus wird verwendet, wenn Traffic flapping erwartet wird oder die Anzahl der Pods nicht zu früh verkleinert werden soll, weil späte Lastspitzen erwartet werden.

Erstelle einen HPA mit der folgender Konfiguration:

behavior:
  scaleDown:
    stabilizationWindowSeconds: 600
    policies:
    - type: Pods
      value: 5
      periodSeconds: 600

Dieser Modus wird benötigt um nicht runter zu skalieren da dies ggf. über einen externen Prozess geschieht

Erstelle einen HPA mit der folgender Konfiguration:

behavior:
  scaleDown:
    selectPolicy: Disabled