Skip to content

Latest commit

 

History

History
177 lines (140 loc) · 7.63 KB

README.MD

File metadata and controls

177 lines (140 loc) · 7.63 KB

LAB-K8S-07: Secrets

Description: In this lab, participants will learn how to create and use Secrets.

Duration: ±40m

Goals

At the end of this laboratory, each participant will be able to_

  • Create a Secret object
  • Use the same Secret in applications

Prerequisites


Secrets

Secrets allow to store and manage sensitive information on a (key/value) model. They are commonly used for passwords, OAuth token ... Secrets objects are very similar to ConfigMaps.

⚠️ Kubernetes Secrets are not secure at all as they rely on base64 encoding, and should be avoided as much as possible in production environments. There are secure alternatives to native Secrets, such as Hashicorp Vault.

Such a tool setup and usage would require a dedicated lab.

A New Hope

We've just been informed that a droid has just delivered under cover an encoded message in the form of a Secret inside your namespace. Let's check it out...

  • ✅ Read documentation on Secrets

  • ✅ Can you see the Secret object inside your namespace?

    kubectl get secrets
  • ✅ What does the describe command show ?

    kubectl describe secrets secret-transmission-from-droid 
  • ✅ Show the secret content using the YAML format

    kubectl get secrets secret-transmission-from-droid -o yaml
  • ✅ Retrieve the content of the message entry in the data section, and decode it

    kubectl get secrets secret-transmission-from-droid -o yaml | \
     grep -oP "message: \K(.*)" | base64 --decode

We've been assigned an important mission, bring the Death Star plans to the Rebels. We've immediately tasked our application team to develop a way to access our broadcast message containing the plans.

Preparing the broadcast transmission

This is the message we want to store safely as a Secret (we've covered already the topic of how secure this is)

MENACE! "Message from {{planet}} to all Rebels: Please bring the Death Star plans attached to this message to someone named Obi-Wan-Kenobi" + this ascii code (after the text) : https://github.com/sokube/kubernetes-training/blob/master/LAB-K8S-07/death-star-ascii

  • ✅ Encode this message (base64) and insert it in a new secret named secret-transmission, inside the data field secret-transmission.txt :

    kubectl create -f secret-transmission-2.yml
  • ✅ Verify it's been created:

    kubectl get secrets

Our Rebel-loving dev application team has quickly rushed a new version of our landing zone application and provided us a quick and dirty way to offer the transmission my mounting the secret as a file inside the container filesystem at /usr/src/app/static/transmission/. They've also provided a new link on the main page to facilitate the job of the Rebels.

  • ✅ Deploy a new version of our application (image: sokubedocker:simple-todo:v2.2) and check this new "feature".

    TIPS: If you don't have the previous deployments yaml files, Export your old deployment and simply add the new entries. | kubectl get deployment my-todo-deployment -o yaml > my-todo-deployment-with-secret-volume.yml

Frightening. Time to put the real message.

  • ✅ Read the documentation on Pods and Secrets as volumes

  • ✅ Update the deployment to mount the secret's content as files under /usr/src/app/static/transmission/ in the container. (solution here)

  • ✅ Check that our message can be seen correctly

🍸 Congratulations, you've reached mastery in the management of Secrets 🍸

Advanced Topic: Service Accounts Secrets

  • ✅ Create the debug pod that we've used in LAB-K8S-08 - Persistence for debugging purposes.

    kubectl create -f debug-pod.yml
  • ✅ Check its description... What is this Secret that we have not defined by ourselves ?

    ...
        Environment:    <none>
        Mounts:
          /var/run/secrets/kubernetes.io/serviceaccount from   default-token-gb7gb (ro)
    Conditions:
      Type              Status
      Initialized       True 
      Ready             True 
      ContainersReady   True 
      PodScheduled      True 
    Volumes:
      default-token-gb7gb:
        Type:        Secret (a volume populated by a Secret)
        SecretName:  default-token-gb7gb
        Optional:    false
    ...
    
  • ✅ Check the default Service Account and have a look at the secret it has defined to store a token to this service. Looks familiar ?

    kubectl get sa default -o yaml
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      creationTimestamp: "2020-06-08T15:57:17Z"
      name: default
      namespace: tatooine
      resourceVersion: "554637"
      selfLink: /api/v1/namespaces/tatooine/serviceaccounts/default
      uid: ff5f1745-76a4-4790-9132-cbac285a1530
    secrets:
    - name: default-token-gb7gb
    

So by default, Kubernetes will mount the token information for the Service Account that is used to run the POD in the /var/run/secrets/kubernetes.io/serviceaccount path on the containers of the POD.

  • ✅ Explore the contents of this secret

    kubectl get secret default-token-gb7gb -o yaml

    From https://medium.com/better-programming/k8s-tips-using-a-serviceaccount-801c433d0023

    There are several key/value pairs under the data key of this Secret. Basically:

    • ca.crt is the Base64 encoding of the cluster certificate.
    • namespace is the Base64 encoding of the current namespace
    • token is the Base64 encoding of the JWT used to authenticate against the API server.
  • ✅ Copy the content of the token field, and use jwt.io to parse it.

    { "iss": "kubernetes/serviceaccount", "kubernetes.io/serviceaccount/namespace": "tatooine", "kubernetes.io/serviceaccount/secret.name": "default-token-gb7gb", "kubernetes.io/serviceaccount/service-account.name": "default", "kubernetes.io/serviceaccount/service-account.uid": "ff5f1745-76a4-4790-9132-cbac285a1530", "sub": "system:serviceaccount:tatooine:default" }

  • ✅ Go inside the mounted secret:

    cd /run/secrets/kubernetes.io/serviceaccount/
  • ✅ Copy the content of the JWT token inside a variable TOKEN (for clarity)

    TOKEN=$(cat token)
  • ✅ Now we can curl the kubernetes API Service using the DNS notation we've seen in LAB-K8S-04 - Services. Remember that we're not in the default namespace where this ClusterIP service is running, so we need to use the servicename.namespace notation.

    curl -H "Authorization: Bearer $TOKEN" \
    "https://kubernetes.default/api/v1/" --cacert ca.crt

With this mechanism, we could for example implement a monitoring application that performs queries against the Kubernetes Cluster.

Next lab