Kubernetes

The Complete Guide to Secrets, Ingress, and Pod Security Policies (Part 2)

Secrets Ingress Pod Security Policies
Written by MilanMaximo

Welcome to the second part of my three-part guide on Kubernetes CLI! In this part, we will be exploring the use of Kubernetes secrets, ingress, and pod security policies to secure and scale your Kubernetes clusters. If you’ve read the first part of this guide, you’ll already have a solid foundation of knowledge on how to manage Kubernetes resources using the CLI.
Now, it’s time to take it a step further and learn how to secure your clusters and ensure scalability. In this part, we’ll cover everything from creating and managing secrets to configuring ingress for external traffic. We’ll also explore pod security policies and how they can help you ensure the security of your pods.

So, let’s get started and take your Kubernetes knowledge to the next level!

Secrets

Secrets in Kubernetes are used to store sensitive information such as passwords, API keys, and other confidential data. They are encrypted and can be accessed only by authorized parties, ensuring that sensitive information is kept secure.

Create a new Secret from literal values:

kubectl create secret generic my-secret --from-literal=username='myuser' --from-literal=password='mypassword'

Create a new Secret from a file:

kubectl create secret generic my-secret --from-file=secrets.yaml

Delete a Secret:

kubectl delete secret my-secret

Edit a Secret:

kubectl edit secret my-secret

Add a key-value pair to an existing Secret:

kubectl patch secret my-secret -p '{"data": {"newkey": "newvalue"}}'

Remove a key-value pair from an existing Secret:

kubectl patch secret my-secret -p '{"data": {"oldkey": null}}'

View the data in a Secret:

kubectl get secret my-secret -o jsonpath='{.data}'

Decode the data in a Secret:

kubectl get secret my-secret -o jsonpath='{.data.password}' | base64 --decode

Create a new Secret with a specific type:

kubectl create secret generic my-secret --type=Opaque --from-literal=username='myuser' --from-literal=password='mypassword'

View the metadata of a Secret:

kubectl describe secret my-secret

Add or update multiple key-value pairs to an existing Secret:

kubectl create secret generic my-secret --from-literal=newkey=newvalue --dry-run=client -o yaml | kubectl apply -f -

Export a Secret to a file:

kubectl get secret my-secret -o yaml > secrets.yaml

Import a Secret from a file:

kubectl apply -f secrets.yaml

Create a Secret using a Kubernetes manifest file:

kubectl apply -f my-secret.yaml

Create a Secret with a custom name:

kubectl create secret generic my-secret --from-literal=username='myuser' --from-literal=password='mypassword' --namespace=my-namespace

Create a Secret with labels:

kubectl create secret generic my-secret --from-literal=username='myuser' --from-literal=password='mypassword' --labels=app=myapp,env=dev

Update a Secret by merging data:

kubectl patch secret my-secret --type='json' -p='[{"op": "add", "path": "/data/newkey", "value": "newvalue"}]'

Update a Secret by replacing data:

kubectl create secret generic my-secret --from-literal=newkey=newvalue --dry-run=client -o yaml | kubectl replace -f -

Create a Secret with a TLS certificate:

kubectl create secret tls my-secret --cert=cert.pem --key=key.pem

View the content of a TLS Secret:

kubectl get secret my-secret -o jsonpath='{.data.tls\.crt}' | base64 --decode

Note: The above commands assume that you have already authenticated with your Kubernetes cluster and have the appropriate permissions to work with Secrets.
The above commands are just examples and may need to be modified to fit your specific use case. Also, keep in mind that Secrets are a sensitive resource and should be handled with care to avoid leaking sensitive data.
These examples assume that you have the necessary files (e.g., cert.pem, key.pem) or information (e.g., myuser, mypassword) to create Secrets. You should always take appropriate security measures when working with sensitive information.

Persistent Volume

Persistent Volumes are a way to store data in Kubernetes clusters. They are network-attached storage resources that can be accessed by Pods. They are useful for storing data that needs to persist even if the Pod is deleted.

Create a Persistent Volume:

kubectl create pv my-pv --capacity=1Gi --access-mode=ReadWriteOnce --hostPath=path/to/my/data

Delete a Persistent Volume:

