# Kubernetes for JS Developers (3 hours, 22nd March 2021 - Joel Lord, Dev Advocate, Red Hat OpenShift, Twitter: @joel__lord) ## Agenda - [Intro to Containers and Kubernetes](#Intro) - [Basic Kubernetes Objects](#Kubernetes) - Front-End Application Deployment - Back-End Application Deployment - Monitoring and Logging - Health Checks - [Further Reading](#Further-Reading) ## Intro #### Prerequisites The following tools should be installed prior to the workshop: Docker (or Podman) Minikube [Kubectl]() #### Brief history of containers A container is a lightweight standalone, executable package of software that includes everything needed to run an application: code, runtime, system tools, system libraries and settings. ```bash= docker run -d -rm --name my-node -v $(pwd):/app -p 3000:3000 node:14 node /app ``` ``` FROM node:14 EXPOSE 3000 WORKDIR /app COPY . /app RUN npm install CMD npm start ``` ```bash= docker build .... docker run ... ``` Link to presentation on containers http://javascripteverything.com/landing/containers.php <br/> ## Kubernetes Kubernetes helps with: - Ensuring Pods (containers) are always running - Makes scaling your application easier - Takes care of networking between Pods <br/> #### Nodes A node is a machine or virtual machine that has all the tools required to run pods Two types: 1. Master nodes - manage the worker nodes, 2-3 of them 2. Worker nodes - run the containers, if one fails, the master node will manage that ```bash= kubectl get nodes # List nodes ``` <br/> #### Pods A group of one or more containers with shared storage/network resources Every container in the pod is very tightly coupled ##### **`1.yaml`** ```yaml= apiVersion: v1 kind: Pod metadata: name: hello spec: containers: - name: hello image: node:14 command: [ "/bin/bash", "-c", "--" ] args: [ "node -e \"console.log('Hello'); setTimeout(() => console.log('Terminating'),30000)\"" ] ``` ```bash= kubectl apply -f 1.yaml kubectl get all kubectl describe pod/hello kubectl logs hello kubectl delete pod hello ``` ##### **`2.yaml`** ```yaml= apiVersion: v1 kind: Pod metadata: name: webserver spec: containers: - name: nginx image: nginx:1.17 ``` ```bash= kubectl apply -f 2.yaml kubectl get pods kubectl exec -it pod/webserver -- /bin/bash root@webserver:/# service nginx status [ ok ] nginx is running. ``` ##### **`3.json`** ```json= { "apiVersion": "v1", "kind": "Pod", "metadata": { "name": "toolbox" }, "spec": { "containers": [ { "name": "toolbox", "image": "registry.access.redhat.com/ubi8/ubi", "command": [ "/bin/bash", "-c", "--" ], "args": [ "while true; do sleep 30; done;" ] } ] } } ``` ```bash= kubectl apply -f 3.json kubectl get pods kubectl exec -it pod/toolbox -- /bin/bash printenv #returns all system variables kubectl exec -it pod/webserver -- /bin/bash hostname -I # returns 172.17.0.4, internal ip for webserver kubectl exec -it pod/toolbox -- /bin/bash curl 172.17.0.4 ``` #### Deployments Describes the pods you want to deploy, how many you want - the plan. Will create replica sets, which ensure that pods are always running ##### **`4.yaml`** ```yaml= apiVersion: apps/v1 kind: Deployment metadata: name: hello spec: selector: # look for any pods with this label. If so, it knows it should manage them matchLabels: job: say-hello template: metadata: labels: job: say-hello spec: containers: - name: hello image: joellord/handson-k8s-say-hello ``` ```bash= kubectl apply -f 4.yaml kubectl get all kubectl logs hello-dc64d9cc8-rt87j kubectl get all kubectl scale deployment/hello --replicas=3 # kubectl logs -l=say-hello TODO fill in how to log based on labels ``` ##### **`5.yaml`** ```yaml= apiVersion: apps/v1 kind: Deployment metadata: name: front labels: app: handsonk8s spec: replicas: 2 selector: matchLabels: section: front template: metadata: labels: app: handsonk8s section: front spec: containers: - name: front image: joellord/handsonk8s-front:latest ports: - containerPort: 8080 env: - name: WORKING_API_URL value: api ``` ```bash= kubectl apply -f 5.yaml ``` #### Services Tools to expose your pods. Do load balancing. Manage your network. ##### **`6.yaml`** ```yaml= apiVersion: v1 kind: Service metadata: name: front labels: app: handsonk8s spec: selector: section: front # look for any pods with this selector label. If so, applies this service to them ports: - port: 8080 targetPort: 8080 protocol: TCP ``` ```bash= kubectl apply -f 6.yaml kubectl get services kubectl exec -it pod/toolbox -- /bin/bash curl front:8080 kubectl logs -f -l section=front --prefix=true kubectl delete deployment front ``` ### Ingresses Exposes our pods to the outside world. Provide load balancing, SSL termination TODO: what is this? ##### **`7.yaml`** ```yaml= apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: main annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: rules: - http: paths: - path: / pathType: Prefix backend: service: name: front port: number: 8080 ``` ```bash= minikube addons enable ingress kubectl apply -f 7.yaml kubectl get ingresses minikube ip #192.168.49.2 kubectl delete ingresses --all # to delete it ``` ##### **`8.yaml`** ```yaml= apiVersion: apps/v1 kind: Deployment metadata: name: api labels: app: handsonk8s spec: replicas: 1 selector: matchLabels: section: api template: metadata: labels: app: handsonk8s section: api spec: containers: - name: api image: joellord/handsonk8s-api:latest ports: - containerPort: 3000 --- apiVersion: v1 kind: Service metadata: name: api labels: app: handsonk8s spec: selector: section: api ports: - port: 3000 protocol: TCP ``` ```bash= kubectl apply -f 8.yaml ``` ##### **`9.yaml`** ```yaml= apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: main annotations: nginx.ingress.kubernetes.io/rewrite-target: /$2 spec: rules: - http: paths: - path: /api(/|$)(.*) pathType: Prefix backend: service: name: api port: number: 3000 - path: /()(.*) pathType: Prefix backend: service: name: front port: number: 8080 ``` ```bash= kubectl apply -f 9.yaml ``` tools to debug: - kubectl describe - kubectl logs - kubectl describe pods $PODNAME ## Resources: - Discord channel: https://discord.gg/jGbHB3YDkf - Kubernetes docs: https://kubernetes.io - github folder for yaml files: https://github.com/joellord/handson-k8s/tree/master/node #### Platforms we may use - Minikube (https://minikube.sigs.k8s.io) - Using Katacoda: gives you 1 hour of kubernetes cluster (https://katacoda.com/courses/kubernetes) - Red Hat: 14 days developer sandbox (https://developers.redhat.com/developer-sandbox) ## Further Reading - Using Terraform with kubernetes - Can't seem to get ingress to work - TODO: debug