Sunday, May 20, 2018

Kubernetes - Secrets

Passing sensitive data like user name and password to a container is necessary when running in production. kubernetes defines secrets that allow us to store sensitive data such as username and password with encryption and can be passed to the pod.

A secret can be created in kubernetes using
from text file
or by creating a yml file
or by passing as Env Variables

Creating a Secret using text file -
$ echo -n "A19fh68B001j" > ./apikey.txt

$ kubectl create secret generic apikey --from-file=./apikey.txt
secret "apikey" created

lets check the secret using ,
[root@manja17-I13330 kubenetes-config]# kubectl describe secrets/apikey
Name:         apikey
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
apikey.txt:  12 bytes

Create a pod manifest file by including the above secret as,
[root@manja17-I13330 kubenetes-config]# cat secret-mount-pod.yml
apiVersion: v1
kind: Pod
metadata:
 name: "testing-service"
 labels:
  name: "testingService"
spec:
 containers:
  - image: docker.io/jagadesh1982/testing-service
    name:  "testing"
    imagePullPolicy: IfNotPresent
    ports:
      - containerPort: 9876
    volumeMounts:
      - name: apikeyvol
        mountPath: "/tmp/apikey"
        readOnly: true
 volumes:
  - name: apikeyvol
    secret:
      secretName: apikey

In the above manifest file ,we attached the secret file by mounting the secret as a volume. the secret is mounted on the location /tmp/apikey. The mounted secret file is a read only. Create a pod using the "kubectl create -f secret-mount-pod.yml". Once the pod is created , log in to the pod and see if we can see the secretes,

[root@manja17-I13330 kubenetes-config]# kubectl exec testing-service -c testing -it bash
root@testing-service:/usr/src/app# mount | grep apikey
tmpfs on /tmp/apikey type tmpfs (ro,relatime,seclabel)
root@testing-service:/usr/src/app# cat /tmp/apikey/apikey.txt
A19fh68B001j
root@testing-service:/usr/src/app# exit
exit

From inside the container , we can see the mount point where apikey is available and when we use the cat command with the apikey.txt i can see the contents. this is how applications will also consume secrets attached to the pod.

Create a secret using the Yml file -
As we already discussed a yml file can be created using a yml file even.

[root@manja17-I13330 kubenetes-config]# echo 'admin' | base64
YWRtaW4K
[root@manja17-I13330 kubenetes-config]# echo 'password' | base64
cGFzc3dvcmQK

The above admin and password can always be decoded using,
[root@manja17-I13330 kubenetes-config]# echo 'YWRtaW4K' | base64 --decode
admin

Create a secret file as,
[root@manja17-I13330 kubenetes-config]# cat secrets.yml
apiVersion: v1
kind: Secret
metadata:
 name: mysecret
type: Opaque
data:
 username: YWRtaW4K
 password: cGFzc3dvcmQK

[root@manja17-I13330 kubenetes-config]# kubectl create -f secrets.yml
secret "mysecret" created

[root@manja17-I13330 kubenetes-config]# kubectl get secrets
NAME                   TYPE                 DATA AGE
default-token-fx8mm   kubernetes.io/service-account-token   3 2h
mysecret               Opaque                 2 5s

We can get the secret details using,
[root@manja17-I13330 kubenetes-config]# kubectl get secret mysecret -o yaml
apiVersion: v1
data:
 password: cGFzc3dvcmQK
 username: YWRtaW4K
kind: Secret
metadata:
 creationTimestamp: 2018-05-19T16:23:29Z
 name: mysecret
 namespace: default
 resourceVersion: "11094"
 selfLink: /api/v1/namespaces/default/secrets/mysecret
 uid: f7598c5a-5b80-11e8-9494-020055e1ea1d
type: Opaque

Create a pod with the above secret using,
[root@manja17-I13330 kubenetes-config]# cat secret-file-mount.yml
apiVersion: v1
kind: Pod
metadata:
 name: testing-service
spec:
 containers:
 - name: testing
   image: docker.io/jagadesh1982/testing-service
   volumeMounts:
   - name: foo
     mountPath: "/etc/foo"
     readOnly: true
 volumes:
 - name: foo
   secret:
     secretName: mysecret

Once the pod is created we can login to the pod and see the secrets using,
[root@manja17-I13330 kubenetes-config]# kubectl exec testing-service -c testing -it bash
root@testing-service:/usr/src/app# mount | grep foo
tmpfs on /etc/foo type tmpfs (ro,relatime,seclabel)
root@testing-service:/usr/src/app# cd /etc/foo
root@testing-service:/etc/foo# cat username
admin
root@testing-service:/etc/foo# cat password
password
root@testing-service:/etc/foo# exit
exit

Passing secret as Env Variable -
A secret when created can be also passed as environment variable to the pod. this can be done as,
[root@manja17-I13330 kubenetes-config]# cat secret-env-mount.yml
apiVersion: v1
kind: Pod
metadata:
 name: testing-service
spec:
 containers:
 - name: testing
   image: docker.io/jagadesh1982/testing-service
   env:
     - name: SECRET_USERNAME
       valueFrom:
         secretKeyRef:
           name: mysecret
           key: username
     - name: SECRET_PASSWORD
       valueFrom:
         secretKeyRef:
           name: mysecret
           key: password
 restartPolicy: Never

Iam using the same secret file created above,
[root@manja17-I13330 kubenetes-config]# cat secrets.yml
apiVersion: v1
kind: Secret
metadata:
 name: mysecret
type: Opaque
data:
 username: YWRtaW4K
 password: cGFzc3dvcmQK

Login to the pod and see if the we can see the environment variables as,
[root@manja17-I13330 kubenetes-config]# kubectl exec testing-service -c testing -it bash
root@testing-service:/usr/src/app# set | grep SECRET
SECRET_PASSWORD=$'password\n'
SECRET_USERNAME=$'admin\n'
root@testing-service:/usr/src/app# exit
exit

This is how a secret can be used with the pod. More to Come. Happy learning :-)

No comments :

Post a Comment