kubectl delete pv my-pv

Update a Persistent Volume:

kubectl patch pv my-pv --patch '{"spec": {"accessModes":["ReadWriteMany"]}}'

Get details about a Persistent Volume:

kubectl describe pv my-pv

List all Persistent Volumes:

kubectl get pv

Edit a Persistent Volume:

kubectl edit pv my-pv

Set a Persistent Volume’s reclaim policy:

kubectl patch pv my-pv --patch '{"spec": {"persistentVolumeReclaimPolicy":"Recycle"}}'

Mark a Persistent Volume as “Released”:

kubectl patch pv my-pv --patch '{"spec": {"claimRef": null}}'

Mark a Persistent Volume as “Bound”:

kubectl patch pv my-pv --patch '{"spec": {"claimRef": {"namespace": "mynamespace", "name": "my-pvc"}}}'

List Persistent Volumes with a specific label:

kubectl get pv -l app=my-app

Filter Persistent Volumes by storage class:

kubectl get pv --field-selector spec.storageClassName=ssd

Set a Persistent Volume’s storage class:

kubectl patch pv my-pv --patch '{"spec": {"storageClassName":"fast"}}'

Mark a Persistent Volume for deletion:

kubectl delete pv my-pv --grace-period=0 --force

List Persistent Volumes sorted by creation time:

kubectl get pv --sort-by=.metadata.creationTimestamp

List Persistent Volumes sorted by capacity:

kubectl get pv --sort-by=.spec.capacity.storage

Set a Persistent Volume’s access mode:

kubectl patch pv my-pv --patch '{"spec": {"accessModes":["ReadWriteMany"]}}'

Set a Persistent Volume’s storage capacity:

kubectl patch pv my-pv --patch '{"spec": {"capacity":{"storage":"2Gi"}}}'

Set a Persistent Volume’s mount options:

kubectl patch pv my-pv --patch '{"spec": {"mountOptions":["ro"]}}'

Set a Persistent Volume’s NFS mount options:

kubectl patch pv my-pv --type json -p '[{"op": "add", "path": "/spec/nfs", "value": {"server":"192.168.0.100", "path":"/exports/myvol", "readOnly":true}}]'

Set a Persistent Volume’s owner reference:

kubectl patch pv my-pv --type merge -p '{"metadata": {"ownerReferences": [{"apiVersion": "v1", "kind": "Namespace", "name": "mynamespace", "uid": "1234", "controller": true}]}}'

Persistent Volume Claims

A Persistent Volume Claim is a request for storage made by a Pod. It allows the Pod to use a specific Persistent Volume, which ensures that the Pod has access to the required storage capacity.

Create a new Persistent Volume Claim with default settings:

kubectl create pvc my-pvc --claim-size=1Gi --access-mode=ReadWriteOnce --storage-class=standard

Update the storage class of an existing Persistent Volume Claim:

kubectl patch pvc my-pvc --patch '{"spec": {"storageClassName": "new-storage-class"}}'

Scale up the size of an existing Persistent Volume Claim:

kubectl patch pvc my-pvc --patch '{"spec": {"resources": {"requests": {"storage": "2Gi"}}}}'

Delete an existing Persistent Volume Claim:

kubectl delete pvc my-pvc

Set a label on an existing Persistent Volume Claim:

kubectl label pvc my-pvc environment=production

Remove a label from an existing Persistent Volume Claim:

kubectl label pvc my-pvc environment-

View the status of all Persistent Volume Claims in the current namespace:

kubectl get pvc

View detailed information about a specific Persistent Volume Claim:

kubectl describe pvc my-pvc

View the YAML configuration for an existing Persistent Volume Claim:

kubectl get pvc my-pvc -o yaml

Create a new Persistent Volume Claim using a YAML configuration file:

kubectl apply -f my-pvc.yaml

Update an existing Persistent Volume Claim using a YAML configuration file:

kubectl apply -f my-updated-pvc.yaml

View the logs for a container in a Pod that is using a Persistent Volume Claim:

kubectl logs my-pod my-container

Ingress

Ingress is a way to route traffic into a Kubernetes cluster. It acts as a gateway for incoming traffic and directs it to the correct Service or Pod. It can also be used to configure SSL/TLS encryption for incoming traffic.

