- Create the namespace
ckad-prep
. - In the namespace
ckad-prep
create a new Pod namedmypod
with the imagenginx:2.3.5
. Expose the port 80. - Identify the issue with creating the container. Write down the root cause of issue in a file named
pod-error.txt
. - Change the image of the Pod to
nginx:1.15.12
. - List the Pod and ensure that the container is running.
- Log into the container and run the
ls
command. Write down the output. Log out of the container. - Retrieve the IP address of the Pod
mypod
. - Run a temporary Pod using the image
busybox
, shell into it and run awget
command against thenginx
Pod using port 80. - Render the logs of Pod
mypod
. - Delete the Pod and the namespace.
- Create a new file named
config.txt
with the following environment variables as key/value pairs on each line.
DB_URL
equates tolocalhost:3306
DB_USERNAME
equates topostgres
- Create a new ConfigMap named
db-config
from that file. - Create a Pod named
backend
that uses the environment variables from the ConfigMap and runs the container with the imagenginx
. - Shell into the Pod and print out the created environment variables. You should find
DB_URL
andDB_USERNAME
with their appropriate values.
- Create a new Secret named
db-credentials
with the key/value pairdb-password=passwd
. - Create a Pod named
backend
that defines uses the Secret as environment variable namedDB_PASSWORD
and runs the container with the imagenginx
. - Shell into the Pod and print out the created environment variables. You should find
DB_PASSWORD
variable.
- Create a Pod named
secured
that uses the imagenginx
for a single container. Mount anemptyDir
volume to the directory/data/app
. - Files created on the volume should use the filesystem group ID 3000.
- Get a shell to the running container and create a new file named
logs.txt
in the directory/data/app
. List the contents of the directory and write them down.
Create a resource quota named apps
under the namespace rq-demo
using the following YAML definition in the file rq.yaml
.
apiVersion: v1
kind: ResourceQuota
metadata:
name: app
spec:
hard:
pods: "2"
requests.cpu: "2"
requests.memory: 500m
- Create a new Pod that exceeds the limits of the resource quota requirements. Write down the error message.
- Change the request limits to fulfill the requirements to ensure that the Pod could be created successfully. Write down the output of the command that renders the used amount of resources for the namespace.
The adapter pattern helps with providing a simplified, homogenized view of an application running within a container. For example, we could stand up another container that unifies the log output of the application container. As a result, other monitoring tools can rely on a standardized view of the log output without having to transform it into an expected format.
- Create a new Pod in a YAML file named
adapter.yaml
. The Pod declares two containers. The containerapp
uses the imagebusybox
and runs the commandwhile true; do echo "$(date) | $(du -sh ~)" >> /var/logs/diskspace.txt; sleep 5; done;
. The adapter containertransformer
uses the imagebusybox
and runs the commandsleep 20; while true; do while read LINE; do echo "$LINE" | cut -f2 -d"|" >> $(date +%Y-%m-%d-%H-%M-%S)-transformed.txt; done < /var/logs/diskspace.txt; sleep 20; done;
to strip the log output off the date for later consumption my a monitoring tool. Be aware that the logic does not handle corner cases (e.g. automatically deleting old entries) and would look different in production systems. - Before creating the Pod, define an
emptyDir
volume. Mount the volume in both containers with the path/var/logs
. - Create the Pod, log into the container
transformer
. The current directory should continuously write a new file every 20 seconds.
- Create a new Pod named
hello
with the imagebonomat/nodejs-hello-world
that exposes the port 3000. Provide the namenodejs-port
for the container port. - Add a Readiness Probe that checks the URL path / on the port referenced with the name
nodejs-port
after a 2 seconds delay. You do not have to define the period interval. - Add a Liveness Probe that verifies that the app is up and running every 8 seconds by checking the URL path / on the port referenced with the name
nodejs-port
. The probe should start with a 5 seconds delay. - Shell into container and curl
localhost:3000
. Write down the output. Exit the container. - Retrieve the logs from the container. Write down the output.
- Create a new Pod with the following YAML.
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: failing-pod
name: failing-pod
spec:
containers:
- args:
- /bin/sh
- -c
- while true; do echo $(date) >> ~/tmp/curr-date.txt; sleep
5; done;
image: busybox
name: failing-pod
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Never
status: {}
- Check the Pod's status. Do you see any issue?
- Follow the logs of the running container and identify an issue.
- Fix the issue by shelling into the container. After resolving the issue the current date should be written to a file. Render the output.
- Create three different Pods with the names
frontend
,backend
anddatabase
that use the imagenginx
. - Declare labels for those Pods as follows:
frontend
:env=prod
,team=shiny
backend
:env=prod
,team=legacy
,app=v1.2.4
database
:env=prod
,team=storage
- Declare annotations for those Pods as follows:
frontend
:contact=John Doe
,commit=2d3mg3
backend
:contact=Mary Harris
- Render the list of all Pods and their labels.
- Use label selectors on the command line to query for all production Pods that belong to the teams
shiny
andlegacy
. - Remove the label
env
from thebackend
Pod and rerun the selection. - Render the surrounding 3 lines of YAML of all Pods that have annotations.
- Create a Deployment named
deploy
with 3 replicas. The Pods should use thenginx
image and the namenginx
. The Deployment uses the labeltier=backend
. The Pods should use the labelapp=v1
. - List the Deployment and ensure that the correct number of replicas is running.
- Update the image to
nginx:latest
. - Verify that the change has been rolled out to all replicas.
- Scale the Deployment to 5 replicas.
- Have a look at the Deployment rollout history.
- Revert the Deployment to revision 1.
- Ensure that the Pods use the image
nginx
.
- Create a CronJob named
current-date
that runs every minute and executes the shell commandecho "Current date: $(date)"
. - Watch the jobs as they are being scheduled.
- Identify one of the Pods that ran the CronJob and render the logs.
- Determine the number of successful executions the CronJob will keep in its history.
- Delete the Job.
- Create a deployment named
myapp
that creates 2 replicas for Pods with the imagenginx
. Expose the container port 80. - Expose the Pods so that requests can be made against the service from inside of the cluster.
- Create a temporary Pods using the image
busybox
and run awget
command against the IP of the service. - Change the service type so that the Pods can be reached from outside of the cluster.
- Run a
wget
command against the service from outside of the cluster. - (Optional) Can you expose the Pods as a service without a deployment?
Let's assume we are working on an application stack that defines three different layers: a frontend, a backend and a database. Each of the layers runs in a Pod. You can find the definition in the YAML file app-stack.yaml
. The application needs to run in the namespace app-stack
.
kind: Pod
apiVersion: v1
metadata:
name: frontend
namespace: app-stack
labels:
app: todo
tier: frontend
spec:
containers:
- name: frontend
image: nginx
---
kind: Pod
apiVersion: v1
metadata:
name: backend
namespace: app-stack
labels:
app: todo
tier: backend
spec:
containers:
- name: backend
image: nginx
---
kind: Pod
apiVersion: v1
metadata:
name: database
namespace: app-stack
labels:
app: todo
tier: database
spec:
containers:
- name: database
image: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: example
- Create the required namespace.
- Copy the Pod definition to the file
app-stack.yaml
and create all three Pods. Notice that the namespace has already been defined in the YAML definition. - Create a network policy in the YAML file
app-stack-network-policy.yaml
. - The network policy should allow incoming traffic from the backend to the database but disallow incoming traffic from the frontend.
- Incoming traffic to the database should only be allowed on TCP port 3306 and no other port.
- Create a Persistent Volume named
pv
, access modeReadWriteMany
, storage class nameshared
, 512MB of storage capacity and the host path/data/config
. - Create a Persistent Volume Claim named
pvc
that requests the Persistent Volume in step 1. The claim should request 256MB. Ensure that the Persistent Volume Claim is properly bound after its creation. - Mount the Persistent Volume Claim from a new Pod named
app
with the path/var/app/config
. The Pod uses the imagenginx
. - Check the events of the Pod after starting it to ensure that the Persistent Volume was mounted properly.