Summary Terms #
- Pod: Is a wrapper that is placed around a container, Kubernetes manages pods.
- Nodes: Is a VM or physical machine that runs the PODS.
- Controller node: It is the node that manages the cluster.
- API Server: The broker between etcd and kubelet process running on worker nodes.
- Scheduler: The process that determines where pods will be ran.
- Controller-manager: A daemon that manages services such as the replication controller, endpoint controller, namespace controller.
- Kubectl: Connects to the API server and is used to control the cluster.
- Kubelet: Runs on all nodes, its main purpose is running pods, pods are defined by a json or yaml file refer to as a manifest.
- Container runtime: Kubelet is the process that runs the container runtime app to invoke a pods.
- Mainfest: The set of instructions that Kubernetes uses for provisioning. below is an example of a pod manifest.
- Resource Quota: Can be used to set a hard limit of what name space is allowed to consume.
- Probes: There are two types of probes liveness and readiness
- Liveness: Polls the pods to determine of the pod is responding. If the pod fails to respond after a period of time this probe will restart the pod.
- Readiness: Polls the pods to determine of the pod is responding. The readiness probe will not add the Pod to the loadBalancer unless the Pod passes the probe check.
Deeper Dive #
Namespaces #
Kubernetes namespaces are a mechanism for logically partitioning a single physical Kubernetes cluster into multiple virtual clusters
- Resource Scoping and Organization: Resources within a namespace must have unique names, but the same name can be reused in a different namespace (e.g., a “web-app” deployment can exist in both a dev and a prod namespace).
- Isolation: Namespaces provide logical isolation, ensuring that actions or resources in one namespace do not interfere with those in another. This separation is key to a stable multi-tenant environment.
- Access Control (RBAC): Namespaces are a fundamental component of Role-Based Access Control (RBAC). Administrators can define specific permissions for users or teams at the namespace level, ensuring they only have access to the resources they need.
- Resource Management and Quotas: Administrators can apply resource quotas and limit ranges to a namespace to control the total amount of CPU, memory, and storage that the contained pods and services can consume. This prevents any single team or application from monopolizing cluster resources.
- Network Policies: Network policies can be defined at the namespace level to control the flow of traffic between pods within a namespace or across different namespaces, adding an essential layer of security
namespace assignment can be controlled via a manifest as well under the metadata section.
metadata:
name: nginx
namespace: demo
| command | Function |
|---|---|
kubectl get namespace |
Lists all namespace |
kubectl create ns demo |
creates a namespace called demo |
kubectl describe ns demo |
Provides information about a namespace such as LimitRange resource, resource quota, and description |
kubectl delete ns demo |
removes namespace called demo |
Resource Quota #
an API object that restricts the total amount of resources (CPU, memory, storage) and object counts (pods, services) a specific namespace can consume. If a namespace were restricted to 1Gb of memory and a series of pods have a requests value of 250m, you would be capped a 4 pods. as the 5th pod would exceed memory limits on the namespace.
Example Resource Quota for a Namespace #
The following content would be written to ResourceQuota.yaml and would apply 4 cpu and 1gb of memory
---
apiVersion: v1
kind: ResourceQuota
metadata:
name: tiny-quota
spec:
hard:
cpu: "4"
memory: 1Gi
| command | Function |
|---|---|
kubectl apply -f ResourceQuota.yaml -n demo |
Applies the above quota to the demo namespace |
kubectl describe ns demo |
Can be used to confirm that the quota is applied |
watch -n 0.1 kubectl describe ns demo |
Allows you to monitor kubectl output, Can be used to confirm that the quota is applied |
Example Resource Quota for a Pod #
The following content would be written to manifest.yaml. If the following manifest were to be be used with the above resource quota, you would be capped a 4 pods. as the 5th pod would exceed both the CPU and Memory limits on the namespace.
---
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: demo
spec:
containers:
- name: nginx
image: nginx:1.14.2
resources:
requests:
cpu: 1 core # = 1000 millicore, could be written as 250m for 1/4 a core
memory: "250M" #
limits: # limits must be at least the what is specified under requests
cpu: 2 core
memory: "500M"
| command | Function |
|---|---|
kubectl create -f manifest.yaml |
Crates a Pod with the above manifest |
kubectl describe ns demo |
Can be used to confirm that the quota is applied |
watch -n 0.1 kubectl describe ns demo |
Allows you to monitor kubectl output, Can be used to confirm that the quota is applied |
Readiness Probes #
There are two types of probes liveness and readiness for more information refer to (Configure Liveness, Readiness and Startup Probes)[https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/]
Liveness Probe #
How many consecutive failures before the container is killed?
---
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: demo
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
livenessProbe:
initialDelaySeconds: 2 # How soon after creation are probes being sent
periodSeconds: 5 # How often there after are probes being sent
timeoutSeconds: 1 # How long are we giving the container to respond to the probe
failureThreshold: 3 # How many consecutive failures before the container is killed
httpGet: # Method of the Probe, http GET to API /health port 80
path: /heath
port: 80
Readiness Probe #
How many consecutive failures before the container has traffic cut off?
---
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: demo
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
readinessProbe:
initialDelaySeconds: 2 # How soon after creation are probes being sent
periodSeconds: 5 # How often there after are probes being sent
timeoutSeconds: 1 # How long are we giving the container to respond to the probe
failureThreshold: 3 # How many consecutive failures before the container has traffic cut off.
httpGet: # Method of the Probe, http GET to API /health port 80
path: /heath
port: 80
ConfigMap #
a configMap is mounted as a volume to the pod. the Volume is mounted as a path to the container at a specific mount point. For more information refer to ConfigMaps
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: demo
spec:
containers:
- name: nginx
image: nginx:1.14.2
volumeMounts:
- name: dc-list
mountPath: "/config" # where in the container will this be mounted, This will OVERWRITE existing directories without a subpath.
subPath: hero.txt # Allows you to write just a file to a directory.
volumes:
# You set volumes at the Pod level, then mount them into containers inside that Pod
- name: config
configMap:
# Provide the name of the ConfigMap you want to mount.
name: dc-list
configMap:
name: my-list
For the purpose of this explanation list.txt would contain a simple list the actual content does not matter. If it would matter if was an configuration file.
| command | Function |
|---|---|
kubectl apply -f manifest.yaml |
deploys a configmaps based of the above manifest |
kubectl get configmaps |
Lists configMaps |
kubectl create configmap my-list --from-file=list.txt |
Creates a configMap |
kubectl create cm my-list --from-file=list.txt |
shorthand version Creates a configMap |
kubectl describe cm my-list |
Provides detailed information about the configMap |
kubectl delete cm my-list |
removes configMap |
Secrets #
A Secret is an object that contains a small amount of sensitive data such as a password, a token, or a key. for more information refer to Secrets
Define a Secret #
apiVersion: v1
kind: Secret
metadata:
name: mysql-secret
type: kubernetes.io/basic-auth
stringData:
password: sup3rSecr3t
| command | Function |
|---|---|
kubectl apply -f manifest.yaml |
deploys a Secret based of the above manifest |
kubectl get secrets |
Lists secrets |
kubectl create secret generic mysql-secret --type=kubernetes.io/basic-auth --from-literal=password=alta3 |
Creates a secret |
kubectl create secret -f secret.yaml |
Creates a secret from a file |
kubectl describe secret mysql-secret |
Provides detailed information about the secret |
kubectl delete secret mysql-secret |
removes secret |
Reference a Secret #
To use a secret.
apiVersion: v1
kind: Pod
metadata:
name: mysql-locked
spec:
containers:
- name: mysql
image: mysql:8-debian
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secret
key: password
ports:
- containerPort: 3306
name: mysql
| command | Function |
|---|---|
kubectl exec -it mysql -- bash |
Connect to the container |
echo $MYSQL_ROOT_PASSWORD |
Since secret was tied to an environment variable echo will print the password. |
Logs #
Logging is a tool to help you troubleshoot issues in your container. More information can be found at kubectl logs
| command | Function |
|---|---|
kubectl describe portainer-agent-7c9df8687-45m5s |
Gets information about the pod |
kubectl logs portainer-agent-7c9df8687-45m5s |
Gets detailed logging information about the container |
kubectl logs deportainer-agent-7c9df8687-45m5smo -c container2 |
Gets detailed logging information about the specified container when a pod has more than one container -c may be needed. |
kubectl logs portainer-agent-7c9df8687-45m5s --all-containers |
Gets detailed logging information about the all containers. |
kubectl logs portainer-agent-7c9df8687-45m5s -n portainer --all-containers |
Gets detailed logging information about the all containers in a specified namespace |
kubectl logs portainer-agent-7c9df8687-45m5s -n portainer --all-containers |
Gets detailed logging information about the all containers in a specified namespace |
kubectl logs portainer-agent-7c9df8687-45m5s -n portainer f |
Follows detailed logging information about the container in a specified namespace |
Labels #
Labels are key/value pairs that are attached to objects such as Pods. Labels are intended to be used to specify identifying attributes of objects that are meaningful and relevant to users, but do not directly imply semantics to the core system. For more information refer to Labels and Selectors
apiVersion: v1
kind: Pod
metadata:
name: label-demo
labels:
environment: production
app: nginx
ver: 2
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
| command | Function |
|---|---|
kubectl label pod label-demo app=nginx |
Can be used to add to existing labels. cannot overwrite existing labels |
kubectl label pod label-demo app=web --overwrite |
Can be used to overwrite a existing label. |
kubectl label pod label-demo app- |
Can be used to remove a existing label. |
kubectl get pods -L app |
Can be used to list Labels with a certain name |
kubectl get pods --selector=app=nginx |
Can be used to list pods that have a specified label and value |
Deployments #
A Deployment manages a set of Pods to run an application workload, usually one that doesn’t maintain state. Deployments
Deployments create replacasets and the replacasets create the pods
Deployments allow for version control, zero down time, and accepts and change made to manifest yaml.
apiVersion: apps/v1
kind: Deployment
metadata: # Metadata of the Deployment
name: nginx-deployment # Name of the Deployment
labels:
app: nginx
spec: # spec of the Deployment
replicas: 3
selector:
matchLabels:
app: nginx
template: # Starts the information of the Pod
metadata: # Metadata of the Pod
labels:
app: nginx
spec: # spec of the pod
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
| command | Function |
|---|---|
kubectl apply -f manifest.yaml |
deploys a deployment based of the above manifest |
kubectl rollout history deploy nginx-deployment |
provides a list of changes to the deployment. e.g if you added a second container to the deployment |
kubectl rollout undo deploy nginx-deployment |
rolls a deployment back from the current revision to the previous revision |
kubectl create deployment nginx-deployment --image=nginx |
deploys a deployment named nginx using the image nginx |
kubectl scale deploy nginx -- replicas 3 |
can be used to increase the number of pods that a deployment is running |
kubectl get pods -o wide |
provides a list of running pods, includes IP and node information |
kubectl delete deployment nginx-deployment |
Provides detailed information about the deployment named ngnix |
Storage #
Ways to provide both long-term and temporary storage to Pods in your cluster. For more information please refer to Storage
hierarchy: Storage Classes -> Persistent Storage -> Volume Claim -> Volume
Storage Classes #
A StorageClass provides a way for administrators to describe the classes of storage they offer. Different classes might map to quality-of-service levels, or to backup policies, or to arbitrary policies determined by the cluster administrators. Kubernetes itself is unopinionated about what classes represent.
Since a storage class is dependant on the provider a process for defining the class is being omitted from this document.
PersistentVolume #
# PersistentVolume manifest
apiVersion: v1
kind: PersistentVolume
metadata:
name: nginx-pv
spec:
storageClassName: manual
capacity:
storage: 2Gi
accessModes:
- ReadWriteOnce # the Volume can only be mounted by one node at a time
hostPath:
path: "/mnt/data" # where on the node is the storage located
---
# PersistentVolumeClaim manifest
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nginx-pvc
spec:
storageClassName: manual # must match storageClassName from the PersistentVolume manifest
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
---
# Pod manifest
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
nodeSelector:
kubernetes.io/hostname: worker1
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
volumeMounts:
name: nginx-storage
mountPath: /etc/nginx/domains
volumes:
- name: nginx-storage
persistentVolumeClaim:
claimName: nginx-pvc
| command | Function |
|---|---|
kubectl apply -f manifest.yaml |
deploys a deployment based of the above manifest |
kubectl get pv,pvc |
Provides a list of PersistentVolume and PersistentVolumeClaim information |
kubectl exec -it nginx -- bash |
Connect to the container to allow you to visually see the directory |
Networking #
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
| command | Function |
|---|---|
kubectl apply -f manifest.yaml |
deploys a deployment based of the above manifest |
kubectl create deployment nginx --image=nginx --port=80 --replicas=3 |
deploys a deployment named nginx using the image nginx |
kubectl expose deployment nginx |
deploys a service used by the deployment |
kubectl get service |
lists services |
kubectl describe svc nginx |
lists services |
Network Policies #
If you want to control traffic flow at the IP address or port level (OSI layer 3 or 4), NetworkPolicies allow you to specify rules for traffic flow within your cluster, and also between Pods and the outside world. Your cluster must use a network plugin that supports NetworkPolicy enforcement. For more information refer to Network Policies
The below example work in an OR manor. ipBlock OR namespaceSelector OR podSelector
# example allow
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
namespace: default # Target the namespace of the Pods this policy should apply against.
spec:
podSelector: # What Pods is this policy supposed to control
matchLabels:
role: db # If you are in the "default" namespace with the "db" label this policy would apply to you.
policyTypes:
- Ingress # Inbound Traffic
- Egress # Outbound Traffic
ingress:
- from:
- ipBlock:
cidr: 172.17.0.0/16 # allows this from network range
except: # blocks this from network range
- 172.17.1.0/24
- namespaceSelector: # allow traffic from a namespace so long as it has the label "myproject"
matchLabels:
project: myproject
- podSelector: # Allow traffic from a pod with the label "frontend"
matchLabels:
role: frontend
ports: # Allow Traffic to this port
- protocol: TCP
port: 6379
egress:
- to:
- ipBlock: # allows this to network range
cidr: 10.0.0.0/24
ports: # allows this to this port
- protocol: TCP
port: 5978
| command | Function |
|---|---|
kubectl apply -f manifest.yaml |
deploys a deployment based of the above manifest |
kubectl get pods --show-labels |
Displays a list of pods and the associated labels |
Other Examples #
---
# example default deny
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-default-network-policy
namespace: default # Target the namespace of the Pods this policy should apply against.
spec:
podSelector: {} # What Pods is this policy supposed to control
policyTypes:
- Ingress # Inbound Traffic
- Egress # Outbound Traffic
---
# example allow based off labels
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-default-network-policy
namespace: default # Target the namespace of the Pods this policy should apply against.
spec:
podSelector: # What Pods is this policy supposed to control
match labels:
app: nginx # Deployment label
policyTypes:
- Ingress # Inbound Traffic
ingress:
- from:
- podSelector: # What pods are allowed
matchLabels:
run: client # Pod with "client" label
Service Manifest #
In Kubernetes, a Service is a method for exposing a network application that is running as one or more Pods in your cluster. For more information refer to Service
---
#
apiVersion: networking.k8s.io/v1
kind: Service
metadata:
name: nginx-svc
spec:
selector:
dem: pods
ports:
- protocol: TCP # Maps TCP 3423 on the service to port 80 on the container
port: 3423
targetPort: 80
- protocol: TCP # Maps TCP 8080 on the service to port 4444 on the container
port: 8080
targetPort: 4444
nodePort #
Allows you to access a pod via a port on your node.
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: NodePort
selector:
app.kubernetes.io/name: MyApp
ports:
- port: 80
# By default and for convenience, the `targetPort` is set to
# the same value as the `port` field.
targetPort: 80
# Optional field
# By default and for convenience, the Kubernetes control plane
# will allocate a port from a range (default: 30000-32767)
nodePort: 30007
| command | Function |
|---|---|
kubectl apply -f manifest.yaml |
deploys a deployment based of the above manifest |
kubectl expose pod nginx --type="NodePort" |
deploys a service used by the deployment |
kubectl describe svc nginx |
Display information about the nodePort that was just created |