Create a new Ingress:

kubectl create ingress my-ingress --rule="host:example.com,path:/foo,backend:serviceName:servicePort"

Update the backend service and port of an existing Ingress:

kubectl patch ingress my-ingress --patch '{"spec": {"rules": [{"host": "example.com","http": {"paths": [{"path": "/foo","backend": {"serviceName": "new-service","servicePort": 8080}}]}}]}}'

Scale up the number of replicas for the backend service of an Ingress:

kubectl scale deployment my-deployment --replicas=3

Delete an existing Ingress:

kubectl delete ingress my-ingress

Set a label on an existing Ingress:

kubectl label ingress my-ingress environment=production

Remove a label from an existing Ingress:

kubectl label ingress my-ingress environment-

View the status of all Ingresses in the current namespace:

kubectl get ingress

View detailed information about a specific Ingress:

kubectl describe ingress my-ingress

View the YAML configuration for an existing Ingress:

kubectl get ingress my-ingress -o yaml

Create a new Ingress using a YAML configuration file:

kubectl apply -f my-ingress.yaml

Update an existing Ingress using a YAML configuration file:

kubectl apply -f my-updated-ingress.yaml

View the logs for a Pod that is serving traffic for an Ingress:

kubectl logs my-pod

Update the TLS configuration of an existing Ingress:

kubectl patch ingress my-ingress --type=json -p='[{"op": "add", "path": "/spec/tls/0", "value": {"hosts": ["example.com"], "secretName": "tls-secret"}}]'

Set a new annotation on an existing Ingress:

kubectl annotate ingress my-ingress my-annotation=my-value

Remove an annotation from an existing Ingress:

kubectl annotate ingress my-ingress my-annotation-

Scale up the number of replicas for all backend services of an Ingress:

kubectl scale deployment --all --replicas=3

Rollback an Ingress to a previous revision:

kubectl rollout undo ingress my-ingress

Pause an Ingress rollout:

kubectl rollout pause ingress my-ingress

Resume an Ingress rollout:

kubectl rollout resume ingress my-ingress

View the status of an Ingress rollout:

kubectl rollout status ingress my-ingress

Forcefully update the configuration of an existing Ingress:

kubectl apply -f my-updated-ingress.yaml --force

Conclusion: These are just a few examples of imperative commands for working with Kubernetes Ingress resources. The exact commands and parameters you use will depend on your specific use case and configuration.
These are just a few more examples of imperative commands for working with Kubernetes Ingress resources. The exact commands and parameters you use will depend on your specific use case and configuration.

Daemon Sets

Daemon Sets ensure that a specific Pod runs on every node in a Kubernetes cluster. This is useful for running system-level daemons or other background processes that need to be present on every node.

Create a DaemonSet:

kubectl create daemonset my-daemonset --image=my-image

Update the image of a DaemonSet:

kubectl set image daemonset my-daemonset my-container=my-new-image

Scale a DaemonSet to 5 replicas:

kubectl scale daemonset my-daemonset --replicas=5

Rollout a new version of a DaemonSet:

kubectl rollout daemonset my-daemonset --image=my-new-image

Pause a DaemonSet:

kubectl rollout pause daemonset my-daemonset

Resume a paused DaemonSet:

kubectl rollout resume daemonset my-daemonset

Check the rollout history of a DaemonSet:

kubectl rollout history daemonset my-daemonset

Undo the last rollout of a DaemonSet:

kubectl rollout undo daemonset my-daemonset

Rollback to a specific revision of a DaemonSet:

kubectl rollout undo daemonset my-daemonset --to-revision=2

Restart all pods of a DaemonSet:

kubectl rollout restart daemonset my-daemonset

Delete a DaemonSet:

kubectl delete daemonset my-daemonset

Get the logs of a container in a DaemonSet:

kubectl logs daemonset/my-daemonset -c my-container

Get the status of a DaemonSet:

kubectl get daemonset my-daemonset

Get detailed information about a DaemonSet:

kubectl describe daemonset my-daemonset

Update the resource limits of a DaemonSet:

kubectl set resources daemonset my-daemonset -c my-container --limits=cpu=200m,memory=512Mi

