- Provide the YAML that runs a Pod with Nginx 1.23.3-alpine
Yaml name is nginx.yaml
1. apiVersion: v1
2. kind: Pod
3. metadata:
4. name: nginx-pod
5. spec:
6. containers:
7. - name: nginx
8. image: nginx:1.21.6-alpine
9. ports:
10. - containerPort: 80
11. name: http
12. protocol: TCP
as well as the kubectl commands needed to:
-
- Install the manifest on Kubernetes and start the Pod.
Firstly run minikube start
Then
kubectl apply -f nginx.yaml
-
- Forward port 80 locally, so that it answers calls through a browser (or curl or wget).
kubectl port-forward nginx-pod 8080:80
-
- See the logs of the running container.
kubectl logs nginx-pod
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2024/03/17 19:55:35 \[notice\] 1#1: using the "epoll" event method
2024/03/17 19:55:35 \[notice\] 1#1: nginx/1.21.6
2024/03/17 19:55:35 \[notice\] 1#1: built by gcc 10.3.1 20211027 (Alpine 10.3.1_git20211027)
2024/03/17 19:55:35 \[notice\] 1#1: OS: Linux 5.10.102.1-microsoft-standard-WSL2
2024/03/17 19:55:35 \[notice\] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2024/03/17 19:55:35 \[notice\] 1#1: start worker processes
2024/03/17 19:55:35 \[notice\] 1#1: start worker process 32
2024/03/17 19:55:35 \[notice\] 1#1: start worker process 33
2024/03/17 19:55:35 \[notice\] 1#1: start worker process 34
2024/03/17 19:55:35 \[notice\] 1#1: start worker process 35
2024/03/17 19:55:35 \[notice\] 1#1: start worker process 36
2024/03/17 19:55:35 \[notice\] 1#1: start worker process 37
2024/03/17 19:55:35 \[notice\] 1#1: start worker process 38
2024/03/17 19:55:35 \[notice\] 1#1: start worker process 39
127.0.0.1 - - \[17/Mar/2024:19:55:52 +0000\] "GET / HTTP/1.1" 200 615 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36" "-"
2024/03/17 19:55:52 \[error\] 32#32: \*1 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 127.0.0.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "localhost:8080", referrer: "<http://localhost:8080/>"
127.0.0.1 - - \[17/Mar/2024:19:55:52 +0000\] "GET /favicon.ico HTTP/1.1" 404 555 "<http://localhost:8080/>" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36" "-"
-
- Open a shell session inside the running container and change the first sentence of the default page to "Welcome to MY nginx!". Close the session.
kubectl exec -it nginx-pod – sh
vi /usr/share/nginx/html/index.html
exit
-
- From your computer terminal (outside the container), download the default page locally and upload another one in its place.
kubectl cp nginx-pod:/usr/share/nginx/html/index.html ./index.html
cp ./hy548/html/public/index.html nginx-pod:
/usr/share/nginx/html/index.html
-
- Stop the Pod and remove the manifest from Kubernetes.
kubectl delete -f nginx.yaml
2. The code that produces the course's website is available on GitHub (https://github.com/chazapis/hy548). Provide the YAML that creates a Job using Ubuntu 20.04, which when started will run a script (defined in a ConfigMap) that will download the repository (and submodules), hugo (the tool that builds the website), and build the website.
We need the extended hugo version, otherwise it will not work
Yaml name is ubuntu.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: website-build-script
data:
build-script.sh: |
#!/bin/bash
apt-get update && apt-get install -y git wget tar
wget -qO- <https://github.com/gohugoio/hugo/releases/download/v0.94.0/hugo_extended_0.94.0_Linux-64bit.tar.gz> | tar xvz
mv hugo /usr/local/bin/
git clone --recursive <https://github.com/chazapis/hy548.git>
cd ./hy548
git submodule update --init --recursive
cd ./html
hugo -D
\---
apiVersion: batch/v1
kind: Job
metadata:
name: ubuntu
spec:
template:
spec:
volumes:
- name: script-volume
configMap:
name: website-build-script
restartPolicy: Never
containers:
- name: website-builder
image: ubuntu:20.04
volumeMounts:
- name: script-volume
mountPath: /scripts
command: \["/bin/bash", "/scripts/build-script.sh"\]
Then run
kubectl apply -f ubuntu.yaml
Which command can you use to confirm that the Job completed successfully?
kubectl logs -f job/ubuntu
And we can see the logs
At the end we see that website was build
Start building sites …
hugo v0.94.0-63B23660+extended linux/amd64 BuildDate=2022-03-10T09:46:36Z VendorInfo=gohugoio
| EL | EN
\-------------------+----+-----
Pages | 3 | 3
Paginator pages | 0 | 0
Non-page files | 0 | 0
Static files | 60 | 60
Processed images | 0 | 0
Aliases | 1 | 0
Sitemaps | 0 | 0
Cleaned | 0 | 0
Total in 90 ms
3. Following the previous two exercises, provide a single YAML that will run the Pod with Nginx, the above Job with the script, and a CronJob that will refresh the content every night at 2:15 (only if changes have been made to git). The Nginx Pod should serve the web pages produced by the Jobs instead of the default page. Briefly describe how data is communicated between containers.
Yaml name is ubuntu-host.yaml
So we use the previous 2 yaml files but we add the PersistentVolumeClaim, in order to communicate the data from Job to Pod. We copy the html/public to /websites (which is mounted to PersistentVolume.) Then we mount the same volume to Pod too, in /usr/share/nginx/html. And in this way we have the data from Job inside the Pod
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
spec:
volumes:
- name: website-content
persistentVolumeClaim:
claimName: ubuntu-pvc
containers:
- name: nginx
image: nginx:1.21.6-alpine
ports:
- containerPort: 80
name: http
protocol: TCP
volumeMounts:
- name: website-content
mountPath: /usr/share/nginx/html
\---
apiVersion: v1
kind: ConfigMap
metadata:
name: website-build-script
data:
build-script.sh: |
#!/bin/bash
apt-get update && apt-get install -y git wget tar
wget -qO- <https://github.com/gohugoio/hugo/releases/download/v0.94.0/hugo_extended_0.94.0_Linux-64bit.tar.gz> | tar xvz
mv hugo /usr/local/bin/
git clone --recursive <https://github.com/chazapis/hy548.git>
cd ./hy548
git submodule update --init --recursive
cd ./html
hugo -D
cp -r ./public/\* /website
\---
apiVersion: batch/v1
kind: Job
metadata:
name: ubuntu
spec:
template:
spec:
volumes:
- name: script-volume
configMap:
name: website-build-script
- name: website-content
persistentVolumeClaim:
claimName: ubuntu-pvc
restartPolicy: OnFailure
containers:
- name: website-builder
image: ubuntu:20.04
command: \["/bin/bash", "/scripts/build-script.sh"\]
volumeMounts:
- name: script-volume
mountPath: /scripts
- name: website-content
mountPath: /website
\---
apiVersion: batch/v1
kind: CronJob
metadata:
name: ubuntu
spec:
schedule: "15 2 \* \* \*"
jobTemplate:
spec:
template:
spec:
volumes:
- name: script-volume
configMap:
name: website-build-script
- name: website-content
persistentVolumeClaim:
claimName: ubuntu-pvc
restartPolicy: OnFailure
containers:
- name: website-builder
image: ubuntu:20.04
volumeMounts:
- name: script-volume
mountPath: /scripts
- name: website-content
mountPath: /website
command: \["/bin/bash", "/scripts/build-script.sh"\]
\---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: ubuntu-pvc
spec:
storageClassName: ""
volumeName: ubuntu-pv
accessModes: \[ReadWriteOnce\]
resources:
requests:
storage: 1Gi
\---
apiVersion: v1
kind: PersistentVolume
metadata:
name: ubuntu-pv
spec:
accessModes: \[ReadWriteOnce\]
capacity:
storage: 1Gi
hostPath:
path: /website
4. Following on from the previous exercise, embed the Nginx Pods in a Deployment (keeping the Job and Cronjob in the YAML) and use an init container to start the Pods when the web page is finished building. Also add a Service to the manifest. Provide the overall YAML.
Yaml name is ubuntu-dev.yaml
To port forward, use kubectl port-forward service/nginx-service 8080:80
apiVersion: v1
kind: ConfigMap
metadata:
name: website-build-script
data:
build-script.sh: |
#!/bin/bash
apt-get update && apt-get install -y git wget tar
wget -qO- <https://github.com/gohugoio/hugo/releases/download/v0.94.0/hugo_extended_0.94.0_Linux-64bit.tar.gz> | tar xvz
mv hugo /usr/local/bin/
git clone --recursive <https://github.com/chazapis/hy548.git>
cd ./hy548
git submodule update --init --recursive
cd ./html
hugo -D
cp -r ./public/\* /website
\---
apiVersion: batch/v1
kind: Job
metadata:
name: ubuntu
spec:
template:
spec:
volumes:
- name: script-volume
configMap:
name: website-build-script
- name: website-content
persistentVolumeClaim:
claimName: ubuntu-pvc
restartPolicy: OnFailure
containers:
- name: website-builder
image: ubuntu:20.04
command: \["/bin/bash", "/scripts/build-script.sh"\]
volumeMounts:
- name: script-volume
mountPath: /scripts
- name: website-content
mountPath: /website
\---
apiVersion: batch/v1
kind: CronJob
metadata:
name: ubuntu
spec:
schedule: "15 2 \* \* \*"
jobTemplate:
spec:
template:
spec:
volumes:
- name: script-volume
configMap:
name: website-build-script
- name: website-content
persistentVolumeClaim:
claimName: ubuntu-pvc
restartPolicy: OnFailure
containers:
- name: website-builder
image: ubuntu:20.04
volumeMounts:
- name: script-volume
mountPath: /scripts
- name: website-content
mountPath: /website
command: \["/bin/bash", "/scripts/build-script.sh"\]
\---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: ubuntu-pvc
spec:
storageClassName: ""
volumeName: ubuntu-pv
accessModes: \[ReadWriteOnce\]
resources:
requests:
storage: 1Gi
\---
apiVersion: v1
kind: PersistentVolume
metadata:
name: ubuntu-pv
spec:
accessModes: \[ReadWriteOnce\]
capacity:
storage: 1Gi
hostPath:
path: /website
\---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
volumes:
- name: website-content
persistentVolumeClaim:
claimName: ubuntu-pvc
initContainers:
- name: wait-for-website
image: busybox:latest
command: \["sh", "-c", "#until \[ -f /usr/share/nginx/html/index.html \]; do sleep 1; done"\]
volumeMounts:
- name: website-content
mountPath: /usr/share/nginx/html
containers:
- name: nginx
image: nginx:1.21.6-alpine
ports:
- containerPort: 80
name: http
protocol: TCP
volumeMounts:
- name: website-content
mountPath: /usr/share/nginx/html
\---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80