- kubernetes.io -> Tasks -> Configure Pods and Containers -> Configure a Pod to Use a ConfigMap
- kubernetes.io -> Concepts -> Configuration -> Secrets
- kubernetes.io -> Tasks -> Inject Data Into Applications -> Distribute Credentials Securely Using Secrets
- kubernetes.io -> Tasks -> Configure Pods and Containers -> Configure a Pod to Use a Volume for Storage
- kubernetes.io -> Tasks -> Configure Pods and Containers -> Configure a Pod to Use a PersistentVolume for Storage
- kubernetes.io -> Concepts -> Workloads -> Controllers -> Deployments
echo -e "key1=value1\nkey2=value2" > /path/to/file
kubectl create configmap config \
--from-literal=akey=avalue \
--from-file=/path/to/file \
--from-file=/path/to/dir/
kubectl get configmap config -o yaml
# Or
kubectl describe configmap config
kubectl run nginx --image=nginx --restart=Never --dry-run -o yaml > pod.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: nginx
name: nginx
spec:
containers:
- image: nginx
name: nginx
resources: {}
env:
- name: config # env var name
valueFrom:
configMapKeyRef:
name: config # configmap name
key: akey # key name in the cm. If ignored, will get all
dnsPolicy: ClusterFirst
restartPolicy: Never
status: {}
kubectl create -f pod.yaml
kubectl exec -it nginx -- env
vi pod.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: nginx
name: nginx
spec:
containers:
- image: nginx
name: nginx
resources: {}
env:
- name: config # env var name
valueFrom:
configMapKeyRef:
name: config # configmap name
key: akey # key name in the cm. If ignored, will get all
volumeMounts:
- name: my-config-vol # reference to name of the volume, see below
mountPath: /etc/config # path inside the container
volume:
- name: my-config-vol # name of the volume
configMap:
name: config # name of the configMap
dnsPolicy: ClusterFirst
restartPolicy: Never
status: {}
kubectl exec -it nginx -- /bin/sh -c 'ls -l /etc/config && cat /etc/config/key1'
Create the base64-encoded output for the data
echo -n "superpassword" | base64
Include it in the Secret.data
object. Create it from scratch using the documentation.
apiVersion: v1
kind: Secret
metadata:
name: demo-secret
data:
password: c3VwZXJwYXNzd29yZA==
echo -n "admin" > username
kubectl create secret generic demo-secret-1 \
--from-literal=password='c3VwZXJwYXNzd29yZA==' \
--from-file=username
kubectl get secret demo-secret-1 \
-o jsonpath='{.data.username}{"\n"}' | base64 -d
Create the Pod or Deployment
kubectl run nginx --image=nginx --restart=Never -o yaml --dry-run > pod.yaml
Add the volume to spec.volumes
and mount it in the container with spec.containers[n].volumeMounts
apiVersion: v1
kind: Pod
...
spec:
volumes:
- name: demo-secret-volume
secret:
secretName: demo-secret-1
containers:
- name: nginx
volumeMounts:
- name: demo-secret-vm
mountPath: /etc/secret
...
Check
kubectl exec nginx -- /bin/bash -c \
'ls -l /etc/secret && cat /etc/secret/username && cat /etc/secret/password'
It prints the files username
and password
, then admin
and c3VwZXJwYXNzd29yZA==
.
Add in the Pod into spec.containers[n].env
apiVersion: v1
kind: Pod
...
spec:
containers:
- name: test-container
env:
- name: USERNAME
valueFrom:
secretKeyRef:
name: demo-secret-1
key: username
- name: PASSWORD
valueFrom:
secretKeyRef:
name: demo-secret-1
key: password
...
Also, you could add into the Pod Pod.spec.containers[n].envFrom[*].secretRef.name
apiVersion: v1
kind: Pod
...
spec:
containers:
- name: test-container
env:
- name: USERNAME
envFrom:
- secretRef:
name: demo-secret-1
...
Check
kubectl exec nginx -- /bin/bash -c 'echo $USERNAME:$PASSWORD'
- Create the Presistent Volume
- Create the Persistent Volume Claim
- Add the Volume to the Pod and to the Container
It's created from scratch, get help from the kubernetes.io documentation
apiVersion: v1
kind: PersistentVolume
metadata:
name: demo-pv-volume
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 10Gi
accessMode:
- ReadWriteOnce
hostPath:
path: "/mnt/data"
If you are in Kubernetes on Docker Desktop, make sure the path
is in the File Sharing list.
It's created from scratch, get help from the kubernetes.io documentation
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: demo-pv-claim
spec:
storageClassName: manual # use the same class name as the PV
accessModes:
- ReadWriteOnce # use one of the mode used by the PV
resources:
request:
storage: 3Gi # make sure is =< than the PV capacity
When created, make sure the status is Bound
.
Generate the code for the Pod or Deployment:
kubectl run nginx --image=nginx --restart=Never -o yaml --dry-run > pod.yaml
Add the volume to the Pod in Pod.spec.volumes
apiVersion: v1
kind: Pod
...
spec:
volumes:
- name: demo-pv-storage
persistentVolumeClaim:
claimName: demo-pv-claim
containers:
...
Add the volume to the Container in Pod.spec.containers[n].volumeMounts
apiVersion: v1
kind: Pod
...
spec:
containers:
- name: nginx
volumeMounts:
- mountPath: "/var/log/nginx"
name: demo-pv-storage # same name as in volumes section
...
To check the content of the volume inside the container use:
kubectl exec nginx -it -- ls /var/log/nginx
In your local system:
ls /mnt/data
They should have the same data.
Use allways version tags in the images, try to avoid :latest
tag.
To update the pod or deployment use kubectl set
or kubectl edit
.
export KUBE_EDITOR=vim
kubectl edit deployment demo
Or,
kubectl set image deployment demo simpleapp=simpleapp:v2
kubectl set image TYPE NAME CONTAINER1=IMAGE1 CONTAINER2=IMAGE2 ...
kubectl rollout status deployment demo
kubectl rollout undo deployment demo --dry-run
kubectl rollout undo deployment demo
kubectl rollout history deployment demo
kubectl rollout undo deployment demo --revision=1
kubectl describe deployment demo | grep Image:
# Also
diff <(kubectl rollout history deploy demo --revision=1) \
<(kubectl rollout history deploy demo --revision=2)
kubectl scale deployment demo --replicas=5
Between 5-10 pods, autoscale when CPU arrives to 80%
kubectl autoscale deployment demo --min=5 --max=10 --cpu-percent=80
kubectl get hpa
kubectl rollout pause deployment demo
kubectl rollout resume deployment demo
emptyDir storage:
apiVersion: v1
kind: Pod
metadata:
name: busybox
spec:
containers:
- name: busy
image: busybox
command: ["sleep", "3600"]
volumeMounts:
- name: scratch-vol
mountPath: /scratch
volumes:
- name: scratch-vol
emptyDir: {}
emptyDir shared volume
...
spec:
containers:
- name: busy
image: busybox
volumenMounts:
- name: test
mountPath: /busy
- name: box
image: busybox
volumeMounts:
- name: test
mountPath: /box
volumens:
- name: test
emptyDir: {}
$ kubectl exec -it busybox -c box -- touch /box/foobar
$ kubectl exec -it busybox -c busy -- ls /busy
foobar
Persistent Volume of type hostPath
apiVersion: v1
kind: PersistentVolume
metadata:
name: 10Gpv01
labels:
type: local
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/some/path/data01"
Persistent Volume Claim for the declared Persistent Volume
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: myclaim
spec:
accessModes:
- ReadWriteOnce
resources:
request:
storage: 8Gi
kind: Pod
...
spec:
containers:
...
volumes:
- name: test-vol
persistentVolumeClaim:
claimName: myclaim
Persistent Volume Claim with rbd of Ceph
volumeMounts:
- name: cephpd
mountPath: "/data/rbd"
volumes:
- name: rbdpd
rbd:
image: client
monitor:
- "10.19.14.22:6789"
- "10.19.14.23:6789"
- "10.19.14.24:6789"
pool: k8s
fsType: ext4
readOnly: true
user: admin
keyring: /etc/ceph/keyring
imageformat: "2"
imagefeatures: "layering"
$ echo secreto | base64
c2VjcmV0bwo=
apiVersion: v1
kind: Secret
metadata:
name: mysql
data:
password: c2VjcmV0bwo=
Secret as environment variable
kind: Pod
...
spec:
containers:
- name: mysql
image: mysql
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql
key: password
Secret as a volume
kind: Pod
...
spec:
containers:
- name: busy
image: busybox
command: ["sleep", "3600"]
volumenMounts:
- name: mysql
mountPath: /mysqlpassword
volumes:
- name: mysql
secret:
secretName: mysql
kubectl exec -it busybox -- cat /mysqlpassword/password
As environment variable
kind: Pod
...
spec:
containers:
- name:
env:
- name: LEVEL
valueFrom:
configMapKeyRef:
name: config
key: special
As volumen
volumes:
- name: config-vol
configMap:
name: config