├── docker-example-class ├── compose │ ├── requirements.txt │ ├── DockerFile │ ├── docker-compose.yml │ ├── app.py │ └── .gitignore ├── dockerfile │ ├── copy-and-add │ │ ├── app.py │ │ ├── copy.Dockerfile │ │ └── add.Dockerfile │ ├── redis-alpine │ │ └── Dockerfile │ ├── caching │ │ ├── withoutcache.Dockerfile │ │ ├── withcache.Dockerfile │ │ ├── app.py │ │ └── requirements.txt │ ├── multistage │ │ ├── hello.c │ │ ├── gcc.DockerFile │ │ └── tuning.gcc.DockerFile │ └── cmd-and-entrypoint │ │ ├── cmd.Dockerfile │ │ ├── entrypoint.Dockerfile │ │ └── cmd.entrypoint.Dockerfile ├── network │ ├── example │ │ ├── host-stpes │ │ └── bridge-steps │ └── workshop │ │ └── ping-ws-steps ├── nodeapp │ ├── DockerFile │ ├── app.js │ ├── package.json │ ├── .gitignore │ └── package-lock.json ├── racing-condition │ ├── normal.DockerFile │ ├── dockerize.DockerFile │ ├── docker-compose.yml │ └── server.js ├── volume │ ├── workshop │ │ └── share-volume-steps │ └── mount │ │ └── simple.html └── workshop │ ├── dockerize.DockerFile │ ├── server.js │ └── docker-compose.yml ├── ch5-kustomization ├── configuration │ ├── application.properties │ ├── kustomization.yaml │ └── script.sh ├── secret │ ├── password.txt │ ├── kustomization.yaml │ └── script.sh ├── composing │ ├── kustomization.yaml │ ├── service.yaml │ ├── deployment.yaml │ └── script.sh ├── customizing │ ├── kustomization.yaml │ ├── add_container_port.yaml │ ├── deployment.yaml │ └── script.sh ├── workshop │ ├── after │ │ ├── increase_replicas.yaml │ │ ├── pod-a.yaml │ │ ├── pod-b.yaml │ │ ├── set_memory.yaml │ │ ├── kustomization.yaml │ │ └── deployment.yaml │ └── before │ │ ├── pod-a.yaml │ │ ├── pod-b.yaml │ │ └── deployment.yaml ├── cross-cutting-fields │ ├── kustomization.yaml │ └── pod.yaml └── generator │ ├── kustomization.yaml │ └── script.sh ├── workshop ├── k8s │ ├── wordpress │ │ ├── aws │ │ │ ├── uninstall.sh │ │ │ ├── install.sh │ │ │ └── README.md │ │ ├── gke │ │ │ ├── uninstall.sh │ │ │ ├── install.sh │ │ │ └── README.md │ │ ├── helm │ │ │ ├── uninstall.sh │ │ │ ├── install.sh │ │ │ └── phpmyadmin.sh │ │ └── barefoot │ │ │ ├── kustomization.yaml │ │ │ ├── script.sh │ │ │ ├── phpmyadmin.yaml │ │ │ ├── mysql.yaml │ │ │ └── wordpress.yaml │ ├── ELK │ │ └── simple │ │ │ ├── script_k.sh │ │ │ ├── script_m.sh │ │ │ ├── script_e.sh │ │ │ ├── script_uninstall.sh │ │ │ └── values_e.yaml │ └── skaffold │ │ ├── python │ │ ├── Dockerfile │ │ ├── app.py │ │ └── requirements.txt │ │ ├── skaffold.yaml │ │ ├── k8s │ │ └── k8s-pod.yaml │ │ └── README.md └── docker │ └── ecs │ ├── ecs-params.yml │ ├── docker-compose.yml │ └── README.md ├── dashboard ├── admin-user.yaml ├── cluste-role-binding.yaml └── README.md ├── ch1-core-component ├── configMap │ ├── kustomization.yaml │ ├── directories-file │ │ ├── ui.properties │ │ └── game.properties │ ├── kustomize.sh │ └── steps ├── pod.yaml ├── configMap-example │ ├── configmap-dev.yaml │ ├── configmap-prod.yaml │ ├── pod-env.yaml │ └── pod-volume.yaml ├── service-nodeport.yaml └── deployment.yaml ├── ch2-volume ├── pv.yaml ├── workshop │ ├── pv.yaml │ ├── pod-a.yaml │ └── deployment.yaml └── deployment.yaml ├── ch3-services ├── headless │ ├── normal-service.yaml │ ├── headless-service.yaml │ └── deployment.yaml ├── ingress │ ├── ingress-service.yaml │ ├── simpleapp.yaml │ └── README.md ├── configuration │ └── endpoint │ │ ├── service.yaml │ │ └── deployment.yaml ├── clusterip │ └── example.yaml └── stateful │ └── simple-nginx.yaml ├── tools ├── busybox.yaml └── busyboxplus.yaml ├── ch4-secret ├── secret.yaml ├── pod.yaml └── pod-mount.yaml ├── ch7-gitlab └── gitlab-admin-service-account.yaml ├── ch6-logging └── daemonset │ ├── simple-daemonset.yaml │ └── README.md ├── ch8-helm └── mychart │ └── steps └── README.md /docker-example-class/compose/requirements.txt: -------------------------------------------------------------------------------- 1 | flask 2 | redis -------------------------------------------------------------------------------- /ch5-kustomization/configuration/application.properties: -------------------------------------------------------------------------------- 1 | FOO=Bar 2 | -------------------------------------------------------------------------------- /workshop/k8s/wordpress/aws/uninstall.sh: -------------------------------------------------------------------------------- 1 | helm uninstall my-wordpress -------------------------------------------------------------------------------- /workshop/k8s/wordpress/gke/uninstall.sh: -------------------------------------------------------------------------------- 1 | helm uninstall my-wordpress -------------------------------------------------------------------------------- /workshop/k8s/wordpress/helm/uninstall.sh: -------------------------------------------------------------------------------- 1 | helm uninstall my-wordpress -------------------------------------------------------------------------------- /workshop/k8s/ELK/simple/script_k.sh: -------------------------------------------------------------------------------- 1 | helm install kibana elastic/kibana -------------------------------------------------------------------------------- /ch5-kustomization/secret/password.txt: -------------------------------------------------------------------------------- 1 | username=admin 2 | password=secret 3 | -------------------------------------------------------------------------------- /workshop/k8s/ELK/simple/script_m.sh: -------------------------------------------------------------------------------- 1 | helm install metricbeat elastic/metricbeat -------------------------------------------------------------------------------- /workshop/k8s/wordpress/aws/install.sh: -------------------------------------------------------------------------------- 1 | helm install my-wordpress stable/wordpress -------------------------------------------------------------------------------- /workshop/k8s/wordpress/gke/install.sh: -------------------------------------------------------------------------------- 1 | helm install my-wordpress stable/wordpress -------------------------------------------------------------------------------- /workshop/k8s/wordpress/helm/install.sh: -------------------------------------------------------------------------------- 1 | helm install my-wordpress stable/wordpress -------------------------------------------------------------------------------- /docker-example-class/dockerfile/copy-and-add/app.py: -------------------------------------------------------------------------------- 1 | print('Hello World! Docker and K8S class') -------------------------------------------------------------------------------- /ch5-kustomization/composing/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - deployment.yaml 3 | - service.yaml 4 | -------------------------------------------------------------------------------- /workshop/k8s/ELK/simple/script_e.sh: -------------------------------------------------------------------------------- 1 | helm install elasticsearch elastic/elasticsearch -f ./values.yaml -------------------------------------------------------------------------------- /ch5-kustomization/secret/kustomization.yaml: -------------------------------------------------------------------------------- 1 | secretGenerator: 2 | - name: example-secret-1 3 | files: 4 | - password.txt 5 | -------------------------------------------------------------------------------- /docker-example-class/network/example/host-stpes: -------------------------------------------------------------------------------- 1 | # Work only linux host 2 | docker run --rm -d --network host --name my_nginx nginx -------------------------------------------------------------------------------- /ch5-kustomization/customizing/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - deployment.yaml 3 | patchesStrategicMerge: 4 | - add_container_port.yaml 5 | -------------------------------------------------------------------------------- /dashboard/admin-user.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: admin-user 5 | namespace: kubernetes-dashboard -------------------------------------------------------------------------------- /workshop/k8s/ELK/simple/script_uninstall.sh: -------------------------------------------------------------------------------- 1 | helm list 2 | helm uninstall elasticsearch 3 | helm uninstall kibana 4 | helm uninstall metricbeat -------------------------------------------------------------------------------- /ch1-core-component/configMap/kustomization.yaml: -------------------------------------------------------------------------------- 1 | configMapGenerator: 2 | - name: game-config 3 | files: 4 | - ./directories-file/game.properties 5 | -------------------------------------------------------------------------------- /workshop/docker/ecs/ecs-params.yml: -------------------------------------------------------------------------------- 1 | version: 1 2 | task_definition: 3 | services: 4 | web: 5 | cpu_shares: 100 6 | mem_limit: 524288000 -------------------------------------------------------------------------------- /ch1-core-component/configMap/directories-file/ui.properties: -------------------------------------------------------------------------------- 1 | color.good=purple 2 | color.bad=yellow 3 | allow.textmode=true 4 | how.nice.to.look=fairlyNice 5 | -------------------------------------------------------------------------------- /ch5-kustomization/workshop/after/increase_replicas.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: simpleapp-deploy 5 | spec: 6 | replicas: 3 -------------------------------------------------------------------------------- /docker-example-class/dockerfile/redis-alpine/Dockerfile: -------------------------------------------------------------------------------- 1 | # docker build -t demo:redis-alpine -f ./Dockerfile . 2 | FROM alpine 3 | RUN apk add --update redis 4 | CMD ["redis-server"] -------------------------------------------------------------------------------- /docker-example-class/dockerfile/caching/withoutcache.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.7-slim-buster 2 | 3 | COPY . . 4 | 5 | RUN pip install -r requirements.txt 6 | 7 | ENTRYPOINT ["python", "app.py"] -------------------------------------------------------------------------------- /docker-example-class/dockerfile/multistage/hello.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main() { 3 | // printf() displays the string inside quotation 4 | printf("Hello, World!"); 5 | return 0; 6 | } -------------------------------------------------------------------------------- /docker-example-class/nodeapp/DockerFile: -------------------------------------------------------------------------------- 1 | FROM node:8.7.0 2 | 3 | WORKDIR /app 4 | 5 | RUN npm install express 6 | 7 | COPY app.js . 8 | 9 | EXPOSE 3000 10 | 11 | CMD [ "node", "app.js" ] -------------------------------------------------------------------------------- /ch2-volume/pv.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: myclaim 5 | spec: 6 | accessModes: 7 | - ReadWriteOnce 8 | resources: 9 | requests: 10 | storage: 1Gi -------------------------------------------------------------------------------- /docker-example-class/racing-condition/normal.DockerFile: -------------------------------------------------------------------------------- 1 | FROM node:8.7.0 2 | 3 | WORKDIR /app 4 | 5 | RUN npm install mysql express 6 | 7 | COPY server.js . 8 | 9 | EXPOSE 3000 10 | 11 | CMD node server.js -------------------------------------------------------------------------------- /workshop/k8s/wordpress/helm/phpmyadmin.sh: -------------------------------------------------------------------------------- 1 | # printenv | grep PASSWORD 2 | # to get WORDPRESS_DATABASE_PASSWORD for connect database 3 | helm install my-phpmyadmin stable/phpmyadmin --set db.host=my-wordpress-mariadb -------------------------------------------------------------------------------- /ch2-volume/workshop/pv.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: myclaim 5 | spec: 6 | accessModes: 7 | - ReadWriteOnce 8 | resources: 9 | requests: 10 | storage: 1Gi -------------------------------------------------------------------------------- /docker-example-class/dockerfile/caching/withcache.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.7-slim-buster 2 | 3 | COPY requirements.txt . 4 | RUN pip install -r requirements.txt 5 | 6 | COPY app.py . 7 | 8 | ENTRYPOINT ["python", "app.py"] -------------------------------------------------------------------------------- /workshop/k8s/skaffold/python/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.7-slim-buster 2 | WORKDIR /usr/src/app 3 | COPY requirements.txt ./ 4 | RUN pip install --no-cache-dir -r requirements.txt 5 | COPY . . 6 | EXPOSE 5000 7 | CMD [ "python", "./app.py" ] -------------------------------------------------------------------------------- /ch1-core-component/configMap/directories-file/game.properties: -------------------------------------------------------------------------------- 1 | enemies=aliens 2 | lives=3 3 | enemies.cheat=true 4 | enemies.cheat.level=noGoodRotten 5 | secret.code.passphrase=UUDDLRLRBABAS 6 | secret.code.allowed=true 7 | secret.code.lives=30 -------------------------------------------------------------------------------- /ch5-kustomization/workshop/after/pod-a.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: simple-nginx-app 5 | spec: 6 | containers: 7 | - name: nginx-app 8 | image: nginx 9 | ports: 10 | - containerPort: 80 -------------------------------------------------------------------------------- /workshop/k8s/skaffold/python/app.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | app = Flask(__name__) 3 | 4 | @app.route('/') 5 | def hello_world(): 6 | return 'Hello, Test!' 7 | 8 | if __name__ == '__main__': 9 | app.run(debug=True, host='0.0.0.0') -------------------------------------------------------------------------------- /ch1-core-component/configMap/kustomize.sh: -------------------------------------------------------------------------------- 1 | # Create a kustomization.yaml file with ConfigMapGenerator 2 | cat <./kustomization.yaml 3 | configMapGenerator: 4 | - name: game-config 5 | files: 6 | - ./directories-file/game.properties 7 | EOF -------------------------------------------------------------------------------- /ch5-kustomization/cross-cutting-fields/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # if you use alias please us `kk .` 2 | # if not use kubectl kustomize . 3 | # to apply use kubectl apply -k . 4 | commonLabels: 5 | apptype: REST 6 | resources: 7 | - pod.yaml 8 | -------------------------------------------------------------------------------- /docker-example-class/dockerfile/copy-and-add/copy.Dockerfile: -------------------------------------------------------------------------------- 1 | # docker build -t demo:copy -f copy.Dockerfile . 2 | # docker run --rm demo:copy 3 | 4 | FROM python:3.7-slim-buster 5 | WORKDIR /usr/src/app 6 | COPY . ./ 7 | CMD [ "python", "./app.py" ] -------------------------------------------------------------------------------- /docker-example-class/dockerfile/caching/app.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | app = Flask(__name__) 3 | 4 | @app.route('/') 5 | def hello_world(): 6 | return 'Hello, World!' 7 | 8 | if __name__ == '__main__': 9 | app.run(debug=True, host='0.0.0.0') -------------------------------------------------------------------------------- /ch5-kustomization/composing/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: my-nginx 5 | labels: 6 | run: my-nginx 7 | spec: 8 | ports: 9 | - port: 80 10 | protocol: TCP 11 | selector: 12 | run: my-nginx 13 | -------------------------------------------------------------------------------- /ch5-kustomization/configuration/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # if you use alias please us `kk .` 2 | # if not use kubectl kustomize . 3 | # to apply use kubectl apply -k . 4 | configMapGenerator: 5 | - name: example-configmap-1 6 | files: 7 | - application.properties 8 | -------------------------------------------------------------------------------- /ch5-kustomization/workshop/after/pod-b.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: simpleapp 5 | spec: 6 | containers: 7 | - name: simpleapp 8 | image: howtoautomateinth/docker-simpleapp:v1.1 9 | ports: 10 | - containerPort: 5000 -------------------------------------------------------------------------------- /docker-example-class/nodeapp/app.js: -------------------------------------------------------------------------------- 1 | const express = require('express') 2 | const app = express() 3 | const port = 3000 4 | 5 | app.get('/', (req, res) => res.send('Hello World!')) 6 | 7 | app.listen(port, () => console.log(`Example app listening at http://localhost:${port}`)) -------------------------------------------------------------------------------- /ch5-kustomization/generator/kustomization.yaml: -------------------------------------------------------------------------------- 1 | configMapGenerator: 2 | - name: example-configmap-3 3 | literals: 4 | - FOO=Bar 5 | generatorOptions: 6 | disableNameSuffixHash: true 7 | labels: 8 | type: generated 9 | annotations: 10 | note: generated 11 | -------------------------------------------------------------------------------- /workshop/k8s/wordpress/barefoot/kustomization.yaml: -------------------------------------------------------------------------------- 1 | secretGenerator: 2 | - name: mysql-pass 3 | literals: 4 | - password=YOUR_PASSWORD 5 | resources: 6 | - mysql.yaml 7 | - wordpress.yaml 8 | - phpmyadmin.yaml 9 | generatorOptions: 10 | disableNameSuffixHash: true 11 | -------------------------------------------------------------------------------- /ch3-services/headless/normal-service.yaml: -------------------------------------------------------------------------------- 1 | # k exec -it pod/busyboxplus nslookup normal-service 2 | 3 | apiVersion: v1 4 | kind: Service 5 | metadata: 6 | name: normal-service 7 | spec: 8 | selector: 9 | app: simpleapp 10 | ports: 11 | - port: 80 12 | targetPort: 5000 -------------------------------------------------------------------------------- /ch5-kustomization/configuration/script.sh: -------------------------------------------------------------------------------- 1 | # Create a application.properties file 2 | cat <application.properties 3 | FOO=Bar 4 | EOF 5 | 6 | cat <./kustomization.yaml 7 | configMapGenerator: 8 | - name: example-configmap-1 9 | files: 10 | - application.properties 11 | EOF -------------------------------------------------------------------------------- /ch5-kustomization/workshop/after/set_memory.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: simpleapp-deploy 5 | spec: 6 | template: 7 | spec: 8 | containers: 9 | - name: simpleapp 10 | resources: 11 | limits: 12 | memory: 512Mi -------------------------------------------------------------------------------- /ch5-kustomization/workshop/before/pod-a.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: simple-nginx-app 5 | labels: 6 | app: simpleapp 7 | env: development 8 | spec: 9 | containers: 10 | - name: nginx-app 11 | image: nginx 12 | ports: 13 | - containerPort: 80 -------------------------------------------------------------------------------- /ch5-kustomization/customizing/add_container_port.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: my-nginx 5 | spec: 6 | template: 7 | spec: 8 | containers: 9 | - name: my-nginx 10 | resources: 11 | ports: 12 | - containerPort: 80 13 | -------------------------------------------------------------------------------- /ch5-kustomization/generator/script.sh: -------------------------------------------------------------------------------- 1 | cat <./kustomization.yaml 2 | configMapGenerator: 3 | - name: example-configmap-3 4 | literals: 5 | - FOO=Bar 6 | generatorOptions: 7 | disableNameSuffixHash: true 8 | labels: 9 | type: generated 10 | annotations: 11 | note: generated 12 | EOF -------------------------------------------------------------------------------- /ch5-kustomization/workshop/after/kustomization.yaml: -------------------------------------------------------------------------------- 1 | commonLabels: 2 | app: simpleapp 3 | env: development 4 | namePrefix: demo- 5 | 6 | resources: 7 | - pod-a.yaml 8 | - pod-b.yaml 9 | - deployment.yaml 10 | 11 | patchesStrategicMerge: 12 | - increase_replicas.yaml 13 | - set_memory.yaml -------------------------------------------------------------------------------- /docker-example-class/compose/DockerFile: -------------------------------------------------------------------------------- 1 | FROM python:3.7-alpine 2 | WORKDIR /code 3 | ENV FLASK_APP app.py 4 | ENV FLASK_RUN_HOST 0.0.0.0 5 | RUN apk add --no-cache gcc musl-dev linux-headers 6 | COPY requirements.txt requirements.txt 7 | RUN pip install -r requirements.txt 8 | COPY . . 9 | CMD ["flask", "run"] -------------------------------------------------------------------------------- /ch1-core-component/pod.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: simpleapp 5 | labels: 6 | app: simpleapp 7 | env: development 8 | spec: 9 | containers: 10 | - name: simpleapp 11 | image: howtoautomateinth/docker-simpleapp:v1.1 12 | ports: 13 | - containerPort: 5000 -------------------------------------------------------------------------------- /ch3-services/headless/headless-service.yaml: -------------------------------------------------------------------------------- 1 | # k exec -it pod/busyboxplus nslookup headless-service 2 | 3 | apiVersion: v1 4 | kind: Service 5 | metadata: 6 | name: headless-service 7 | spec: 8 | clusterIP: None 9 | selector: 10 | app: simpleapp 11 | ports: 12 | - port: 80 13 | targetPort: 5000 -------------------------------------------------------------------------------- /docker-example-class/dockerfile/multistage/gcc.DockerFile: -------------------------------------------------------------------------------- 1 | # docker build --tag normal --file gcc.DockerFile . 2 | 3 | FROM alpine:3.7 4 | RUN apk update && apk add --update alpine-sdk 5 | RUN mkdir /app 6 | WORKDIR /app 7 | COPY . /app 8 | RUN mkdir bin 9 | RUN gcc -Wall hello.c -o bin/hello 10 | CMD /app/bin/hello -------------------------------------------------------------------------------- /tools/busybox.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: busybox 5 | labels: 6 | app: busybox 7 | spec: 8 | containers: 9 | - image: busybox:1.28 10 | command: 11 | - sleep 12 | - "3600" 13 | imagePullPolicy: IfNotPresent 14 | name: busybox 15 | restartPolicy: Always -------------------------------------------------------------------------------- /ch5-kustomization/cross-cutting-fields/pod.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: simpleapp 5 | labels: 6 | app: simpleapp 7 | env: development 8 | spec: 9 | containers: 10 | - name: simpleapp 11 | image: howtoautomateinth/docker-simpleapp:v1.1 12 | ports: 13 | - containerPort: 5000 -------------------------------------------------------------------------------- /ch5-kustomization/workshop/before/pod-b.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: simpleapp 5 | labels: 6 | app: simpleapp 7 | env: development 8 | spec: 9 | containers: 10 | - name: simpleapp 11 | image: howtoautomateinth/docker-simpleapp:v1.1 12 | ports: 13 | - containerPort: 5000 -------------------------------------------------------------------------------- /ch1-core-component/configMap-example/configmap-dev.yaml: -------------------------------------------------------------------------------- 1 | kind: ConfigMap 2 | apiVersion: v1 3 | metadata: 4 | name: example-configmap 5 | labels: 6 | env: development-configmap 7 | data: 8 | database: mongodb 9 | database_uri: mongodb://localhost:27017 10 | keys: | 11 | image.public.key=771 12 | rsa.public.key=42 -------------------------------------------------------------------------------- /ch1-core-component/configMap-example/configmap-prod.yaml: -------------------------------------------------------------------------------- 1 | kind: ConfigMap 2 | apiVersion: v1 3 | metadata: 4 | name: example-configmap 5 | labels: 6 | env: production-configmap 7 | data: 8 | database: mongodb 9 | database_uri: http://someserver:27017 10 | keys: | 11 | image.public.key=5556 12 | rsa.public.key=6555 -------------------------------------------------------------------------------- /dashboard/cluste-role-binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: admin-user 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: ClusterRole 8 | name: cluster-admin 9 | subjects: 10 | - kind: ServiceAccount 11 | name: admin-user 12 | namespace: kubernetes-dashboard -------------------------------------------------------------------------------- /tools/busyboxplus.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: busyboxplus 5 | labels: 6 | app: busyboxplus 7 | spec: 8 | containers: 9 | - image: radial/busyboxplus:latest 10 | command: 11 | - sleep 12 | - "3600" 13 | imagePullPolicy: IfNotPresent 14 | name: busyboxplus 15 | restartPolicy: Always 16 | -------------------------------------------------------------------------------- /workshop/docker/ecs/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | web: 4 | image: howtoautomateinth/docker-simpleapp:v1.1 5 | ports: 6 | - "80:5000" 7 | logging: 8 | driver: awslogs 9 | options: 10 | awslogs-group: ec2-tutorial 11 | awslogs-region: us-west-2 12 | awslogs-stream-prefix: web -------------------------------------------------------------------------------- /workshop/k8s/skaffold/skaffold.yaml: -------------------------------------------------------------------------------- 1 | # skaffold dev 2 | # kg all 3 | # minikube ip 4 | 5 | apiVersion: skaffold/v2beta1 6 | kind: Config 7 | build: 8 | artifacts: 9 | - image: simpleapp-skaffold 10 | context: python 11 | sync: 12 | infer: 13 | - '**/*.py' 14 | deploy: 15 | kubectl: 16 | manifests: 17 | - ./k8s/k8s-* -------------------------------------------------------------------------------- /docker-example-class/nodeapp/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "simplenodeapp", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "app.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "devDependencies": { 12 | "express": "^4.17.1" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /docker-example-class/dockerfile/copy-and-add/add.Dockerfile: -------------------------------------------------------------------------------- 1 | # docker build -t demo:add . 2 | # docker run --rm --name my-running-app -p 8080:80 demo:add 3 | # docker exec -it my-running-app bash 4 | # cd /usr/local/apache2/htdocs/ 5 | 6 | FROM httpd:2.4 7 | ADD https://www.dropbox.com/s/q1ew8rb44ud2wum/7-Days-Workout-by-Workout-Motivation.pdf?dl=0 /usr/local/apache2/htdocs/ 8 | -------------------------------------------------------------------------------- /ch4-secret/secret.yaml: -------------------------------------------------------------------------------- 1 | # kg secret 2 | # echo -n 'admin' | base64 3 | # kg secret cats-and-dogs -o yaml 4 | # echo 'bXlzZWNyZXQ=' | base64 --decode 5 | 6 | apiVersion: v1 7 | kind: Secret 8 | metadata: 9 | name: cats-and-dogs 10 | type: Opaque 11 | data: 12 | # encode with base64 13 | user: anNtaXRo 14 | password: bXlzdXBlcnNlY3VyZXBhc3N3b3Jk 15 | example: bXlzZWNyZXQ= -------------------------------------------------------------------------------- /docker-example-class/network/example/bridge-steps: -------------------------------------------------------------------------------- 1 | docker network create my-net 2 | 3 | # default 4 | docker create --name my-nginx \ 5 | --publish 8080:80 \ 6 | nginx:latest 7 | 8 | # User-defined 9 | docker create --name my-nginx \ 10 | --network my-net \ 11 | --publish 8080:80 \ 12 | nginx:latest 13 | 14 | docker start my-nginx 15 | docker inspect my-nginx 16 | -------------------------------------------------------------------------------- /ch5-kustomization/customizing/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: my-nginx 5 | spec: 6 | selector: 7 | matchLabels: 8 | run: my-nginx 9 | replicas: 2 10 | template: 11 | metadata: 12 | labels: 13 | run: my-nginx 14 | spec: 15 | containers: 16 | - name: my-nginx 17 | image: nginx 18 | -------------------------------------------------------------------------------- /docker-example-class/volume/workshop/share-volume-steps: -------------------------------------------------------------------------------- 1 | docker volume create DataVolume 2 | docker inspect some-nginx --format="{{json .Mounts}}" | jq 3 | docker run --name some-nginx-1 -v DataVolume:/usr/share/nginx/html -d -p 8080:80 nginx 4 | docker run --name some-nginx-2 -v DataVolume:/usr/share/nginx/html -d -p 8081:80 nginx 5 | docker run --name some-nginx-3 -v DataVolume:/usr/share/nginx/html -d -p 8082:80 nginx -------------------------------------------------------------------------------- /docker-example-class/dockerfile/multistage/tuning.gcc.DockerFile: -------------------------------------------------------------------------------- 1 | # docker build --tag tunning --file tuning.gcc.DockerFile . 2 | 3 | FROM alpine:3.7 AS build 4 | RUN apk update && \ 5 | apk add --update alpine-sdk 6 | RUN mkdir /app 7 | WORKDIR /app 8 | COPY . /app 9 | RUN mkdir bin 10 | RUN gcc hello.c -o bin/hello 11 | 12 | FROM alpine:3.7 13 | COPY --from=build /app/bin/hello /app/hello 14 | CMD /app/hello -------------------------------------------------------------------------------- /ch1-core-component/configMap-example/pod-env.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: simpleapp 5 | labels: 6 | app: simpleapp 7 | env: development 8 | spec: 9 | containers: 10 | - name: simpleapp 11 | image: howtoautomateinth/docker-simpleapp:v1.1 12 | ports: 13 | - containerPort: 5000 14 | envFrom: 15 | - configMapRef: 16 | name: example-configmap -------------------------------------------------------------------------------- /ch5-kustomization/composing/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: my-nginx 5 | spec: 6 | selector: 7 | matchLabels: 8 | run: my-nginx 9 | replicas: 2 10 | template: 11 | metadata: 12 | labels: 13 | run: my-nginx 14 | spec: 15 | containers: 16 | - name: my-nginx 17 | image: nginx 18 | ports: 19 | - containerPort: 80 20 | -------------------------------------------------------------------------------- /workshop/k8s/wordpress/barefoot/script.sh: -------------------------------------------------------------------------------- 1 | cat < ./kustomization.yaml 2 | secretGenerator: 3 | - name: mysql-pass 4 | literals: 5 | - password=YOUR_PASSWORD 6 | EOF 7 | 8 | cat <> ./kustomization.yaml 9 | resources: 10 | - mysql.yaml 11 | - wordpress.yaml 12 | - phpmyadmin.yaml 13 | EOF 14 | 15 | cat <> ./kustomization.yaml 16 | generatorOptions: 17 | disableNameSuffixHash: true 18 | EOF 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /ch3-services/ingress/ingress-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Ingress 3 | metadata: 4 | name: ingress-service 5 | annotations: 6 | kubernetes.io/ingress.class: nginx 7 | nginx.ingress.kubernetes.io/rewrite-target: / 8 | spec: 9 | rules: 10 | - http: 11 | paths: 12 | - path: / 13 | backend: 14 | serviceName: simpleapp-cluster-ip-service 15 | servicePort: 5000 16 | -------------------------------------------------------------------------------- /docker-example-class/dockerfile/cmd-and-entrypoint/cmd.Dockerfile: -------------------------------------------------------------------------------- 1 | # docker build -t demo:cmd -f cmd.Dockerfile . 2 | # docker run --rm demo:cmd 3 | # docker run --rm demo:cmd screenfetch -E 4 | 5 | FROM debian:jessie-slim 6 | 7 | RUN apt-get update && \ 8 | apt-get install -y --no-install-recommends \ 9 | cowsay \ 10 | screenfetch && \ 11 | rm -rf /var/lib/apt/lists/* 12 | 13 | ENV PATH "$PATH:/usr/games" 14 | CMD ["cowsay", "Yo, CMD !!"] 15 | 16 | -------------------------------------------------------------------------------- /ch2-volume/workshop/pod-a.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: simple-nginx-app 5 | labels: 6 | app: simpleapp 7 | env: development 8 | spec: 9 | containers: 10 | - name: nginx-app 11 | image: nginx 12 | ports: 13 | - containerPort: 80 14 | volumeMounts: 15 | - name: mypv 16 | mountPath: "/tmp/persistent" 17 | volumes: 18 | - name: mypv 19 | persistentVolumeClaim: 20 | claimName: myclaim -------------------------------------------------------------------------------- /ch1-core-component/configMap/steps: -------------------------------------------------------------------------------- 1 | # from directories 2 | kubectl create configmap game-config --from-file=./directories-file/configmap 3 | 4 | # from file 5 | kubectl create configmap game-config --from-file=/directories-file/configmap/game.properties 6 | 7 | # from literal 8 | kubectl create configmap special-config --from-literal=special.how=very --from-literal=special.type=charm 9 | 10 | kubectl describe configmaps game-config 11 | kubectl get configmaps game-config -o yaml -------------------------------------------------------------------------------- /docker-example-class/dockerfile/cmd-and-entrypoint/entrypoint.Dockerfile: -------------------------------------------------------------------------------- 1 | # docker build -t demo:entry -f entrypoint.Dockerfile . 2 | # docker run --rm demo:entry 3 | # docker run demo:entry screenfetch -E 4 | 5 | FROM debian:jessie-slim 6 | 7 | RUN apt-get update && \ 8 | apt-get install -y --no-install-recommends \ 9 | cowsay \ 10 | screenfetch && \ 11 | rm -rf /var/lib/apt/lists/* 12 | 13 | ENV PATH "$PATH:/usr/games" 14 | ENTRYPOINT ["cowsay", "Yo, Entrypoint!!"] 15 | -------------------------------------------------------------------------------- /ch5-kustomization/secret/script.sh: -------------------------------------------------------------------------------- 1 | # Create a password.txt file 2 | cat <./password.txt 3 | username=admin 4 | password=secret 5 | EOF 6 | 7 | # file base 8 | cat <./kustomization.yaml 9 | secretGenerator: 10 | - name: example-secret-1 11 | files: 12 | - password.txt 13 | EOF 14 | 15 | # list base 16 | # cat <./kustomization.yaml 17 | # secretGenerator: 18 | # - name: example-secret-2 19 | # literals: 20 | # - username=admin 21 | # - password=secret 22 | # EOF -------------------------------------------------------------------------------- /ch7-gitlab/gitlab-admin-service-account.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: gitlab-admin 5 | namespace: kube-system 6 | --- 7 | apiVersion: rbac.authorization.k8s.io/v1beta1 8 | kind: ClusterRoleBinding 9 | metadata: 10 | name: gitlab-admin 11 | roleRef: 12 | apiGroup: rbac.authorization.k8s.io 13 | kind: ClusterRole 14 | name: cluster-admin 15 | subjects: 16 | - kind: ServiceAccount 17 | name: gitlab-admin 18 | namespace: kube-system 19 | -------------------------------------------------------------------------------- /ch1-core-component/service-nodeport.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: simpleapp-service 5 | labels: 6 | run: simpleapp 7 | spec: 8 | type: NodePort 9 | ports: 10 | - 11 | # Inside the cluster, port of this service 12 | port: 8080 13 | # Service port that are going to expose 14 | targetPort: 5000 15 | # Port node that can accessible (30000-32767) 16 | nodePort: 31366 17 | name: http 18 | selector: 19 | app: simpleapp -------------------------------------------------------------------------------- /ch4-secret/pod.yaml: -------------------------------------------------------------------------------- 1 | # kg secret 2 | 3 | apiVersion: v1 4 | kind: Pod 5 | metadata: 6 | name: simpleapp-ch4-ref 7 | labels: 8 | app: simpleapp-ch4 9 | env: development 10 | 11 | spec: 12 | containers: 13 | - name: simpleapp 14 | image: howtoautomateinth/docker-simpleapp:v1.1 15 | ports: 16 | - containerPort: 5000 17 | env: 18 | - name: databasePassword 19 | valueFrom: 20 | secretKeyRef: 21 | name: cats-and-dogs 22 | key: example -------------------------------------------------------------------------------- /ch3-services/configuration/endpoint/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: my-service 5 | spec: 6 | ports: 7 | - protocol: TCP 8 | port: 80 9 | targetPort: 5000 10 | ## no selector so Endpoint object is not created automatically 11 | ## then we create our Endpoint object to redirect 12 | --- 13 | apiVersion: v1 14 | kind: Endpoints 15 | metadata: 16 | name: my-service 17 | subsets: 18 | - addresses: 19 | - ip: 216.58.200.14 20 | ports: 21 | - port: 80 -------------------------------------------------------------------------------- /docker-example-class/compose/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.7' 2 | services: 3 | web: 4 | build: 5 | context: . 6 | dockerfile: DockerFile 7 | ports: 8 | - "5000:5000" 9 | volumes: 10 | - .:/code 11 | environment: 12 | FLASK_ENV: development 13 | networks: 14 | - front 15 | - back 16 | redis: 17 | image: "redis:alpine" 18 | networks: 19 | - back 20 | volumes: 21 | composedata: 22 | networks: 23 | front: 24 | back: 25 | -------------------------------------------------------------------------------- /ch4-secret/pod-mount.yaml: -------------------------------------------------------------------------------- 1 | # kg secret 2 | 3 | apiVersion: v1 4 | kind: Pod 5 | metadata: 6 | name: simpleapp-ch4-mount 7 | labels: 8 | app: simpleapp-ch4 9 | env: development 10 | spec: 11 | volumes: 12 | - name: vol-secret 13 | secret: 14 | secretName: cats-and-dogs 15 | containers: 16 | - name: simpleapp 17 | image: howtoautomateinth/docker-simpleapp:v1.1 18 | ports: 19 | - containerPort: 5000 20 | volumeMounts: 21 | - name: vol-secret 22 | mountPath: /etc/app/secrets -------------------------------------------------------------------------------- /workshop/k8s/skaffold/python/requirements.txt: -------------------------------------------------------------------------------- 1 | astroid==2.3.3 2 | attrs==19.3.0 3 | Click==7.0 4 | Flask==1.1.1 5 | importlib-metadata==1.3.0 6 | isort==4.3.21 7 | itsdangerous==1.1.0 8 | Jinja2==2.10.3 9 | lazy-object-proxy==1.4.3 10 | MarkupSafe==1.1.1 11 | mccabe==0.6.1 12 | more-itertools==8.0.2 13 | packaging==19.2 14 | pluggy==0.13.1 15 | py==1.8.1 16 | pylint==2.4.4 17 | pyparsing==2.4.6 18 | pytest==5.3.2 19 | six==1.13.0 20 | typed-ast==1.4.0 21 | wcwidth==0.1.8 22 | Werkzeug==0.16.0 23 | wrapt==1.11.2 24 | zipp==0.6.0 -------------------------------------------------------------------------------- /docker-example-class/dockerfile/caching/requirements.txt: -------------------------------------------------------------------------------- 1 | astroid==2.3.3 2 | attrs==19.3.0 3 | Click==7.0 4 | Flask==1.1.1 5 | importlib-metadata==1.3.0 6 | isort==4.3.21 7 | itsdangerous==1.1.0 8 | Jinja2==2.10.3 9 | lazy-object-proxy==1.4.3 10 | MarkupSafe==1.1.1 11 | mccabe==0.6.1 12 | more-itertools==8.0.2 13 | packaging==19.2 14 | pluggy==0.13.1 15 | py==1.8.1 16 | pylint==2.4.4 17 | pyparsing==2.4.6 18 | pytest==5.3.2 19 | six==1.13.0 20 | typed-ast==1.4.0 21 | wcwidth==0.1.8 22 | Werkzeug==0.16.0 23 | wrapt==1.11.2 24 | zipp==0.6.0 -------------------------------------------------------------------------------- /docker-example-class/dockerfile/cmd-and-entrypoint/cmd.entrypoint.Dockerfile: -------------------------------------------------------------------------------- 1 | # docker build -t demo:cmd-entry -f cmd.entrypoint.Dockerfile . 2 | # docker run --rm demo:cmd-entry 3 | # docker run --rm demo:cmd-entry Overriding arg passed in cmd 4 | 5 | FROM debian:jessie-slim 6 | 7 | RUN apt-get update && \ 8 | apt-get install -y --no-install-recommends \ 9 | cowsay \ 10 | screenfetch && \ 11 | rm -rf /var/lib/apt/lists/* 12 | 13 | ENV PATH "$PATH:/usr/games" 14 | 15 | CMD ["Yo, CMD!!"] 16 | ENTRYPOINT ["cowsay", "Yo, Entrypoint!!"] -------------------------------------------------------------------------------- /ch1-core-component/configMap-example/pod-volume.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: simpleapp 5 | labels: 6 | app: simpleapp 7 | env: development 8 | spec: 9 | volumes: 10 | - name: example-configmap-volume 11 | configMap: 12 | name: example-configmap 13 | containers: 14 | - name: simpleapp 15 | image: howtoautomateinth/docker-simpleapp:v1.1 16 | ports: 17 | - containerPort: 5000 18 | volumeMounts: 19 | - name: example-configmap-volume 20 | mountPath: /etc/config -------------------------------------------------------------------------------- /ch1-core-component/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: simpleapp-deploy 5 | spec: 6 | replicas: 2 7 | selector: 8 | matchLabels: 9 | app: simpleapp 10 | template: 11 | metadata: 12 | labels: 13 | app: simpleapp 14 | spec: 15 | containers: 16 | - name: simpleapp 17 | image: howtoautomateinth/docker-simpleapp:v1.1 18 | ports: 19 | - containerPort: 5000 20 | env: 21 | - name: SIMPLE_APP_VERSION 22 | value: "1.1" -------------------------------------------------------------------------------- /ch3-services/headless/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: simpleapp-deploy 5 | spec: 6 | replicas: 5 7 | selector: 8 | matchLabels: 9 | app: simpleapp 10 | template: 11 | metadata: 12 | labels: 13 | app: simpleapp 14 | spec: 15 | containers: 16 | - name: simpleapp 17 | image: howtoautomateinth/docker-simpleapp:v1.1 18 | ports: 19 | - containerPort: 5000 20 | env: 21 | - name: SIMPLE_APP_VERSION 22 | value: "1.1" -------------------------------------------------------------------------------- /ch5-kustomization/workshop/after/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: simpleapp-deploy 5 | spec: 6 | replicas: 2 7 | selector: 8 | matchLabels: 9 | app: simpleapp 10 | template: 11 | metadata: 12 | labels: 13 | app: simpleapp 14 | spec: 15 | containers: 16 | - name: simpleapp 17 | image: howtoautomateinth/docker-simpleapp:v1.1 18 | ports: 19 | - containerPort: 5000 20 | env: 21 | - name: SIMPLE_APP_VERSION 22 | value: "1.1" -------------------------------------------------------------------------------- /ch5-kustomization/workshop/before/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: simpleapp-deploy 5 | spec: 6 | replicas: 2 7 | selector: 8 | matchLabels: 9 | app: simpleapp 10 | template: 11 | metadata: 12 | labels: 13 | app: simpleapp 14 | spec: 15 | containers: 16 | - name: simpleapp 17 | image: howtoautomateinth/docker-simpleapp:v1.1 18 | ports: 19 | - containerPort: 5000 20 | env: 21 | - name: SIMPLE_APP_VERSION 22 | value: "1.1" -------------------------------------------------------------------------------- /ch3-services/configuration/endpoint/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: simpleapp-deploy 5 | spec: 6 | replicas: 2 7 | selector: 8 | matchLabels: 9 | app: simpleapp 10 | template: 11 | metadata: 12 | labels: 13 | app: simpleapp 14 | spec: 15 | containers: 16 | - name: simpleapp 17 | image: howtoautomateinth/docker-simpleapp:v1.1 18 | ports: 19 | - containerPort: 5000 20 | env: 21 | - name: SIMPLE_APP_VERSION 22 | value: "1.1" -------------------------------------------------------------------------------- /docker-example-class/network/workshop/ping-ws-steps: -------------------------------------------------------------------------------- 1 | docker network create network1 2 | docker run -itd --name container1 --network network1 busybox 3 | docker run -itd --name container2 --network network1 busybox 4 | docker network inspect network1 --format="{{json .Containers}}" | jq 5 | docker exec -it container1 ping container2 6 | 7 | docker network create network2 8 | docker run -itd --name container3 --network network2 busybox 9 | docker network inspect network2 --format="{{json .Containers}}" | jq 10 | docker exec -it container3 ping container2 11 | 12 | 13 | -------------------------------------------------------------------------------- /docker-example-class/volume/mount/simple.html: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | The HTML5 12 | 13 | 14 | 15 | 16 |

