This commit is contained in:
Marco Verleun
2022-05-19 12:15:11 +02:00
commit 17809c992c
16 changed files with 428 additions and 0 deletions

28
.editorconfig Normal file
View File

@@ -0,0 +1,28 @@
# EditorConfig is awesome: https://EditorConfig.org
# top-most EditorConfig file
root = true
[*]
indent_style = space
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = false
insert_final_newline = false
[*.yaml]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = false
[*.md]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
grype.exe

12
Dockerfile-1 Normal file
View File

@@ -0,0 +1,12 @@
FROM python:3.9.9-bullseye
WORKDIR /usr/src/app
COPY requirements.txt .
RUN pip install \
--no-cache-dir \
-r requirements.txt
COPY . .
CMD ["uvicorn", "app:api", "--host", "0.0.0.0", "--port", "80"]

12
Dockerfile-2 Normal file
View File

@@ -0,0 +1,12 @@
FROM python:3.9.9-bullseye
WORKDIR /usr/src/app
COPY requirements.txt .
RUN pip install \
--no-cache-dir \
-r requirements.txt
COPY . .
CMD ["uvicorn", "app:api", "--host", "0.0.0.0", "--port", "8000"]

15
Dockerfile-3 Normal file
View File

@@ -0,0 +1,15 @@
FROM python:3.9.9-bullseye
WORKDIR /usr/src/app
COPY requirements.txt .
RUN pip install \
--no-cache-dir \
-r requirements.txt
RUN apt-get update && apt-get upgrade -y \
&& rm -rf /var/lib/apt/lists/*
COPY . .
CMD ["uvicorn", "app:api", "--host", "0.0.0.0", "--port", "8000"]

154
README.md Normal file
View File

@@ -0,0 +1,154 @@
# Workshop
Bekijk de Dockerfile. Deze is redelijk eenvoudig. Het neemt een bestaand python image en voegt daar een eenvoudige applicatie aan toe.
Deze applicatie is straks te benaderen op <http://localhost/hello> en <http://localhost/healthz>
## 1 Maak het image en start deze
Hiervoor heb je twee terminals nodig.
In terminal 1 voer je de volgende commando's uit:
```bash
docker build -t workshop:1.0.0 -f Dockerfile-1 .
docker run -e HELLO_NAME=Phippy2 --name workshop --rm -p 80:80 workshop:1.0.0
```
(Phippy2 is de broer van Phippy <https://www.cncf.io/phippy/>)
Kijk in een browser of <http://localhost/hello> het doet. Kijk ook naar de logging van de pod.
## 2 Inspecteer de container
Log in een tweede terminal in in de draaiende container en bekijk verschillende aspecten:
```bash
docker exec -it workshop:1.0.0 bash
# inside container
id
apt update
ps -ef
touch /test
exit
```
En wat vind je er van?
Stop de container in terminal 1.
## 3 Hoe maken we dit veiliger?
Suggesties?
Probeer eens het volgende in terminal 1:
```bash
diff Dockerfile-1 Dockerfile-2
docker build -t workshop:1.2.0 -f Dockerfile-2 .
docker run -e HELLO_NAME=Phippy2 --user 500 --name workshop --rm -p 80:8000 workshop:1.2.0
```
(We schakelen over naar poort 8000 omdat op een *nix systeem poort 80 bijzonder is. Wie weet wat er bijzonder aan is?)
En in terminal 2:
```bash
docker exec -it workshop:1.0.0 bash
# inside container
id
apt update
ps -ef
touch /test
exit
```
Stop de container in terminal 1
## 4 Upload image in minikube
Lokale images zijn niet direct beschikbaar in minikube. Iedere keer als we een nieuwe versie maken moeten we deze uploaden.
```bash
docker image ls
minikube image load workshop:1.0.0
minikube image ls
```
## 5 Deploy de manifest file, gebaseerd op de helm chart in de directory helm
Als je Lens hebt geinstalleerd is dit een mooi moment om deze te starten.
```bash
minikube kubectl -- get nodes
minikube kubectl -- create -f rendered-chart.yaml
```
Controleer of de deployment werkt:
In een terminal start een portforwarding:
```bash
minikube kubectl port-forward svc/workshop 80:80
```
Open weer de link <http://localhost/hello>
Hoe veilig is deze eigenlijk?
## 6 Inspecteer de POD
```bash
minikube kubectl -- get pods
NAME READY STATUS RESTARTS AGE
workshop-6c7bc5c754-ngq9n 1/1 Running 0 7m28s
# Get Pod name and use it below
minikube kubectl -- exec workshop-6c7bc5c754-ngq9n -it -- bash
# inside container
id
apt update
ps -ef
touch /test
exit
```
We hebben nog steeds dezelfde issue als met Dockerfile-1
Kunnen we iets doen:
- A in de Dockerfile?
- B in de manifest file?
- C c'est la via, mon ami.
Wat dachten jullie van:
- <https://kubernetes.io/docs/tasks/configure-pod-container/security-context/>
- <https://docs.docker.com/engine/reference/builder/#user>
## 7 Wat is er nog meer mis?
In terminal 1:
```bash
grype workshop:1.2.0
```
Ai, dat is schrikken...
En nu dan?
```bash
docker build -t workshop:1.3.0 .
grype workshop:1.3.0
docker image ls
```
## 8 Zijn we er nu?
Wat kan nog meer beter?
- Resources?
- Probes?
- Replicacount?

16
app.py Normal file
View File

@@ -0,0 +1,16 @@
from fastapi import FastAPI, Response
import os
name = os.getenv("HELLO_NAME", "unknown")
api = FastAPI()
@api.get("/hello")
async def hello():
return f"Hello {name}!!!"
@api.get("/healthz")
async def healthz():
return "OK"

7
build.sh Normal file
View File

@@ -0,0 +1,7 @@
#!/bin/bash
CONTEXT="."
TAG="workshop"
DOCKERFILE="Dockerfile.local"
docker build -f $DOCKERFILE -t $TAG $CONTEXT

24
helm/.helmignore Normal file
View File

@@ -0,0 +1,24 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/

25
helm/Chart.yaml Normal file
View File

@@ -0,0 +1,25 @@
apiVersion: v2
name: cursus-application-1
description: A Helm chart for Kubernetes
# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.1.0
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "0.0.1"

View File

@@ -0,0 +1,8 @@
{{ if (default .Values.useConfigMap false) }}
apiVersion: v1
kind: ConfigMap
metadata:
name: env-variabelen
data:
naam: "Topper"
{{ end }}

View File

@@ -0,0 +1,69 @@
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: {{ .Values.app.name }}
name: {{ .Values.app.name }}
spec:
replicas: {{ .Values.app.replicaCount }}
selector:
matchLabels:
app: {{ .Values.app.name }}
revisionHistoryLimit: 1
template:
metadata:
labels:
app: {{ .Values.app.name }}
spec:
{{- with .Values.securityContext }}
securityContext:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: {{ .Values.app.name }}
image: {{ .Values.app.image }}
imagePullPolicy: Never
command: ["uvicorn", "app:api", "--host", "0.0.0.0", "--port", "{{ .Values.app.containerPort }}"]
ports:
- name: {{ .Values.app.portName }}
containerPort: {{ .Values.app.containerPort }}
protocol: TCP
livenessProbe:
httpGet:
path: /healthz
port: {{ .Values.app.portName }}
readinessProbe:
httpGet:
path: /healthz
port: {{ .Values.app.portName }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
# command: ["python", "sleep.py"]
{{ if (default .Values.useConfigMap false) }}
env:
- name: HELLO_NAME
valueFrom:
configMapKeyRef:
name: env-variabelen
key: naam
{{ end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}

View File

@@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
name: {{ .Values.app.name }}
labels:
app: {{ .Values.app.name }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: {{ .Values.app.containerPort }}
protocol: TCP
name: {{ .Values.app.portName }}
selector:
app: {{ .Values.app.name }}

39
helm/values.yaml Normal file
View File

@@ -0,0 +1,39 @@
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
app:
name: workshop
replicaCount: 1
image: docker.io/library/workshop:latest
loglevel: INFO
containerPort: 8000
portName: http
useConfigMap: false
securityContext: {}
# runAsUser: 1000
# runAsGroup: 3000
# fsGroup: 2000
resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
nodeSelector: {}
tolerations: []
affinity: {}
service:
type: ClusterIP
port: 80
portName: http

BIN
rendered-chart.yaml Normal file

Binary file not shown.

3
requirements.txt Normal file
View File

@@ -0,0 +1,3 @@
# Dit zijn bewust niet de nieuwste versies
fastapi==0.68.2
uvicorn==0.13.4