Skip to main content

Kubernetes: 21. Secrets

Passwords

  • In the webapps we store the properties file for storing and retrieving the data required by application
  • But we never store the application passwords, truststore, keystore passwords etc here
  • We might store them in an encrypted format, but storing them as plain text is not the correct way
  • In Kubernetes we store these sensitive information in Secrets

Secrets
  • Secrets are used to store the sensitive information
  • They are similar to ConfigMaps, except that they are stored in hashed or encoded format
  • Note that they are only encoded (using base64) but are not encrypted
  • So secrets are a safe option to store sensitive information but infact they are not the safest option
  • As such secret objects should be not checked into source code tools, its best to store them encrypted at REST in ETCD
  • Again as in ConfigMaps, we have to create the secrets object first and then inject them into the pods
  • There are 2 ways to create secretes
    1. Imperative
    2. Declarative

Types of Secrets:
  • Opaque. This is the default secret, when you don't mention generic, it is an opaque secret. Provide the data in base64 encoded format
  • kubernetes.io/service-account-token.
    • A kubernetes.io/service-account-token type of Secret is used to store a token that identifies a service account.
    • When using this Secret type, you need to ensure that the kubernetes.io/service-account.name annotation is set to an existing service account name.
  • There-are-many-others-which-can-be-found-in-this-link

app-secret
DB_HOST: abcdb
DB_USERNAME: kites
DB_PASSWORD: kites@123


secret-creation-imperative
kubectl create secret generic
-> Imperative way of creating secret

<secret-name> --from-literal=<key>=<value>
-> Add key value pairs by mentioning from-literal

kubectl create secret generic
-> Imperative way of creating secret

<secret-name> --from-file=<path-to-file>
-> Add key value pairs by passing through a file by mentioning from-file

kubectl create secret generic \
    <secret-name> --from-literal=DB_HOST=abcdb \
                  --from-literal=DB_USERNAME=kites \
                  --from-literal=DB_PASSWORD=kites@123

kubectl create secret generic \
    <secret-name> --from-file=app_secret.properties

secret-creation-declarative.yaml
apiVersion: v1
kind: Secret
metadata:
    name: app-secret

data:
    DB_HOST=abcdb
    DB_USERNAME=kites
    DB_PASSWORD=kites@123

kubectl create -f secret-definition.yaml
-> Create the secret

kubectl get secrets
-> Get all the secrets in the existing namespace

kubectl get secrets <secret-name> -o yaml
-> Get the secrets in the existing namespace with the clear text value

kubectl describe secrets
-> Describe all the secrets in the existing namespace but hides the values

kubectl describe secrets <secret-name>
-> Describe the secret <secret-name> in the existing namespace but hides the values

Encode Secret Data
  • As secrets are sensitive, when we create them using declarative format, we have to encode the data
  • The above example clearly shows the secret data in plain text
  • It should be encoded rather in plain text
  • On a Linux system this can be easily converted using echo as below
echo -n abcdb | base64
YWJjZGI=
  • So when these secrets are printed using get secrets command, the output will be in the encoded format
  • Decode them as below
echo -n YWJjZGI= | base64 --decode
abcdb

Add Secrets to the Pods
  • Secrets can be added in variety of ways to the pods
  • The entire Secret references can be injected into the pod
  • This can be seen from below spec.envFrom.secretRef array
    • Here we provide the name of the secret
    • Since this is an array, you can inject multiple secrets
  • Only a single value from Secret can be injected
  • This can be seen from spec.env array
    • Here we provide the name of our variable
    • Value is taken from a Secret, with the name of the Secret and the key name provided
    • Since this is any array, you can inject multiple variables
  • Secrets can be injected as a file by using volumes
  • This can be seen from spec.volumes
    • Name of the Secret that has to be injected into the Pod is provided
    • Secrets are then mounted as a file on the pod
    • When secrets are mounted as volumes each key value pair is added as a file
    • File name will be the key name and the file content will be the value
pod-definition.yaml
apiVersion: v1
kind: Pod
metadata:
    name: my-color-webapp

spec:
    containers:
    - name: my-color-container
      image: simple-webapp-color
    ports:
    - containerPort: 8080
    envFrom:
    - secretRef:
        name: app-secret

    env:
    - name: DB_PASSWORD
      valueFrom:
          secretRef:
            name: app-secret
            key: DB_PASSWORD

    volumes:
    - name: secret-config-volume
      secret:
        secretName: app-secret



Comments

Popular posts from this blog

Kubernetes: 6. Imperative Commands

Imperative commands are useful in quickly creating the resources on Kubernetes kubectl --dry-run -> When created with this option, Kubernetes just validates the definition and does not actually create the resource -o=yaml -> Gets the output in YAML format kubectl run nginx-pod --image=nginx:alpine  -> Create a pod with name nginx-pod and image nginx:alpine kubectl run httpd --image=httpd:alpine  -> By default, run implies run-a-pod kubectl run redis --image=redis:alpine --labels=tier=db  -> Create a pod with name redis and image redis:alpine and labels set to tier=db kubectl run custom-nginx --image=nginx --port=8080  -> Create a pod with name custom-nginx and image nginx to run on port 8080 kubectl expose pod redis --port=6379 --name=redis-service  -> Create a service with name redis-service to expose pod named redis on service-port 6379 kubectl create deployment webapp --image=kodekloud/webapp-color --replicas=3  -> Create a depl...

Kubernetes: 19. Configure Application

Configuring application consists of Configuring commands and arguments on applications Configuring environment variables Configuring secrets Docker Commands docker run ubuntu  -> Runs ubuntu container and exit, container CMD is set to [bash], so the container quitely exits docker run ubuntu echo "Hello World" -> Runs ubuntu container, prints "Hello World" exits quitely. To update the default settings, create your own image from the base image lets call this ubuntu-sleeper image FROM ubuntu CMD sleep 5 CMD can also be mentioned in the JSON format like CMD ["sleep", "5"] Note that with JSON format the first element should always be the command to execute,  for eg, it CANNOT be ["sleep 5"] Run build the new ubuntu-sleeper image and run the new image docker build -t ubuntu-sleeper .  -> Build the image docker run ubuntu-sleeper -> Run the new image So the new image will launch ubuntu container, sleep for 5 seconds and quitely ex...