18.9 External Secrets Operator: Syncing from Vault, AWS SSM, GCP Secret Manager

Right, so you’ve got ConfigMaps and Secrets down. You’re manually kubectl create secret generic-ing your life away. It works, but it feels a bit… medieval. You’re duplicating secrets into Kubernetes, which is a fantastic way to have them rot in two different places instead of one. And let’s be honest, you’re probably not rotating them as often as you should. Nobody is. The real grown-ups keep their secrets in a proper vault—Hashicorp Vault, AWS Secrets Manager, Google Cloud Secret Manager, Azure Key Vault, you name it. These tools are built for this job: tight access controls, auditing, rotation, the whole nine yards. The question is, how do you bridge that world with the frantic, YAML-obsessed world of Kubernetes?

18.8 Sealed Secrets: Encrypting Secrets for GitOps

Right, so you’ve got your Kubernetes cluster humming along, you’re deploying with GitOps, and you’ve hit the classic snag: you can’t just git commit your database password. Pushing a plain-text Secret to a git repo is like writing your PIN on a postcard. It’s a spectacularly bad idea. This is where Sealed Secrets come in. Think of them as a one-way encryption wrapper for your regular Kubernetes Secrets. You encrypt the secret on your local machine into a SealedSecret custom resource, you commit that to git, and the controller running in your cluster decrypts it, turning it back into a regular Secret. It’s magic, but the kind that runs on public-key cryptography.

18.7 Secret Security: Encryption at Rest and RBAC

Right, let’s talk about keeping your secrets secret. Because by default, Kubernetes doesn’t. I know, I was disappointed too. When you create a Secret, the API server slaps it into etcd, the cluster’s brain, and just… leaves it there. In plain text. It’s the digital equivalent of writing your database password on a post-it note and sticking it to the monitor. We can, and must, do better. This involves two key concepts: encryption at rest (so the post-it note is in a locked drawer) and RBAC (so only certain people have the key to that drawer).

18.6 Secrets as Environment Variables vs Volume Mounts

Alright, let’s get down to brass tacks. You’ve got your shiny new Secret, and now you need to get its precious data into your Pod. You’ve got two main highways for this: injecting them as environment variables or mounting them as files in a volume. The choice isn’t just about preference; it’s a fundamental decision that affects security, observability, and how your application behaves. Let’s break it down. The Quick and Dirty: Environment Variables This is the method everyone reaches for first because it’s dead simple. You define your environment variables in your Pod spec, and Kubernetes magically populates them from your Secret. It feels familiar, especially if you’re coming from a traditional app development background.

18.5 Secret Types: Opaque, TLS, dockerconfigjson, service-account-token

Right, so you’ve got your ConfigMaps for your regular, non-secret configuration. That’s great. But sometimes you have things you’d rather not broadcast to the entire cluster, like API keys, database passwords, or the fact that you still use abc123 as a password. Enter Secrets. They’re like ConfigMaps, but with a thin, almost performative veil of secrecy. Don’t get too excited; by default, they’re just base64-encoded, not encrypted. Anyone with kubectl get secrets -o yaml can decode them in about five seconds. It’s the Kubernetes equivalent of hiding your house key under the doormat. We’ll get to making them actually secret later, but first, let’s talk about the different types, because Kubernetes, in its infinite wisdom, decided there shouldn’t just be one kind.

18.4 Secrets: Base64-Encoded Sensitive Data

Alright, let’s talk about Secrets. You’ve just learned about ConfigMaps, and you’re thinking, “Great! I’ll just shove my database password in one of those!” Please, for the love of all that is holy, do not do that. That’s why we have Secrets. They’re the ConfigMap’s more paranoid, security-conscious cousin who whispers instead of shouting. The core idea is simple: Secrets are a Kubernetes object for storing sensitive data like passwords, API keys, TLS certificates, and OAuth tokens. The key difference from a ConfigMap? They’re not just plain text. Well, sort of. Here’s the first thing you need to know, and it’s a bit of a doozy: the data in a Secret is base64-encoded, not encrypted. Let me say that again for the people in the back. It is not encrypted. Base64 is an encoding scheme, designed to avoid weird binary/control characters, not a encryption cipher designed to keep prying eyes out. Anyone with kubectl get secret my-secret -o yaml can see the encoded data, and any mildly curious intern can run echo 'dGhpcyBpcyBzb21lIHNlY3JldA==' | base64 --decode on their laptop to reveal the plain text “this is some secret”. This is the first and most important pitfall. Secrets are a way to avoid accidentally shoulder-surfing a password, not a way to secure it against a determined attacker. For real encryption at rest, you need to enable and configure the EncryptionConfiguration for the Kubernetes API server, which is a whole other chapter of pain.

18.3 Consuming ConfigMaps as Mounted Files

Right, so you’ve defined your ConfigMap. Good for you. Now, how do you actually get those configuration values into your grumpy little application that expects a good old-fashioned file on the filesystem? You mount it. This is the most robust and common way to consume ConfigMaps, and it works exactly like it sounds: you take the contents of the ConfigMap and make them appear as files in a directory inside your Pod.

18.2 Consuming ConfigMaps as Environment Variables

Right, so you’ve defined your ConfigMap. Good for you. You’ve written a beautiful YAML file full of pristine configuration data. It’s a work of art. But it’s about as useful as a screen door on a submarine until you actually get those values into your application. The most straightforward way to do that is by injecting them as environment variables. It’s the lingua franca of application configuration, and Kubernetes, bless its heart, makes this pretty simple, albeit with a few quirks that will make you question your life choices.

18.1 ConfigMaps: Storing Non-Sensitive Configuration

Right, let’s talk about ConfigMaps. This is where we stop hard-coding configuration details like database URLs or feature flags directly into our application code. Hard-coding is for amateurs and prototypes that accidentally get pushed to production. We’re better than that. Think of a ConfigMap as a simple, string-based key-value dictionary that you can hand to your application running in Kubernetes. It’s not a fancy database; it’s more like a stack of sticky notes you can pass to your Pod. The crucial thing to remember: ConfigMaps are for non-sensitive configuration data. We’re talking database URLs (db-service.prod.svc.cluster.local), config file contents, environment names (“dev”, “staging”), and other mundane details. If you put a password in here, I will find out, and I will be very disappointed in you. For secrets, we have another tool, which we’ll get to shortly.

— joke —

...