Create and manage Pods, Deployments, and other workload resources.
This section is a refresher that provides an overview of the primary Kubernetes resources related to workloads. At the end of this section, please complete the exercises to put these concepts into practice.
A Pod is the smallest workload unit in Kubernetes. It’s an abstraction containing one or more containers in charge of running applications.
Below is the simplest version of a Pod, this one runs a container based on the stefanprodan/podinfo image.
apiVersion: v1
kind: Pod
metadata:
name: podinfo
spec:
containers:
- name: podinfo
image: stefanprodan/podinfo
We create the Pod with the usual kubectl command from this YAML definition.
kubectl apply -f pod.yaml
As a Pod does not expose the application it is running (this is the role of the Service resource, which we’ll detail later in this workshop), we can access the application using a port-forward command as follows.
kubectl port-forward podinfo 9898:9898 --address 0.0.0.0
This command opens port 9898 on the machine it is run from and forwards traffic to port 9898 in the Pod. The βaddress 0.0.0.0
flag ensures this port is available on all the network interfaces of the host machine (otherwise limited to localhost).
The simple specification we saw above is too simple and must not be run in a production environment. Below is a more complete specification, including additional properties:
apiVersion: v1
kind: Pod
metadata:
name: podinfo
labels:
app: podinfo
spec:
containers:
- image: stefanprodan/podinfo:6.1.0
name: podinfo
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 50m
memory: 64Mi
livenessProbe:
httpGet:
path: /healthz
port: 9898
initialDelaySeconds: 3
periodSeconds: 3
readinessProbe:
httpGet:
path: /readyz
port: 9898
initialDelaySeconds: 3
periodSeconds: 3
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsUser: 10000
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
capabilities:
drop:
- ALL
A Deployment runs a given number of identical Pods across the cluster. The number of replicas can easily be scaled (manually or with an HPA).
The following specification defines a Deployment in charge of 5 Pods based on the nginx:1.24 image.
apiVersion: apps/v1
kind: Deployment
metadata:
name: www
spec:
replicas: 5
selector:
matchLabels:
app: www
template:
metadata:
labels:
app: www
spec:
containers:
- name: www
image: nginx:1.24
ports:
- containerPort: 80
A DaemonSet ensures a Pod (usually an agent) is running on each cluster’s Node.
The following specification defines a DaemonSet in charge of running a fluentbit Pod on each node of the cluster.
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluent-bit
spec:
selector:
matchLabels:
k8s-app: fluent-bit-logging
template:
metadata:
labels:
k8s-app: fluent-bit-logging
spec:
containers:
- name: fluent-bit
image: fluent/fluent-bit:1.5
volumeMounts:
- name: varlog
mountPath: /var/log
- name: varlogcontainers
mountPath: /var/log/containers
volumes:
- name: varlog
hostPath:
path: /var/log
- name: varlogcontainers
hostPath:
path: /var/log/containers
A Job allows running several Pods in parallel or sequence. This must not be used to run long-running tasks, like application servers.
The following specification defines a Job running 3 Pods in parallel to train a machine learning model.
apiVersion: batch/v1
kind: Job
metadata:
name: training
spec:
completions: 3
parallelism: 3
template:
spec:
restartPolicy: OnFailure
containers:
- name: training
image: org/ml-training:1.2
A CronJob is in charge of launching Jobs according to a schedule, similar to the Linux crontab.
The following specification defines a CronJob in charge of running a backup Job every 6 hours.
apiVersion: batch/v1
kind: CronJob
metadata:
name: dump
spec:
schedule: "0 */6 * * *"
jobTemplate:
spec:
template:
spec:
restartPolicy: OnFailure
containers:
- name: dump
image: org/db-dump:2.3
A ConfigMap is not used to run Pods, unlike the resources above. Instead, we use it to configure the application running in Pods. A ConfigMap contains files or key/value pairs that we provide to the containers either:
The following specification defines a ConfigMap containing a nginx configuration file.
apiVersion: v1
kind: ConfigMap
metadata:
name: proxy-config
data:
nginx.conf: |
user nginx;
worker_processes 4;
pid /run/nginx.pid;
events {
worker_connections 768;
}
http {
server {
listen *:80;
location = /whoami {
proxy_pass http://whoami/;
}
}
}
The following specification illustrates how to use this ConfigMap in a Pod. The nginx.conf file is made available in the /etc/nginx/config.conf
in the Pod’s container.
apiVersion: v1
kind: Pod
metadata:
name: www
spec:
containers:
- name: proxy
image: nginx:1.24
volumeMounts:
- name: config
mountPath: "/etc/nginx/"
volumes:
- name: config
configMap:
name: nginx-config
A Secret is very similar to a ConfigMap except that it is used to handle sensitive information (credentials, ssh keys) as it can be encrypted. As for ConfigMap, a Secret contains files or key/value pairs that we can provide to the containers either:
When viewing a Secret’s specification, we can see base64 encoded (not encrypted) content.
The following specification defines a Secret containing an encoded MongoDB connection string.
apiVersion: v1
kind: Secret
metadata:
name: mongo-credentials
data:
mongo_url: dG9rZW49Y2IzNDU2YTU0RUI1Cg==
type: Opaque
The specification below illustrates how to use a Secret in a Pod. The Secret’s unique key is available as an environment variable in the Pod’s container.
apiVersion: v1
kind: Pod
metadata:
name: api
spec:
containers:
- name: api
image: api:1.2
env:
- name: MONGO_URL
valueFrom:
secretKeyRef:
name: mongo-credentials
key: mongo_url
Namespaces are Kubernetes resources that allow grouping resources. The image below illustrates the Namespaces created by default.
As Namespaces do not offer strong isolation, specific resources must be applied to a Namespace to limit CPU, RAM usage, and network rules allowed within and across Namespaces. Those resources are:
You can now jump to the Exercises part to learn and practice the concepts above.