Update the resource requests of a DaemonSet:

kubectl set resources daemonset my-daemonset -c my-container --requests=cpu=100m,memory=256Mi

Horizontal Pod Autoscaling

Horizontal Pod Autoscaling automatically scales the number of Pods based on CPU utilization or other metrics. This helps ensure that the cluster can handle increased traffic or workload demands.

Create an autoscaler for a deployment:

kubectl autoscale deployment my-deployment --cpu-percent=80 --min=2 --max=10

Update the min and max replicas of an autoscaler:

kubectl scale --current-replicas=2 --min=1 --max=5 deployment/my-deployment

Update the CPU target of an autoscaler:

kubectl patch hpa my-hpa -p '{"spec":{"targetCPUUtilizationPercentage": "50"}}'

Delete an autoscaler:

kubectl delete hpa my-hpa

Get the status of an autoscaler:

kubectl get hpa my-hpa

Get detailed information about an autoscaler:

kubectl describe hpa my-hpa

Update the max replicas of an autoscaler:

kubectl patch hpa my-hpa -p '{"spec":{"maxReplicas": "10"}}'

Update the min replicas of an autoscaler:

kubectl patch hpa my-hpa -p '{"spec":{"minReplicas": "3"}}'

Update the CPU and memory targets of an autoscaler:

kubectl autoscale deployment my-deployment --cpu-percent=50 --min=2 --max=10 --memory-percent=80

Update the metrics of an autoscaler:

kubectl patch hpa my-hpa -p '{"spec":{"metrics":[{"type":"Resource","resource":{"name":"cpu","target":{"type":"Utilization","averageUtilization":50}}},{"type":"Resource","resource":{"name":"memory","target":{"type":"Utilization","averageUtilization":80}}}]}}'

Update the scaling behavior of an autoscaler:

kubectl patch hpa my-hpa -p '{"spec":{"behavior":{"scaleUp":{"stabilizationWindowSeconds":120,"policies":[{"type":"Pods","value":3,"periodSeconds":10}]},"scaleDown":{"stabilizationWindowSeconds":120,"policies":[{"type":"Percent","value":50,"periodSeconds":10}]}}}}'

Get the events related to an autoscaler:

kubectl get events --field-selector involvedObject.kind=HorizontalPodAutoscaler --all-namespaces

Update the behavior of an autoscaler to use the CPU and memory targets:

kubectl patch hpa my-hpa -p '{"spec":{"behavior":"predictable"}}'

Update the behavior of an autoscaler to use the default behavior:

kubectl patch hpa my-hpa -p '{"spec":{"behavior":"default"}}'

Update the behavior of an autoscaler to use the custom behavior:

kubectl patch hpa my-hpa -p '{"spec":{"behavior":"custom"}}'

Get the metrics of an autoscaler:

kubectl get --raw "/apis/metrics.k8s.io/v1beta1/namespaces/my-namespace/pods" | jq '.items[] | select(.metadata.name | contains("my-deployment")) | .containers[].usage.cpu' | paste -sd+ - | bc

Get the recommended configuration for an autoscaler:

kubectl autoscale --dry-run --cpu-percent=50 --min=2 --max=10 deployment/my-deployment

Vertical Pod Autoscaling

Vertical Pod Autoscaling automatically adjusts the CPU and memory resources allocated to a Pod based on its usage patterns. This ensures that the Pod has the necessary resources to run efficiently.

Enable VPA for a deployment:

kubectl create vpa my-vpa --namespace=my-namespace --target=my-deployment --update-policy=auto

Update the VPA resource:

kubectl patch vpa my-vpa --namespace=my-namespace --patch '{"spec":{"updatePolicy":{"updateMode":"Off"}}}'

Disable VPA for a deployment:

kubectl delete vpa my-vpa --namespace=my-namespace

Get the status of a VPA:

kubectl get vpa my-vpa --namespace=my-namespace

Get detailed information about a VPA:

kubectl describe vpa my-vpa --namespace=my-namespace

Get the recommended configuration for a VPA:

kubectl get pods --namespace=my-namespace --selector=app=my-app --output=json | vpa-admission-controller

Get the logs of the VPA controller:

