GO
This commit is contained in:
28
.editorconfig
Normal file
28
.editorconfig
Normal 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
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
grype.exe
|
||||
12
Dockerfile-1
Normal file
12
Dockerfile-1
Normal 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
12
Dockerfile-2
Normal 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
15
Dockerfile-3
Normal 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
154
README.md
Normal 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
16
app.py
Normal 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
7
build.sh
Normal 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
24
helm/.helmignore
Normal 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
25
helm/Chart.yaml
Normal 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"
|
||||
|
||||
8
helm/templates/configMap.yaml
Normal file
8
helm/templates/configMap.yaml
Normal file
@@ -0,0 +1,8 @@
|
||||
{{ if (default .Values.useConfigMap false) }}
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: env-variabelen
|
||||
data:
|
||||
naam: "Topper"
|
||||
{{ end }}
|
||||
69
helm/templates/deployment.yaml
Normal file
69
helm/templates/deployment.yaml
Normal 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 }}
|
||||
15
helm/templates/service.yaml
Normal file
15
helm/templates/service.yaml
Normal 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
39
helm/values.yaml
Normal 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
BIN
rendered-chart.yaml
Normal file
Binary file not shown.
3
requirements.txt
Normal file
3
requirements.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
# Dit zijn bewust niet de nieuwste versies
|
||||
fastapi==0.68.2
|
||||
uvicorn==0.13.4
|
||||
Reference in New Issue
Block a user