Hello World!!!

17 | Docker & K8S class 18 | 19 | -------------------------------------------------------------------------------- /ch6-logging/daemonset/simple-daemonset.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: DaemonSet 3 | metadata: 4 | name: simple-daemonset 5 | labels: 6 | app: simple-daemonset 7 | spec: 8 | selector: 9 | matchLabels: 10 | app: simple-daemonset 11 | template: 12 | metadata: 13 | labels: 14 | app: simple-daemonset 15 | spec: 16 | tolerations: 17 | - key: node-role.kubernetes.io/master 18 | effect: NoSchedule 19 | containers: 20 | - name: busybox 21 | image: busybox 22 | args: 23 | - sleep 24 | - "10000" -------------------------------------------------------------------------------- /workshop/k8s/ELK/simple/values_e.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # Permit co-located instances for solitary minikube virtual machines. 3 | antiAffinity: "soft" 4 | 5 | # Shrink default JVM heap. 6 | esJavaOpts: "-Xmx128m -Xms128m" 7 | 8 | # Allocate smaller chunks of memory per pod. 9 | resources: 10 | requests: 11 | cpu: "100m" 12 | memory: "512M" 13 | limits: 14 | cpu: "1000m" 15 | memory: "512M" 16 | 17 | # Request smaller persistent volumes. 18 | volumeClaimTemplate: 19 | accessModes: [ "ReadWriteOnce" ] 20 | storageClassName: "standard" 21 | resources: 22 | requests: 23 | storage: 100M 24 | -------------------------------------------------------------------------------- /docker-example-class/workshop/dockerize.DockerFile: -------------------------------------------------------------------------------- 1 | FROM node:8.7.0 2 | 3 | RUN apt-get update && apt-get install -y wget 4 | 5 | ENV DOCKERIZE_VERSION v0.5.0 6 | RUN wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \ 7 | && tar -C /usr/local/bin -xzvf dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \ 8 | && rm dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz 9 | 10 | WORKDIR /app 11 | 12 | RUN npm install mysql express 13 | 14 | COPY server.js . 15 | 16 | EXPOSE 3000 17 | 18 | CMD dockerize -wait tcp://mysql:3306 -timeout 1m && node server.js -------------------------------------------------------------------------------- /docker-example-class/racing-condition/dockerize.DockerFile: -------------------------------------------------------------------------------- 1 | FROM node:8.7.0 2 | 3 | RUN apt-get update && apt-get install -y wget 4 | 5 | ENV DOCKERIZE_VERSION v0.5.0 6 | RUN wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \ 7 | && tar -C /usr/local/bin -xzvf dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \ 8 | && rm dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz 9 | 10 | WORKDIR /app 11 | 12 | RUN npm install mysql express 13 | 14 | COPY server.js . 15 | 16 | EXPOSE 3000 17 | 18 | CMD dockerize -wait tcp://mysql:3306 -timeout 1m && node server.js -------------------------------------------------------------------------------- /ch2-volume/deployment.yaml: -------------------------------------------------------------------------------- 1 | # ka ch2-volume 2 | # kg pv 3 | # kg pvc 4 | 5 | apiVersion: apps/v1 6 | kind: Deployment 7 | metadata: 8 | name: pv-deploy 9 | spec: 10 | replicas: 1 11 | selector: 12 | matchLabels: 13 | app: mypv 14 | template: 15 | metadata: 16 | labels: 17 | app: mypv 18 | spec: 19 | containers: 20 | - name: simpleapp 21 | image: howtoautomateinth/docker-simpleapp:v1.1 22 | volumeMounts: 23 | - name: mypv 24 | mountPath: "/tmp/persistent" 25 | volumes: 26 | - name: mypv 27 | persistentVolumeClaim: 28 | claimName: myclaim -------------------------------------------------------------------------------- /ch2-volume/workshop/deployment.yaml: -------------------------------------------------------------------------------- 1 | # ka ch2-volume 2 | # kg pv 3 | # kg pvc 4 | 5 | apiVersion: apps/v1 6 | kind: Deployment 7 | metadata: 8 | name: pv-deploy 9 | spec: 10 | replicas: 1 11 | selector: 12 | matchLabels: 13 | app: mypv 14 | template: 15 | metadata: 16 | labels: 17 | app: mypv 18 | spec: 19 | containers: 20 | - name: simpleapp 21 | image: howtoautomateinth/docker-simpleapp:v1.1 22 | volumeMounts: 23 | - name: mypv 24 | mountPath: "/tmp/persistent" 25 | volumes: 26 | - name: mypv 27 | persistentVolumeClaim: 28 | claimName: myclaim -------------------------------------------------------------------------------- /docker-example-class/compose/app.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | import redis 4 | from flask import Flask 5 | 6 | app = Flask(__name__) 7 | cache = redis.Redis(host='redis', port=6379) 8 | 9 | 10 | def get_hit_count(): 11 | retries = 5 12 | while True: 13 | try: 14 | return cache.incr('hits') 15 | except redis.exceptions.ConnectionError as exc: 16 | if retries == 0: 17 | raise exc 18 | retries -= 1 19 | time.sleep(0.5) 20 | 21 | 22 | @app.route('/') 23 | def hello(): 24 | count = get_hit_count() 25 | return 'Hello from Docker ! I have been seen {} times.\n'.format(count) -------------------------------------------------------------------------------- /docker-example-class/racing-condition/docker-compose.yml: -------------------------------------------------------------------------------- 1 | # docker-compose build 2 | # docker-compose up -d 3 | # docker-compose ps 4 | # docker-compose logs -f app 5 | 6 | version: '3.7' 7 | 8 | services: 9 | mysql: 10 | image: mysql:5.6 11 | environment: 12 | - MYSQL_ROOT_PASSWORD=root 13 | networks: 14 | - db-net 15 | 16 | app: 17 | build: 18 | context: . 19 | dockerfile: dockerize.DockerFile 20 | ports: 21 | - 3000:3000 22 | environment: 23 | - MYSQL_HOST=mysql 24 | - MYSQL_USER=root 25 | - MYSQL_PASSWORD=root 26 | networks: 27 | - db-net 28 | 29 | networks: 30 | db-net: 31 | driver: bridge -------------------------------------------------------------------------------- /docker-example-class/workshop/server.js: -------------------------------------------------------------------------------- 1 | var MySQL = require('mysql'), 2 | express = require('express'), 3 | app = express(); 4 | 5 | var connection = MySQL.createConnection({ 6 | host : process.env.MYSQL_HOST || 'localhost', 7 | user : process.env.MYSQL_USER || '', 8 | password : process.env.MYSQL_PASSWORD || '' 9 | }); 10 | 11 | connection.connect(function(err){ 12 | if(err){ 13 | console.log('error connecting:', err.stack); 14 | process.exit(1); 15 | } 16 | console.log('connected as id:', connection.threadId); 17 | }) 18 | 19 | app.get('/', function(req, res){ 20 | res.send('Hello world :)'); 21 | }) 22 | 23 | app.listen(3000, function(){ 24 | console.log('Server started ....'); 25 | }) -------------------------------------------------------------------------------- /docker-example-class/racing-condition/server.js: -------------------------------------------------------------------------------- 1 | var MySQL = require('mysql'), 2 | express = require('express'), 3 | app = express(); 4 | 5 | var connection = MySQL.createConnection({ 6 | host : process.env.MYSQL_HOST || 'localhost', 7 | user : process.env.MYSQL_USER || '', 8 | password : process.env.MYSQL_PASSWORD || '' 9 | }); 10 | 11 | connection.connect(function(err){ 12 | if(err){ 13 | console.log('error connecting:', err.stack); 14 | process.exit(1); 15 | } 16 | console.log('connected as id:', connection.threadId); 17 | }) 18 | 19 | app.get('/', function(req, res){ 20 | res.send('Hello world :)'); 21 | }) 22 | 23 | app.listen(3000, function(){ 24 | console.log('Server started ....'); 25 | }) -------------------------------------------------------------------------------- /workshop/k8s/skaffold/k8s/k8s-pod.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: simpleapp-service 5 | labels: 6 | run: simpleapp 7 | spec: 8 | type: NodePort 9 | ports: 10 | - 11 | # Inside the cluster, port of this service 12 | port: 8080 13 | # Service port that are going to expose 14 | targetPort: 5000 15 | # Port node that can accessible (30000-32767) 16 | nodePort: 31366 17 | name: http 18 | selector: 19 | app: simpleapp 20 | --- 21 | apiVersion: v1 22 | kind: Pod 23 | metadata: 24 | name: simpleapp 25 | labels: 26 | app: simpleapp 27 | env: development 28 | spec: 29 | containers: 30 | - name: simpleapp 31 | image: simpleapp-skaffold 32 | ports: 33 | - containerPort: 5000 -------------------------------------------------------------------------------- /ch3-services/ingress/simpleapp.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: simpleapp-cluster-ip-service 5 | spec: 6 | type: ClusterIP 7 | selector: 8 | app: simpleapp 9 | ports: 10 | - port: 5000 11 | targetPort: 5000 12 | --- 13 | apiVersion: apps/v1 14 | kind: Deployment 15 | metadata: 16 | name: simpleapp-deploy 17 | spec: 18 | replicas: 2 19 | selector: 20 | matchLabels: 21 | app: simpleapp 22 | template: 23 | metadata: 24 | labels: 25 | app: simpleapp 26 | spec: 27 | containers: 28 | - name: simpleapp 29 | image: howtoautomateinth/docker-simpleapp:v1.1 30 | ports: 31 | - containerPort: 5000 32 | env: 33 | - name: SIMPLE_APP_VERSION 34 | value: "1.1" -------------------------------------------------------------------------------- /ch8-helm/mychart/steps: -------------------------------------------------------------------------------- 1 | # add repo 2 | helm repo list 3 | helm repo add stable https://kubernetes-charts.storage.googleapis.com/ 4 | 5 | # custom steps 6 | helm install mychart 7 | helm install --generate-name mychart --dry-run --debug 8 | helm install --generate-name mychart --dry-run --debug --set service.internalPort=8080 9 | helm install --generate-name mychart --set service.type=NodePort 10 | 11 | # update helm 12 | change values.yaml image to new repository 13 | repository: prydonius/todo 14 | tag: 1.0.0 15 | 16 | # check templates are well-formed 17 | helm lint ./mychart 18 | 19 | # package 20 | helm package ./mychart 21 | 22 | # install 23 | helm install example2 ./mychart --set service.type=NodePort 24 | helm install example3 mychart-0.1.0.tgz --set service.type=NodePort -------------------------------------------------------------------------------- /docker-example-class/workshop/docker-compose.yml: -------------------------------------------------------------------------------- 1 | # docker-compose build 2 | # docker-compose up -d 3 | # docker-compose ps 4 | # docker-compose logs -f app 5 | # docker-compose down --volumes 6 | 7 | version: '3.7' 8 | 9 | services: 10 | mysql: 11 | image: mysql:5.6 12 | environment: 13 | - MYSQL_ROOT_PASSWORD=root 14 | networks: 15 | - db-net 16 | volumes: 17 | - my-db:/var/lib/mysql 18 | app: 19 | build: 20 | context: . 21 | dockerfile: dockerize.DockerFile 22 | ports: 23 | - 3000:3000 24 | restart: always 25 | environment: 26 | - MYSQL_HOST=mysql 27 | - MYSQL_USER=root 28 | - MYSQL_PASSWORD=root 29 | networks: 30 | - db-net 31 | volumes: 32 | my-db: 33 | networks: 34 | db-net: 35 | driver: bridge -------------------------------------------------------------------------------- /ch5-kustomization/customizing/script.sh: -------------------------------------------------------------------------------- 1 | cat < deployment.yaml 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | name: my-nginx 6 | spec: 7 | selector: 8 | matchLabels: 9 | run: my-nginx 10 | replicas: 2 11 | template: 12 | metadata: 13 | labels: 14 | run: my-nginx 15 | spec: 16 | containers: 17 | - name: my-nginx 18 | image: nginx 19 | EOF 20 | 21 | cat < add_container_port.yaml 22 | apiVersion: apps/v1 23 | kind: Deployment 24 | metadata: 25 | name: my-nginx 26 | spec: 27 | template: 28 | spec: 29 | containers: 30 | - name: my-nginx 31 | resources: 32 | ports: 33 | - containerPort: 80 34 | EOF 35 | 36 | cat <./kustomization.yaml 37 | resources: 38 | - deployment.yaml 39 | patchesStrategicMerge: 40 | - add_container_port.yaml 41 | EOF -------------------------------------------------------------------------------- /ch6-logging/daemonset/README.md: -------------------------------------------------------------------------------- 1 | # DaemonSet Exmaple 2 | 3 | Since our minikube limitation only one node on local machine so we will use AWS for testing DaemonSet instead 4 | 5 | ## Steps to test DaemonSet 6 | 7 | - Create cluster by following command 8 | 9 | ``` 10 | eksctl create cluster \ 11 | --name hta-cluster \ 12 | --version 1.14 \ 13 | --region us-east-1 \ 14 | --zones=us-east-1a,us-east-1b \--nodegroup-name standard-workers \ 15 | --node-type t3.medium \ 16 | --nodes 3 \ 17 | --nodes-min 1 \ 18 | --nodes-max 4 \ 19 | --ssh-access=true \ 20 | --ssh-public-key hta-cluster-key \ 21 | --managed 22 | ``` 23 | 24 | *change name,ssh-public-key* 25 | 26 | - Deploy daemonset 27 | - kubectl apply -f ./ch6-logging/daemonset.yaml 28 | - After finish please delete custer 29 | - eksctl delete cluster -n hta-cluster 30 | - depend on cluster name that you're using 31 | -------------------------------------------------------------------------------- /ch3-services/ingress/README.md: -------------------------------------------------------------------------------- 1 | # Ingress Nginx 2 | 3 | ## How to install 4 | 5 | Mandatory Command 6 | > kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.26.2/deploy/static/mandatory.yaml 7 | 8 | Create Services 9 | > kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.26.2/deploy/static/provider/cloud-generic.yaml 10 | 11 | Enable Minikube 12 | > minikube addons enable ingress 13 | 14 | After installation, it should have namespace ingress-nginx that contains pods ingress-nginx-controller and svc ingress-nginx 15 | 16 | Verify by 17 | > kubectl get svc -n ingress-nginx 18 | 19 | > kubectl get pod -n ingress-nginx 20 | 21 | ## Verify Ingress Nginx 22 | 23 | With following command it should show pods and running state 24 | > kubectl get pods --all-namespaces -l app.kubernetes.io/name=ingress-nginx --watch -------------------------------------------------------------------------------- /ch5-kustomization/composing/script.sh: -------------------------------------------------------------------------------- 1 | # Create a deployment.yaml file 2 | cat < deployment.yaml 3 | apiVersion: apps/v1 4 | kind: Deployment 5 | metadata: 6 | name: my-nginx 7 | spec: 8 | selector: 9 | matchLabels: 10 | run: my-nginx 11 | replicas: 2 12 | template: 13 | metadata: 14 | labels: 15 | run: my-nginx 16 | spec: 17 | containers: 18 | - name: my-nginx 19 | image: nginx 20 | ports: 21 | - containerPort: 80 22 | EOF 23 | 24 | # Create a service.yaml file 25 | cat < service.yaml 26 | apiVersion: v1 27 | kind: Service 28 | metadata: 29 | name: my-nginx 30 | labels: 31 | run: my-nginx 32 | spec: 33 | ports: 34 | - port: 80 35 | protocol: TCP 36 | selector: 37 | run: my-nginx 38 | EOF 39 | 40 | # Create a kustomization.yaml composing them 41 | cat <./kustomization.yaml 42 | resources: 43 | - deployment.yaml 44 | - service.yaml 45 | EOF -------------------------------------------------------------------------------- /ch3-services/clusterip/example.yaml: -------------------------------------------------------------------------------- 1 | # run with busybox to view nginx 2 | # kubectl port-forward -n default pod/nginx-deployment-7dbc5548c4-rjqpn 5555:80 3 | # http://localhost:8001/api/v1/namespaces/default/services/nginx-svc:80/proxy/ 4 | # https://gardener.cloud/050-tutorials/content/howto/access_pod_from_local/ 5 | 6 | apiVersion: apps/v1 7 | kind: Deployment 8 | metadata: 9 | name: nginx-deployment 10 | spec: 11 | selector: 12 | matchLabels: 13 | app: nginx-app 14 | replicas: 1 15 | template: 16 | metadata: 17 | labels: 18 | app: nginx-app 19 | spec: 20 | containers: 21 | - name: nginx 22 | image: nginx 23 | ports: 24 | - containerPort: 80 25 | --- 26 | apiVersion: v1 27 | kind: Service 28 | metadata: 29 | labels: 30 | app: nginx-app 31 | name: nginx-svc 32 | namespace: default 33 | spec: 34 | type: ClusterIP 35 | ports: 36 | - port: 80 37 | selector: 38 | app: nginx-app -------------------------------------------------------------------------------- /ch3-services/stateful/simple-nginx.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: nginx 5 | labels: 6 | app: nginx 7 | spec: 8 | ports: 9 | - port: 80 10 | name: web 11 | clusterIP: None 12 | selector: 13 | app: nginx 14 | --- 15 | apiVersion: apps/v1 16 | kind: StatefulSet 17 | metadata: 18 | name: web 19 | spec: 20 | serviceName: "nginx" 21 | replicas: 2 22 | selector: 23 | matchLabels: 24 | app: nginx 25 | template: 26 | metadata: 27 | labels: 28 | app: nginx 29 | spec: 30 | containers: 31 | - name: nginx 32 | image: k8s.gcr.io/nginx-slim:0.8 33 | ports: 34 | - containerPort: 80 35 | name: web 36 | volumeMounts: 37 | - name: www 38 | mountPath: /usr/share/nginx/html 39 | volumeClaimTemplates: 40 | - metadata: 41 | name: www 42 | spec: 43 | accessModes: [ "ReadWriteOnce" ] 44 | resources: 45 | requests: 46 | storage: 1Gi -------------------------------------------------------------------------------- /dashboard/README.md: -------------------------------------------------------------------------------- 1 | # Web UI (Dashboard) 2 | 3 | ## How to install 4 | 5 | - Manual 6 | 7 | > kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-beta8/aio/deploy/recommended.yaml 8 | 9 | - helm 10 | 11 | > helm install my-dashboard stable/kubernetes-dashboard 12 | 13 | ## How to create user 14 | 15 | Create service account and role binding 16 | 17 | > k apply -f ./dashboard 18 | 19 | ### Get Token 20 | 21 | bash 22 | > kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | grep admin-user | awk '{print $1}') 23 | 24 | Powershell 25 | > kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | sls admin-user | ForEach-Object { $_ -Split '\s+' } | Select -First 1) 26 | 27 | ## How to use 28 | 29 | Open proxy 30 | > k proxy 31 | 32 | then access via url 33 | 34 | > http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/ 35 | 36 | 37 | ## How to uninstall 38 | 39 | - Manual 40 | 41 | > k delete -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-beta8/aio/deploy/recommended.yaml 42 | 43 | - Helm 44 | 45 | > helm uninstall my-dashboard -------------------------------------------------------------------------------- /workshop/k8s/wordpress/barefoot/phpmyadmin.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Ingress 3 | metadata: 4 | name: phpmyadmin-http-ingress 5 | spec: 6 | backend: 7 | serviceName: phpmyadmin-service 8 | servicePort: 80 9 | --- 10 | apiVersion: v1 11 | kind: Service 12 | metadata: 13 | name: phpmyadmin-service 14 | spec: 15 | type: NodePort 16 | selector: 17 | app: phpmyadmin 18 | ports: 19 | - protocol: TCP 20 | port: 80 21 | targetPort: 80 22 | --- 23 | apiVersion: apps/v1 24 | kind: Deployment 25 | metadata: 26 | name: phpmyadmin-deployment 27 | labels: 28 | app: phpmyadmin 29 | spec: 30 | replicas: 1 31 | selector: 32 | matchLabels: 33 | app: phpmyadmin 34 | template: 35 | metadata: 36 | labels: 37 | app: phpmyadmin 38 | spec: 39 | containers: 40 | - name: phpmyadmin 41 | image: phpmyadmin/phpmyadmin 42 | ports: 43 | - containerPort: 80 44 | env: 45 | - name: PMA_HOST 46 | value: wordpress-mysql 47 | - name: PMA_PORT 48 | value: "3306" 49 | - name: MYSQL_ROOT_PASSWORD 50 | valueFrom: 51 | secretKeyRef: 52 | name: mysql-pass 53 | key: password -------------------------------------------------------------------------------- /workshop/k8s/wordpress/gke/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Wordpress on GKE tutorial 3 | 4 | Example how to deploy wordpress on Google Cloud Platform 5 | 6 | ## Prerequsite 7 | 8 | - install [gcloud cli](https://cloud.google.com/sdk/docs/downloads-interactive) based on your OS 9 | - gcloud init 10 | - for config project that going to use 11 | - gcloud container clusters get-credentials *wp-cluster* --region=*us-west1-a* 12 | - change cluster name and region based on your configuration 13 | - this step will modify your local kubeconfig to generate context for your local machine 14 | - gcloud auth application-default login 15 | - authenticated with the Google Cloud SDK 16 | - for enable using Google client libraries 17 | 18 | ## Steps 19 | 20 | - Create cluster with gcloud gke 21 | - gcloud container clusters create wp-cluster --enable-cloud-logging --enable-cloud-monitoring --subnetwork=default --zone=us-west1-a 22 | - change cluster name and region based on your desired 23 | - *Verify by* 24 | - kubectl config get-contexts 25 | - kubectl get services 26 | - install.sh to install wordpress with helm 27 | - use web dashboard to view object in gke 28 | - uninstall.sh to uninstall wordpress with helm 29 | - gcloud container clusters delete wp-cluster --region=us-west1-a 30 | - change cluster name and region based on your desired 31 | -------------------------------------------------------------------------------- /workshop/k8s/skaffold/README.md: -------------------------------------------------------------------------------- 1 | # Skaffold Tutorial 2 | 3 | Skaffold handles the workflow for building, pushing and deploying your application, allowing you to focus on what matters most: writing code. 4 | 5 | ## Skaffold Feature 6 | 7 | - Fast local Kubernetes Development 8 | - Remote development 9 | - Tag management 10 | - Rebuild only what's changed 11 | 12 | ## Skaffold Overview 13 | 14 | ![Skaffold Pipeline Stages](https://skaffold.dev/images/workflow.png) 15 | 16 | Inside *skaffold.yaml* it depend on above stages which we can interact with 17 | 18 | ## Skaffold modes 19 | 20 | - skaffold dev (local) 21 | - build 22 | - deploy 23 | - watch files 24 | - stream logs 25 | - skaffold run (continuous deployment) 26 | - build 27 | - deploy 28 | - skaffold build 29 | - build 30 | 31 | ## Prerequsite 32 | 33 | - [Skaffold](https://skaffold.dev/docs/install/) 34 | - [Minikube](https://kubernetes.io/docs/tasks/tools/install-minikube/) 35 | - for local development 36 | 37 | ## Steps 38 | - minikube start 39 | - skaffold dev (for local testing) 40 | - change code in *python/**/*.py* will immediately effect on local cluster 41 | - changed will watching by skaffold and deploy to local cluster via kubectl with *k8s/k8s-* pattern 42 | 43 | ## References 44 | - [Skaffold YAML references](https://skaffold.dev/docs/references/yaml/) -------------------------------------------------------------------------------- /workshop/k8s/wordpress/barefoot/mysql.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: wordpress-mysql 5 | labels: 6 | app: wordpress 7 | spec: 8 | ports: 9 | - port: 3306 10 | selector: 11 | app: wordpress 12 | tier: mysql 13 | clusterIP: None 14 | --- 15 | apiVersion: v1 16 | kind: PersistentVolumeClaim 17 | metadata: 18 | name: mysql-pv-claim 19 | labels: 20 | app: wordpress 21 | spec: 22 | accessModes: 23 | - ReadWriteOnce 24 | resources: 25 | requests: 26 | storage: 20Gi 27 | --- 28 | apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2 29 | kind: Deployment 30 | metadata: 31 | name: wordpress-mysql 32 | labels: 33 | app: wordpress 34 | spec: 35 | selector: 36 | matchLabels: 37 | app: wordpress 38 | tier: mysql 39 | strategy: 40 | type: Recreate 41 | template: 42 | metadata: 43 | labels: 44 | app: wordpress 45 | tier: mysql 46 | spec: 47 | containers: 48 | - image: mysql:5.6 49 | name: mysql 50 | env: 51 | - name: MYSQL_ROOT_PASSWORD 52 | valueFrom: 53 | secretKeyRef: 54 | name: mysql-pass 55 | key: password 56 | ports: 57 | - containerPort: 3306 58 | name: mysql 59 | volumeMounts: 60 | - name: mysql-persistent-storage 61 | mountPath: /var/lib/mysql 62 | volumes: 63 | - name: mysql-persistent-storage 64 | persistentVolumeClaim: 65 | claimName: mysql-pv-claim -------------------------------------------------------------------------------- /workshop/k8s/wordpress/barefoot/wordpress.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: wordpress 5 | labels: 6 | app: wordpress 7 | spec: 8 | ports: 9 | - port: 80 10 | selector: 11 | app: wordpress 12 | tier: frontend 13 | type: LoadBalancer 14 | --- 15 | apiVersion: v1 16 | kind: PersistentVolumeClaim 17 | metadata: 18 | name: wp-pv-claim 19 | labels: 20 | app: wordpress 21 | spec: 22 | accessModes: 23 | - ReadWriteOnce 24 | resources: 25 | requests: 26 | storage: 20Gi 27 | --- 28 | apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2 29 | kind: Deployment 30 | metadata: 31 | name: wordpress 32 | labels: 33 | app: wordpress 34 | spec: 35 | selector: 36 | matchLabels: 37 | app: wordpress 38 | tier: frontend 39 | strategy: 40 | type: Recreate 41 | template: 42 | metadata: 43 | labels: 44 | app: wordpress 45 | tier: frontend 46 | spec: 47 | containers: 48 | - image: wordpress:4.8-apache 49 | name: wordpress 50 | env: 51 | - name: WORDPRESS_DB_HOST 52 | value: wordpress-mysql 53 | - name: WORDPRESS_DB_PASSWORD 54 | valueFrom: 55 | secretKeyRef: 56 | name: mysql-pass 57 | key: password 58 | ports: 59 | - containerPort: 80 60 | name: wordpress 61 | volumeMounts: 62 | - name: wordpress-persistent-storage 63 | mountPath: /var/www/html 64 | volumes: 65 | - name: wordpress-persistent-storage 66 | persistentVolumeClaim: 67 | claimName: wp-pv-claim -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Docker & K8S class 2 | Workshop and examples for docker and k8s class 3 | 4 | ## Prepare working environment 5 | - Docker (Required) 6 | - Mac 7 | - Download and install [Docker for mac](https://docs.docker.com/docker-for-mac/install/) 8 | - Window 9 | - Window 10 Pro and above 10 | - [Docker for window](https://docs.docker.com/docker-for-windows/install/) 11 | - Window 10 Home and below 12 | - [Docker Toolbox](https://docs.docker.com/toolbox/toolbox_install_windows/) 13 | - K8S [Minikube](https://kubernetes.io/docs/tasks/tools/install-minikube/) (Required) 14 | - Mac 15 | - brew install minikube 16 | - [kubectl alias](https://github.com/ahmetb/kubectl-aliases) 17 | - Window 18 | - choco install minikube 19 | - Useful Tools 20 | - Window 21 | - [Chocolatey](https://chocolatey.org/install#individual) 22 | - [jq](https://chocolatey.org/packages/jq) 23 | - Mac 24 | - [Brew](https://brew.sh/) 25 | - [jq](https://stedolan.github.io/jq/download/) 26 | - [Travis](https://travis-ci.org/) Account (Optional) 27 | - [AWS Free Account](https://aws.amazon.com/) (Optional) 28 | 29 | Recommended: Do not use kubernetes that packed with Docker for Desktop 30 | 31 | ## Verify your machine with following command 32 | - Docker 33 | - docker run hello-world 34 | - K8S 35 | - minikube status 36 | - kubectl cluster-info 37 | - Package Manager 38 | - Window 39 | - choco -? 40 | - Mac 41 | - brew --version 42 | 43 | ## Useful troubleshooting techniques 44 | - K8S command 45 | - k get all 46 | - k delete all --all 47 | - k exec pod/busybox -i -t -- (command) 48 | - k logs (pod name) 49 | - k describe (service name) (name) 50 | - minikube service list 51 | - minikube dashboard 52 | 53 | - printenv 54 | - will show all env. that use in the POD and lead to find information 55 | 56 | - dashboard 57 | - we can see many information and secret in there 58 | -------------------------------------------------------------------------------- /workshop/k8s/wordpress/aws/README.md: -------------------------------------------------------------------------------- 1 | # Wordpress on EKS tutorial 2 | 3 | Example how to deploy wordpress on AWS EKS 4 | 5 | ## Prerequsite 6 | 7 | - [AWS CLI](https://pypi.org/project/awscli/) 8 | - pip install awscli --upgrade --user 9 | - aws configure (for using awscli, with eks credential) 10 | - [eksctl](https://github.com/weaveworks/eksctl) 11 | - brew tap weaveworks/tap 12 | - brew install weaveworks/tap/eksctl 13 | 14 | ## Steps 15 | 16 | - eksctl create cluster 17 | - for testing purpose (it need to show cluster endpoint instead of minikube) 18 | - kubectl get svc 19 | - kubectl config get-contexts 20 | 21 | ``` 22 | eksctl create cluster \ 23 | --name hta-cluster \ 24 | --version 1.14 \ 25 | --region us-east-1 \ 26 | --zones=us-east-1a,us-east-1b \--nodegroup-name standard-workers \ 27 | --node-type t3.medium \ 28 | --nodes 3 \ 29 | --nodes-min 1 \ 30 | --nodes-max 4 \ 31 | --ssh-access=true \ 32 | --ssh-public-key hta-cluster-key \ 33 | --managed 34 | ``` 35 | 36 | - use helm to install wordpress via *install.sh* 37 | - kubectl get all 38 | - in this step, you should see a list of pod and service that running on eks 39 | 40 | *change name argument and ssh-public-key to the desired name* 41 | *ssh-public-key default will trying to find in local first then will find in EC2 keypair* 42 | 43 | ## Recommendation 44 | 45 | - Create Cluster with specific user 46 | - If console, please use user that generated for cluster not root user 47 | - If CLI, please user eksctl 48 | - user for cluster need **IAM policy** (If don't sure please select full access for all services) 49 | - ec2 key 50 | - cloudformation create 51 | - eks full access 52 | - iam create 53 | - In case you want switch back to minikube 54 | - eksctl delete cluster -n hta-cluster 55 | - kubectl config get-contexts (should be minikube) 56 | - *for security reason, dont use console switch with cli it may occur security problem on cloudformation* 57 | 58 | ## Troblueshooting commandline 59 | 60 | - aws sts get-caller-identity 61 | - kubectl get svc --v=10 62 | 63 | -------------------------------------------------------------------------------- /docker-example-class/compose/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/python 3 | # Edit at https://www.gitignore.io/?templates=python 4 | 5 | ### Python ### 6 | # Byte-compiled / optimized / DLL files 7 | __pycache__/ 8 | *.py[cod] 9 | *$py.class 10 | 11 | # C extensions 12 | *.so 13 | 14 | # Distribution / packaging 15 | .Python 16 | build/ 17 | develop-eggs/ 18 | dist/ 19 | downloads/ 20 | eggs/ 21 | .eggs/ 22 | lib/ 23 | lib64/ 24 | parts/ 25 | sdist/ 26 | var/ 27 | wheels/ 28 | pip-wheel-metadata/ 29 | share/python-wheels/ 30 | *.egg-info/ 31 | .installed.cfg 32 | *.egg 33 | MANIFEST 34 | 35 | # PyInstaller 36 | # Usually these files are written by a python script from a template 37 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 38 | *.manifest 39 | *.spec 40 | 41 | # Installer logs 42 | pip-log.txt 43 | pip-delete-this-directory.txt 44 | 45 | # Unit test / coverage reports 46 | htmlcov/ 47 | .tox/ 48 | .nox/ 49 | .coverage 50 | .coverage.* 51 | .cache 52 | nosetests.xml 53 | coverage.xml 54 | *.cover 55 | .hypothesis/ 56 | .pytest_cache/ 57 | 58 | # Translations 59 | *.mo 60 | *.pot 61 | 62 | # Scrapy stuff: 63 | .scrapy 64 | 65 | # Sphinx documentation 66 | docs/_build/ 67 | 68 | # PyBuilder 69 | target/ 70 | 71 | # pyenv 72 | .python-version 73 | 74 | # pipenv 75 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 76 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 77 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 78 | # install all needed dependencies. 79 | #Pipfile.lock 80 | 81 | # celery beat schedule file 82 | celerybeat-schedule 83 | 84 | # SageMath parsed files 85 | *.sage.py 86 | 87 | # Spyder project settings 88 | .spyderproject 89 | .spyproject 90 | 91 | # Rope project settings 92 | .ropeproject 93 | 94 | # Mr Developer 95 | .mr.developer.cfg 96 | .project 97 | .pydevproject 98 | 99 | # mkdocs documentation 100 | /site 101 | 102 | # mypy 103 | .mypy_cache/ 104 | .dmypy.json 105 | dmypy.json 106 | 107 | # Pyre type checker 108 | .pyre/ 109 | 110 | # End of https://www.gitignore.io/api/python 111 | -------------------------------------------------------------------------------- /docker-example-class/nodeapp/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/node 3 | # Edit at https://www.gitignore.io/?templates=node 4 | 5 | ### Node ### 6 | # Logs 7 | logs 8 | *.log 9 | npm-debug.log* 10 | yarn-debug.log* 11 | yarn-error.log* 12 | lerna-debug.log* 13 | 14 | # Diagnostic reports (https://nodejs.org/api/report.html) 15 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 16 | 17 | # Runtime data 18 | pids 19 | *.pid 20 | *.seed 21 | *.pid.lock 22 | 23 | # Directory for instrumented libs generated by jscoverage/JSCover 24 | lib-cov 25 | 26 | # Coverage directory used by tools like istanbul 27 | coverage 28 | *.lcov 29 | 30 | # nyc test coverage 31 | .nyc_output 32 | 33 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 34 | .grunt 35 | 36 | # Bower dependency directory (https://bower.io/) 37 | bower_components 38 | 39 | # node-waf configuration 40 | .lock-wscript 41 | 42 | # Compiled binary addons (https://nodejs.org/api/addons.html) 43 | build/Release 44 | 45 | # Dependency directories 46 | node_modules/ 47 | jspm_packages/ 48 | 49 | # TypeScript v1 declaration files 50 | typings/ 51 | 52 | # TypeScript cache 53 | *.tsbuildinfo 54 | 55 | # Optional npm cache directory 56 | .npm 57 | 58 | # Optional eslint cache 59 | .eslintcache 60 | 61 | # Optional REPL history 62 | .node_repl_history 63 | 64 | # Output of 'npm pack' 65 | *.tgz 66 | 67 | # Yarn Integrity file 68 | .yarn-integrity 69 | 70 | # dotenv environment variables file 71 | .env 72 | .env.test 73 | 74 | # parcel-bundler cache (https://parceljs.org/) 75 | .cache 76 | 77 | # next.js build output 78 | .next 79 | 80 | # nuxt.js build output 81 | .nuxt 82 | 83 | # rollup.js default build output 84 | dist/ 85 | 86 | # Uncomment the public line if your project uses Gatsby 87 | # https://nextjs.org/blog/next-9-1#public-directory-support 88 | # https://create-react-app.dev/docs/using-the-public-folder/#docsNav 89 | # public 90 | 91 | # Storybook build outputs 92 | .out 93 | .storybook-out 94 | 95 | # vuepress build output 96 | .vuepress/dist 97 | 98 | # Serverless directories 99 | .serverless/ 100 | 101 | # FuseBox cache 102 | .fusebox/ 103 | 104 | # DynamoDB Local files 105 | .dynamodb/ 106 | 107 | # Temporary folders 108 | tmp/ 109 | temp/ 110 | 111 | # End of https://www.gitignore.io/api/node 112 | -------------------------------------------------------------------------------- /workshop/docker/ecs/README.md: -------------------------------------------------------------------------------- 1 | # How to use AWS ECS tutorial 2 | Example usage of ECS 3 | 4 | ![overview](https://cdn-media-1.freecodecamp.org/images/scH1QJHgrQ6NgA1jQo9ITuCiQGkAawRHmzSc) 5 | 6 | *Thanks image from [here](https://cdn-media-1.freecodecamp.org/images/scH1QJHgrQ6NgA1jQo9ITuCiQGkAawRHmzSc)* 7 | 8 | ## Definition 9 | 10 | - Cluster 11 | - a logic group of EC2 instances 12 | - Task Definition 13 | - a blueprint that describes how a docker container should launch 14 | - Task 15 | - instance of Task Definition (running container with settings defined) 16 | - Service 17 | - long running Task of the same Task Definition, if a task in a service stops, the task is killed and a new task is launched 18 | - Container Instance 19 | - EC2 instance that is part of an ECS Cluster and has docker and the ecs-agent running on it 20 | 21 | *Read other AWS summary [here](https://github.com/howtoautomateinth/awesome-aws/blob/master/README.md)* 22 | 23 | ## Prerequsite 24 | - [ECS CLI](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_CLI_installation.html) 25 | - [configure](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_CLI_Configuration.html) access key 26 | - Configuration information is stored in the ~/.ecs directory on macOS and Linux systems and in C:\Users\\AppData\local\ecs on Windows systems. 27 | = Create [ecsInstanceRole](https://docs.aws.amazon.com/batch/latest/userguide/instance_IAM_role.html) for permission ECS 28 | - Create EC2 key on datacenter you desired 29 | 30 | ## Steps 31 | 32 | ``` 33 | # configure going to use cluster for using in this tutorial 34 | ecs-cli configure --cluster ec2-tutorial --default-launch-type EC2 --config-name ec2-tutorial --region us-west-2 35 | 36 | # configure if you didn't configure above (this will related with permission that generated user have) 37 | ecs-cli configure profile --access-key AWS_ACCESS_KEY_ID --secret-key AWS_SECRET_ACCESS_KEY --profile-name ec2-tutorial-profile 38 | 39 | # create cluster with keypair (keypair refer to EC2 keypair that existing on AWS) 40 | # also don't forget to create ecsInstanceRole on prerequsite step 41 | ecs-cli up --keypair id_rsa --capability-iam --size 2 --instance-type t2.medium --cluster-config ec2-tutorial --ecs-profile ec2-tutorial-profile --instance-role ecsInstanceRole 42 | 43 | # deploy our compose file to ecs 44 | # the command looks for a compose file called docker-compose.yml and an optional ECS parameters file called ecs-params.yml in the current directory 45 | ecs-cli compose up --create-log-groups --cluster-config ec2-tutorial --ecs-profile ec2-tutorial-profile 46 | 47 | # verify process is up 48 | ecs-cli ps --cluster-config ec2-tutorial --ecs-profile ec2-tutorial-profile 49 | 50 | # scale it 51 | ecs-cli compose scale 2 --cluster-config ec2-tutorial --ecs-profile ec2-tutorial-profile 52 | 53 | # test service for grouping task as a long running 54 | ecs-cli compose down --cluster-config ec2-tutorial --ecs-profile ec2-tutorial-profile 55 | ecs-cli compose service up --cluster-config ec2-tutorial --ecs-profile ec2-tutorial-profile 56 | 57 | # clean up 58 | ecs-cli compose service rm --cluster-config ec2-tutorial --ecs-profile ec2-tutorial-profile 59 | ecs-cli down --force --cluster-config ec2-tutorial --ecs-profile ec2-tutorial-profile 60 | ``` 61 | 62 | ### References 63 | - [Loadbalance with ECS](https://medium.com/boltops/gentle-introduction-to-how-aws-ecs-works-with-example-tutorial-cea3d27ce63d) 64 | -------------------------------------------------------------------------------- /docker-example-class/nodeapp/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "simplenodeapp", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "accepts": { 8 | "version": "1.3.7", 9 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", 10 | "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", 11 | "dev": true, 12 | "requires": { 13 | "mime-types": "~2.1.24", 14 | "negotiator": "0.6.2" 15 | } 16 | }, 17 | "array-flatten": { 18 | "version": "1.1.1", 19 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 20 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", 21 | "dev": true 22 | }, 23 | "body-parser": { 24 | "version": "1.19.0", 25 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", 26 | "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", 27 | "dev": true, 28 | "requires": { 29 | "bytes": "3.1.0", 30 | "content-type": "~1.0.4", 31 | "debug": "2.6.9", 32 | "depd": "~1.1.2", 33 | "http-errors": "1.7.2", 34 | "iconv-lite": "0.4.24", 35 | "on-finished": "~2.3.0", 36 | "qs": "6.7.0", 37 | "raw-body": "2.4.0", 38 | "type-is": "~1.6.17" 39 | } 40 | }, 41 | "bytes": { 42 | "version": "3.1.0", 43 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", 44 | "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", 45 | "dev": true 46 | }, 47 | "content-disposition": { 48 | "version": "0.5.3", 49 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", 50 | "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", 51 | "dev": true, 52 | "requires": { 53 | "safe-buffer": "5.1.2" 54 | } 55 | }, 56 | "content-type": { 57 | "version": "1.0.4", 58 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 59 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", 60 | "dev": true 61 | }, 62 | "cookie": { 63 | "version": "0.4.0", 64 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", 65 | "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", 66 | "dev": true 67 | }, 68 | "cookie-signature": { 69 | "version": "1.0.6", 70 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 71 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", 72 | "dev": true 73 | }, 74 | "debug": { 75 | "version": "2.6.9", 76 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 77 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 78 | "dev": true, 79 | "requires": { 80 | "ms": "2.0.0" 81 | } 82 | }, 83 | "depd": { 84 | "version": "1.1.2", 85 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 86 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", 87 | "dev": true 88 | }, 89 | "destroy": { 90 | "version": "1.0.4", 91 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 92 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", 93 | "dev": true 94 | }, 95 | "ee-first": { 96 | "version": "1.1.1", 97 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 98 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", 99 | "dev": true 100 | }, 101 | "encodeurl": { 102 | "version": "1.0.2", 103 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 104 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", 105 | "dev": true 106 | }, 107 | "escape-html": { 108 | "version": "1.0.3", 109 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 110 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", 111 | "dev": true 112 | }, 113 | "etag": { 114 | "version": "1.8.1", 115 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 116 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", 117 | "dev": true 118 | }, 119 | "express": { 120 | "version": "4.17.1", 121 | "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", 122 | "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", 123 | "dev": true, 124 | "requires": { 125 | "accepts": "~1.3.7", 126 | "array-flatten": "1.1.1", 127 | "body-parser": "1.19.0", 128 | "content-disposition": "0.5.3", 129 | "content-type": "~1.0.4", 130 | "cookie": "0.4.0", 131 | "cookie-signature": "1.0.6", 132 | "debug": "2.6.9", 133 | "depd": "~1.1.2", 134 | "encodeurl": "~1.0.2", 135 | "escape-html": "~1.0.3", 136 | "etag": "~1.8.1", 137 | "finalhandler": "~1.1.2", 138 | "fresh": "0.5.2", 139 | "merge-descriptors": "1.0.1", 140 | "methods": "~1.1.2", 141 | "on-finished": "~2.3.0", 142 | "parseurl": "~1.3.3", 143 | "path-to-regexp": "0.1.7", 144 | "proxy-addr": "~2.0.5", 145 | "qs": "6.7.0", 146 | "range-parser": "~1.2.1", 147 | "safe-buffer": "5.1.2", 148 | "send": "0.17.1", 149 | "serve-static": "1.14.1", 150 | "setprototypeof": "1.1.1", 151 | "statuses": "~1.5.0", 152 | "type-is": "~1.6.18", 153 | "utils-merge": "1.0.1", 154 | "vary": "~1.1.2" 155 | } 156 | }, 157 | "finalhandler": { 158 | "version": "1.1.2", 159 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", 160 | "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", 161 | "dev": true, 162 | "requires": { 163 | "debug": "2.6.9", 164 | "encodeurl": "~1.0.2", 165 | "escape-html": "~1.0.3", 166 | "on-finished": "~2.3.0", 167 | "parseurl": "~1.3.3", 168 | "statuses": "~1.5.0", 169 | "unpipe": "~1.0.0" 170 | } 171 | }, 172 | "forwarded": { 173 | "version": "0.1.2", 174 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", 175 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", 176 | "dev": true 177 | }, 178 | "fresh": { 179 | "version": "0.5.2", 180 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 181 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", 182 | "dev": true 183 | }, 184 | "http-errors": { 185 | "version": "1.7.2", 186 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", 187 | "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", 188 | "dev": true, 189 | "requires": { 190 | "depd": "~1.1.2", 191 | "inherits": "2.0.3", 192 | "setprototypeof": "1.1.1", 193 | "statuses": ">= 1.5.0 < 2", 194 | "toidentifier": "1.0.0" 195 | } 196 | }, 197 | "iconv-lite": { 198 | "version": "0.4.24", 199 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 200 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 201 | "dev": true, 202 | "requires": { 203 | "safer-buffer": ">= 2.1.2 < 3" 204 | } 205 | }, 206 | "inherits": { 207 | "version": "2.0.3", 208 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 209 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", 210 | "dev": true 211 | }, 212 | "ipaddr.js": { 213 | "version": "1.9.1", 214 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 215 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", 216 | "dev": true 217 | }, 218 | "media-typer": { 219 | "version": "0.3.0", 220 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 221 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", 222 | "dev": true 223 | }, 224 | "merge-descriptors": { 225 | "version": "1.0.1", 226 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 227 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", 228 | "dev": true 229 | }, 230 | "methods": { 231 | "version": "1.1.2", 232 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 233 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", 234 | "dev": true 235 | }, 236 | "mime": { 237 | "version": "1.6.0", 238 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 239 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", 240 | "dev": true 241 | }, 242 | "mime-db": { 243 | "version": "1.43.0", 244 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz", 245 | "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==", 246 | "dev": true 247 | }, 248 | "mime-types": { 249 | "version": "2.1.26", 250 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz", 251 | "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==", 252 | "dev": true, 253 | "requires": { 254 | "mime-db": "1.43.0" 255 | } 256 | }, 257 | "ms": { 258 | "version": "2.0.0", 259 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 260 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", 261 | "dev": true 262 | }, 263 | "negotiator": { 264 | "version": "0.6.2", 265 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", 266 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", 267 | "dev": true 268 | }, 269 | "on-finished": { 270 | "version": "2.3.0", 271 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 272 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 273 | "dev": true, 274 | "requires": { 275 | "ee-first": "1.1.1" 276 | } 277 | }, 278 | "parseurl": { 279 | "version": "1.3.3", 280 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 281 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", 282 | "dev": true 283 | }, 284 | "path-to-regexp": { 285 | "version": "0.1.7", 286 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 287 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", 288 | "dev": true 289 | }, 290 | "proxy-addr": { 291 | "version": "2.0.6", 292 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", 293 | "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", 294 | "dev": true, 295 | "requires": { 296 | "forwarded": "~0.1.2", 297 | "ipaddr.js": "1.9.1" 298 | } 299 | }, 300 | "qs": { 301 | "version": "6.7.0", 302 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", 303 | "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", 304 | "dev": true 305 | }, 306 | "range-parser": { 307 | "version": "1.2.1", 308 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 309 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", 310 | "dev": true 311 | }, 312 | "raw-body": { 313 | "version": "2.4.0", 314 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", 315 | "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", 316 | "dev": true, 317 | "requires": { 318 | "bytes": "3.1.0", 319 | "http-errors": "1.7.2", 320 | "iconv-lite": "0.4.24", 321 | "unpipe": "1.0.0" 322 | } 323 | }, 324 | "safe-buffer": { 325 | "version": "5.1.2", 326 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 327 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", 328 | "dev": true 329 | }, 330 | "safer-buffer": { 331 | "version": "2.1.2", 332 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 333 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", 334 | "dev": true 335 | }, 336 | "send": { 337 | "version": "0.17.1", 338 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", 339 | "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", 340 | "dev": true, 341 | "requires": { 342 | "debug": "2.6.9", 343 | "depd": "~1.1.2", 344 | "destroy": "~1.0.4", 345 | "encodeurl": "~1.0.2", 346 | "escape-html": "~1.0.3", 347 | "etag": "~1.8.1", 348 | "fresh": "0.5.2", 349 | "http-errors": "~1.7.2", 350 | "mime": "1.6.0", 351 | "ms": "2.1.1", 352 | "on-finished": "~2.3.0", 353 | "range-parser": "~1.2.1", 354 | "statuses": "~1.5.0" 355 | }, 356 | "dependencies": { 357 | "ms": { 358 | "version": "2.1.1", 359 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", 360 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", 361 | "dev": true 362 | } 363 | } 364 | }, 365 | "serve-static": { 366 | "version": "1.14.1", 367 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", 368 | "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", 369 | "dev": true, 370 | "requires": { 371 | "encodeurl": "~1.0.2", 372 | "escape-html": "~1.0.3", 373 | "parseurl": "~1.3.3", 374 | "send": "0.17.1" 375 | } 376 | }, 377 | "setprototypeof": { 378 | "version": "1.1.1", 379 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", 380 | "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", 381 | "dev": true 382 | }, 383 | "statuses": { 384 | "version": "1.5.0", 385 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", 386 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", 387 | "dev": true 388 | }, 389 | "toidentifier": { 390 | "version": "1.0.0", 391 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", 392 | "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", 393 | "dev": true 394 | }, 395 | "type-is": { 396 | "version": "1.6.18", 397 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 398 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 399 | "dev": true, 400 | "requires": { 401 | "media-typer": "0.3.0", 402 | "mime-types": "~2.1.24" 403 | } 404 | }, 405 | "unpipe": { 406 | "version": "1.0.0", 407 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 408 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", 409 | "dev": true 410 | }, 411 | "utils-merge": { 412 | "version": "1.0.1", 413 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 414 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", 415 | "dev": true 416 | }, 417 | "vary": { 418 | "version": "1.1.2", 419 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 420 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", 421 | "dev": true 422 | } 423 | } 424 | } 425 | --------------------------------------------------------------------------------