kubectl logs -f vpa-recommender-6cf5c6d5b6-ltf8w --namespace=my-namespace -c vpa-recommender

Get the metrics of a VPA:

kubectl get --raw "/apis/metrics.k8s.io/v1beta1/namespaces/my-namespace/pods" | jq '.items[] | select(.metadata.name | contains("my-deployment")) | .containers[].usage.cpu' | paste -sd+ - | bc

Check if VPA is supported on the cluster:

kubectl api-versions | grep "autoscaling.k8s.io/v1beta2" && kubectl api-versions | grep "vpa.k8s.io/v1"

Update the target reference of a VPA:

kubectl patch vpa my-vpa --namespace=my-namespace --type=json -p='[{"op": "replace", "path": "/spec/targetRef", "value": {"kind": "Deployment", "name": "my-deployment"}}]'

Update the update policy of a VPA:

kubectl patch vpa my-vpa --namespace=my-namespace --type=json -p='[{"op": "replace", "path": "/spec/updatePolicy", "value": {"updateMode": "Auto", "updateBudget": {"maxSurge": "25%", "maxUnavailable": "25%"}}}]'

Update the resource policy of a VPA:

kubectl patch vpa my-vpa --namespace=my-namespace --type=json -p='[{"op": "replace", "path": "/spec/resourcePolicy", "value": {"containerPolicies": [{"containerName": "my-container", "mode": "Auto", "minAllowed": {"cpu": "100m", "memory": "256Mi"}, "maxAllowed": {"cpu": "200m", "memory": "512Mi"}}]}}]'

Update the update policy and resource policy of a VPA:

kubectl patch vpa my-vpa --namespace=my-namespace --type=json -p='[{"op": "replace", "path": "/spec/updatePolicy", "value": {"updateMode": "Auto", "updateBudget": {"maxSurge": "25%", "maxUnavailable": "25%"}}, "resourcePolicy": {"containerPolicies": [{"containerName": "my-container", "mode": "Auto", "minAllowed": {"cpu": "100m", "memory": "256Mi"}, "maxAllowed": {"cpu": "200m", "memory": "512Mi"}}]}}]'

Update the annotation of a deployment to use a VPA:

kubectl annotate deployment my-deployment --namespace=my-namespace vertical-pod-autoscaler=my-vpa

Remove the annotation of a deployment to disable VPA:

kubectl annotate deployment my-deployment --namespace=my-namespace vertical-pod-autoscaler-

Pod Disruption Budget:

Pod Disruption Budgets ensure that a minimum number of Pods are always available in a deployment. This helps prevent service disruptions during upgrades or maintenance periods.

Create a Pod Disruption Budget:

kubectl create pdb my-pdb --namespace=my-namespace --selector=app=my-app --min-available=2

Update a Pod Disruption Budget:

kubectl patch pdb my-pdb --namespace=my-namespace --type=json -p='[{"op": "replace", "path": "/spec/minAvailable", "value": 3}]'

Delete a Pod Disruption Budget:

kubectl delete pdb my-pdb --namespace=my-namespace

List all Pod Disruption Budgets:

kubectl get pdb --all-namespaces

Describe a Pod Disruption Budget:

kubectl describe pdb my-pdb --namespace=my-namespace

Set a Pod Disruption Budget on a Deployment:

kubectl patch deployment my-deployment --namespace=my-namespace -p '{"spec": {"minAvailable": 2, "strategy": {"type": "RollingUpdate", "rollingUpdate": {"maxUnavailable": 1}}}}'

Remove a Pod Disruption Budget from a Deployment:

kubectl patch deployment my-deployment --namespace=my-namespace -p '{"spec": {"minAvailable": null}}'

Check the status of a Pod Disruption Budget:

kubectl describe pdb my-pdb --namespace=my-namespace | grep Status

Check the status of a Pod with respect to a Pod Disruption Budget:

kubectl describe pod my-pod --namespace=my-namespace | grep PodScheduled

Simulate the eviction of a Pod in a Pod Disruption Budget:

kubectl drain my-node --ignore-daemonsets --delete-local-data --force --grace-period=30 --pod-selector=app=my-app

Resource Quota

