Kubernetes Handbook

    Secrets in Kubernetes

    Hey, Kubernetes newbie! Ready to level up your skills? Last time, we tackled ConfigMaps, and now it’s time to dive into their secure cousin, Secrets. If ConfigMaps are like the settings screen in your Swiggy app, Secrets are like the password-protected vault where you store your login credentials. In this blog, we’ll explore Secrets using Swiggy, India’s favorite food ordering app, to keep things relatable. By the end, you’ll know how to safely handle sensitive data in Kubernetes like a pro. Let’s get rolling! 😊

    What Are Secrets? A Simple Breakdown#

    Picture this: you’re ordering a masala dosa on Swiggy. The app needs to connect to a database to save your order, but it requires a password. Hardcoding that password in your app’s code is like writing your ATM PIN on a sticky note—anyone who sees it can cause trouble. 😬 Secrets in Kubernetes are special objects designed to store sensitive data, like passwords, API keys, or access tokens, securely and separately from your app’s code.

    ConfigMaps and Secrets

    Unlike ConfigMaps, which are great for non-sensitive stuff like delivery distances, Secrets are encoded (and can be encrypted) to keep prying eyes away. You can feed Secrets to your app’s containers, making your app both secure and flexible.

    Why Secrets Are a Big Deal#

    • Security First: Keep sensitive data out of your codebase and away from hackers.
    • Easy Updates: Change a password without redeploying your app.
    • Access Control: Only authorized users or apps can access Secrets.
    • Versatility: Store small bits of data or entire files, like SSL certificates.

    When I first started with Kubernetes, I made the rookie mistake of putting an API key in a ConfigMap. Spoiler: it wasn’t secure, and my team wasn’t thrilled. 😅 Secrets saved the day, and I’m here to help you avoid my blunders!

    Creating a Secret: Two Easy Methods#

    You can create a Secret in two ways: using a YAML file (like a secure note) or the kubectl command (like a quick, encrypted text). We’ll use Swiggy examples to keep it clear and fun.

    Option 1: Creating a Secret with YAML#

    Let’s create a Secret for Swiggy to store sensitive data, like a database password and an API key for payment processing. Here’s the YAML:

    apiVersion: v1 kind: Secret metadata: name: swiggy-secret namespace: default type: Opaque data: db_password: c3dpZ2d5X3Bhc3N3b3Jk payment_api_key: YXBpX2tleV9zd2lnZ3k=

    YAML Explained for Beginners#

    Don’t let YAML intimidate you—it’s just a structured way to tell Kubernetes what to do, like filling out a secure form. Here’s what each part means:

    • apiVersion: v1: Uses the standard Kubernetes API version for Secrets.
    • kind: Secret: Says, “I’m creating a Secret!”
    • metadata: Labels the Secret.
      • name: swiggy-secret: The Secret’s name, which we’ll use later.
      • namespace: default: The “folder” where the Secret lives (organizing your Kubernetes resources).
    • type: Opaque: The most common Secret type, used for arbitrary data (like passwords or keys).
    • data: Where the sensitive data goes, encoded in base64 (more on that below).
      • db_password: The encoded database password.
      • payment_api_key: The encoded API key for payments.

    What’s with the Gibberish? The values under data (like c3dpZ2d5X3Bhc3N3b3Jk) are base64-encoded to add a layer of obfuscation. To encode a value, use a command like:

    echo -n "swiggy_password" | base64

    Output:

    c3dpZ2d5X3Bhc3N3b3Jk

    Similarly, api_key_swiggy encodes to YXBpX2tleV9zd2lnZ3k=. You can decode it back with:

    echo "c3dpZ2d5X3Bhc3N3b3Jk" | base64 -d

    Output:

    swiggy_password

    Save the YAML as swiggy-secret.yaml and apply it:

    kubectl apply -f swiggy-secret.yaml

    Output:

    secret/swiggy-secret created

    You’ve just created a Secret! Check it with:

    kubectl get secret swiggy-secret -o yaml

    Note: The output shows encoded values, not plain text, keeping things secure.

    Option 2: Creating a Secret with kubectl#

    If YAML feels like too much work, you can create a Secret with kubectl. Let’s say Swiggy needs a Secret for an email service password.

    kubectl create secret generic swiggy-email-secret \\ --from-literal=email_password=supersecret123

    What’s Happening?#

    • kubectl create secret generic swiggy-email-secret: Creates a Secret named swiggy-email-secret.
    • -from-literal: Adds a key-value pair. Kubernetes automatically base64-encodes the value for you.

    Output:

    secret/swiggy-email-secret created

    Verify it:

    kubectl describe secret swiggy-email-secret

    Output (shortened):

    Name: swiggy-email-secret Namespace: default Type: Opaque Data ==== email_password: 12 bytes

    YAML or kubectl? YAML is great for complex Secrets or version control (like storing in Git). kubectl is faster for quick setups. Both are beginner-friendly!

    Using Secrets in a Deployment#

    Now that you’ve got a Secret, let’s use it in a Deployment, which is what most devs use to manage scalable apps. We’ll show two ways to feed Secret data to a Swiggy Deployment: as environment variables (like secure app settings) and as a volume (like a secure file).

    Example 1: Secret as Environment Variables#

    Let’s say Swiggy’s Deployment needs the database password and payment API key as environment variables. Here’s the YAML:

    apiVersion: apps/v1 kind: Deployment metadata: name: swiggy-deployment namespace: default spec: replicas: 3 selector: matchLabels: app: swiggy template: metadata: labels: app: swiggy spec: containers: - name: swiggy-app image: swiggy:latest env: - name: DB_PASSWORD valueFrom: secretKeyRef: name: swiggy-secret key: db_password - name: PAYMENT_API_KEY valueFrom: secretKeyRef: name: swiggy-secret key: payment_api_key

    Deployment YAML Explained#

    Think of this YAML as a blueprint for your app. Here’s what each part does:

    • apiVersion: apps/v1: Uses the Deployment API.
    • kind: Deployment: Says, “I’m creating a Deployment.”
    • metadata: Names the Deployment.
      • name: swiggy-deployment: The Deployment’s name.
      • namespace: default: Keeps it in the default namespace.
    • spec: The plan for your Deployment.
      • replicas: 3: Runs 3 copies of your app for reliability and scale.
      • selector: Links the Deployment to its pods using the app: swiggy label.
      • template: Defines the pods the Deployment manages.
        • metadata.labels: Labels pods with app: swiggy.
        • spec.containers: Defines the app’s container.
          • name: swiggy-app: Names the container.
          • image: swiggy:latest: The Docker image for Swiggy.
          • env: Injects Secret data as environment variables.
            • name: DB_PASSWORD: The variable name your app will use.
            • valueFrom.secretKeyRef: Pulls the value from the Secret.
              • name: swiggy-secret: Points to our Secret.
              • key: db_password: Grabs the db_password value.

    Apply it:

    kubectl apply -f swiggy-deployment.yaml

    Output:

    deployment.apps/swiggy-deployment created

    Now, Swiggy’s app can access DB_PASSWORD and PAYMENT_API_KEY as environment variables. Kubernetes decodes the base64 values automatically, so your app gets the plain text (e.g., swiggy_password). If the password changes, update the Secret, and the Deployment picks it up without a redeploy.

    Real-World Scenario: Swiggy’s database team rotates passwords for security. Update the Secret with the new base64-encoded password, and all pods in the Deployment get the update. Your users keep ordering biryani, and you’re the security champ! 😎

    Example 2: Secret as a Volume#

    What if Swiggy needs a file, like creds.properties, for sensitive data? You can mount a Secret as a volume. Here’s a Secret with a file:

    apiVersion: v1 kind: Secret metadata: name: swiggy-creds-secret namespace: default type: Opaque data: creds.properties: ZGF0YWJhc2UucGFzc3dvcmQ9c3dpZ2d5X3Bhc3N3b3JkCnBheW1lbnQuYXBpLmtleT1hcGlfa2V5X3N3aWdneQ==

    Secret Volume Explained#

    • data.creds.properties: This is a base64-encoded file. To create it, write creds.properties:
    database.password=swiggy_password payment.api.key=api_key_swiggy

    Then encode it:

    cat creds.properties | base64

    Output:

    ZGF0YWJhc2UucGFzc3dvcmQ9c3dpZ2d5X3Bhc3N3b3JkCnBheW1lbnQuYXBpLmtleT1hcGlfa2V5X3N3aWdneQ==

    Apply the Secret:

    kubectl apply -f swiggy-creds-secret.yaml

    Now, use it in a Deployment:

    apiVersion: apps/v1 kind: Deployment metadata: name: swiggy-file-deployment namespace: default spec: replicas: 3 selector: matchLabels: app: swiggy-file template: metadata: labels: app: swiggy-file spec: containers: - name: swiggy-app image: swiggy:latest volumeMounts: - name: secret-volume mountPath: "/etc/creds" volumes: - name: secret-volume secret: secretName: swiggy-creds-secret

    Volume Deployment Explained#

    • spec.template.spec.volumes: Creates a volume named secret-volume using the swiggy-creds-secret Secret.
    • spec.template.spec.containers.volumeMounts: Mounts the volume at /etc/creds, so creds.properties appears as a file in the container.

    Apply it, and your container gets /etc/creds/creds.properties with the decoded contents. Swiggy’s app can read it like any file.

    Real-World Scenario: Swiggy’s payment team updates the API key for a new payment gateway. Update the Secret with the new base64-encoded file, and the file updates across all pods. No downtime, just seamless orders for butter naan.

    Avoiding Common Beginner Mistakes#

    You’ll probably trip up at first, and that’s totally fine! Here are pitfalls to avoid:

    • Encoding Errors: Always base64-encode Secret values yourself in YAML. If you forget, Kubernetes won’t do it for you, and your data won’t work.
    • Namespace Mismatch: Secrets and Deployments must be in the same namespace (e.g., default). A mismatch means your Deployment can’t find the Secret.
    • Exposing Secrets: Don’t use kubectl get secret -o yaml in shared environments—it shows decoded values. Use kubectl describe secret instead.

    Pro Tip: Run kubectl describe deployment swiggy-deployment to check if your Secret data is linked correctly. It’s like checking your app’s secure connections!

    Example 3: Debugging a Secret Issue#

    Suppose Swiggy’s Deployment isn’t getting the db_password. Check the Secret:

    kubectl describe secret swiggy-secret

    Output (shortened):

    Name: swiggy-secret Namespace: default Type: Opaque Data ==== db_password: 14 bytes payment_api_key: 16 bytes

    Looks good! Now check a pod’s environment:

    kubectl exec -it $(kubectl get pod -l app=swiggy -o name | head -n 1) -- env

    If DB_PASSWORD is missing, you might’ve mistyped the secretKeyRef key. Fix the YAML, reapply, and you’re back in business.

    Secrets vs. ConfigMaps: Know the Difference#

    Secrets are for sensitive data like passwords and API keys, while ConfigMaps are for non-sensitive data like delivery distances. Secrets are base64-encoded (and can be encrypted with additional tools), making them safer. Never store sensitive data in ConfigMaps—they’re not secure by default.

    Real-World Scenario: Swiggy uses a ConfigMap for the max items per order but a Secret for the database password. This keeps customer orders safe while letting devs tweak settings easily.

    Conclusion#

    In this blog, you mastered Secrets, the Kubernetes tool for securely managing sensitive data. We explored what Secrets are, how to create them with YAML and kubectl, and how to use them in Deployments as environment variables or volumes, with beginner-friendly Swiggy examples. You also learned to avoid common mistakes and why Secrets are crucial for security. You’re now ready to keep your Kubernetes apps safe and sound!

    Last updated on May 06, 2025