Resource Quotas limit the amount of CPU, memory, and storage resources that a user or group can use in a Kubernetes cluster. This helps ensure that resources are distributed fairly and prevents any one user or group from consuming too many resources.

Create a Resource Quota:

kubectl create quota my-quota --hard=pods=5,requests.cpu=1,requests.memory=1G,limits.cpu=2,limits.memory=2G --namespace=my-namespace

Update a Resource Quota:

kubectl patch quota my-quota --namespace=my-namespace --type='json' -p='[{"op": "replace", "path": "/spec/hard/limits.cpu", "value": "4"}]'

Delete a Resource Quota:

kubectl delete quota my-quota --namespace=my-namespace

List all Resource Quotas:

kubectl get quota --all-namespaces

Describe a Resource Quota:

kubectl describe quota my-quota --namespace=my-namespace

Check the usage of a Resource Quota:

kubectl describe quota my-quota --namespace=my-namespace | grep Used

Check the usage of a Resource Quota by a specific Pod:

kubectl describe pod my-pod --namespace=my-namespace | grep -A 2 Resource

List all Pods and their resource usage in a namespace:

kubectl top pods --namespace=my-namespace

List all Nodes and their resource usage:

kubectl top nodes

List all Pods using a specific resource:

kubectl describe pods --all-namespaces | grep -A 5 Resources.*<resource_name>

List all Resource Quotas and their associated Pods:

kubectl describe quota --namespace=my-namespace | grep -A 5 Used

Check if a Pod satisfies a Resource Quota:

kubectl auth can-i create pod --dry-run --namespace=my-namespace --resource=pods --subresource=podquotas --pod-template-file=my-pod.yaml

Service Accounts

Service Accounts are used to provide authentication and authorization for Pods running in a Kubernetes cluster. They allow Pods to access other resources, such as Secrets or Persistent Volumes, without having to manage credentials themselves.

Create a Service Account named “my-service-account” in the “my-namespace” namespace:

kubectl create serviceaccount my-service-account -n my-namespace

View the details of a Service Account named “my-service-account” in the “my-namespace” namespace:

kubectl get serviceaccount my-service-account -n my-namespace

Delete a Service Account named “my-service-account” in the “my-namespace” namespace:

kubectl delete serviceaccount my-service-account -n my-namespace

Create a new Secret named “my-secret” in the “my-namespace” namespace containing a Service Account token for “my-service-account”:

kubectl create secret generic my-secret --from-literal=token="$(kubectl get serviceaccount my-service-account -n my-namespace -o jsonpath='{.secrets[0].data.token}' | base64 -d)" -n my-namespace

Create a new Pod named “my-pod” in the “my-namespace” namespace with a specific Service Account:

kubectl run my-pod --image=my-image --serviceaccount=my-service-account -n my-namespace

Update the Service Account of a running Pod named “my-pod” in the “my-namespace” namespace:

kubectl patch pod my-pod -p '{"spec":{"serviceAccountName":"new-service-account"}}' -n my-namespace

Create a new Role named “my-role” in the “my-namespace” namespace with permissions to access a specific Service Account:

kubectl create role my-role --verb=get --verb=list --resource=pods --namespace=my-namespace --serviceaccount=my-namespace:my-service-account

Bind a Role named “my-role” to a RoleBinding named “my-role-binding” in the “my-namespace” namespace:

kubectl create rolebinding my-role-binding --role=my-role --serviceaccount=my-namespace:my-service-account --namespace=my-namespace

List all Service Accounts in the “my-namespace” namespace:

kubectl get serviceaccounts -n my-namespace

Describe the Service Account named “my-service-account” in the “my-namespace” namespace:

kubectl describe serviceaccount my-service-account -n my-namespace

Create a new Service Account named “my-service-account” in the “my-namespace” namespace:

kubectl create serviceaccount my-service-account -n my-namespace

Delete the Service Account named “my-service-account” in the “my-namespace” namespace:

kubectl delete serviceaccount my-service-account -n my-namespace

Update the image pull secret of a Service Account named “my-service-account” in the “my-namespace” namespace:

kubectl patch serviceaccount my-service-account -p '{"imagePullSecrets": [{"name": "my-secret"}]}' -n my-namespace

About the author

MilanMaximo

Leave a Comment