--- tags: k8s-fundamentals --- # Deploying application to K8S ## Goals * Create a sample cowsay web app * Using buildpacks to build the app image and push to docker hub * Create a kind cluster where the app is deployed to * Deploy Contour as the Ingress controller ## Create a golang simple web app https://github.com/danniel1205/sample-cowsay-web-app ## Build the application image by using buildpack ### Install buildpack on Mac OS https://buildpacks.io/docs/app-journey/ ``` brew tap buildpack/tap brew install pack ``` ### Build the app image ``` cd $GOPATH/src git clone https://github.com/danniel1205/sample-cowsay-web-app.git pack build -B --builder gcr.io/paketo-buildpacks/builder:tiny danielguo/cowsay-web-app:latest --publish ``` Builder: https://github.com/paketo-buildpacks/builder ## Deploy the application to K8S ### Start a kind cluster ``` kind create cluster --image kindest/node:v1.18.0 --config ./kind.yaml ``` ``` # kind.yaml kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 nodes: - role: control-plane kubeadmConfigPatches: - | kind: InitConfiguration nodeRegistration: kubeletExtraArgs: node-labels: "ingress-ready=true" authorization-mode: "AlwaysAllow" extraPortMappings: - containerPort: 80 hostPort: 80 protocol: TCP - containerPort: 443 hostPort: 443 protocol: TCP - role: worker - role: worker - role: worker ``` ### Create a Deployment/Service * kubectl apply -f the following two yaml files ``` apiVersion: apps/v1 kind: Deployment metadata: creationTimestamp: null labels: app: cowsay name: cowsay spec: replicas: 1 selector: matchLabels: app: cowsay strategy: {} template: metadata: creationTimestamp: null labels: app: cowsay spec: containers: - image: danielguo/cowsay-web-app imagePullPolicy: IfNotPresent name: cowsay-web-app resources: {} status: {} ``` ``` apiVersion: v1 kind: Service metadata: creationTimestamp: null labels: app: cowsay name: cowsay spec: ports: - port: 1323 selector: app: cowsay status: loadBalancer: {} ``` * `kubectl port-forward service/cowsay 8081:1323` * Access to the web app on borwser: `localhost:8081` ## (Optional) Deploy Contour The reason of deploying Contour is to get rid of doing port-forwarding * Install Contour ``` kubectl apply -f https://projectcontour.io/quickstart/contour.yaml ``` * Apply kind specific patches to forward the hostPorts to the ingress controller, set taint tolerations and schedule it to the custom labelled node. ``` kubectl patch daemonsets -n projectcontour envoy -p '{"spec":{"template":{"spec":{"nodeSelector":{"ingress-ready":"true"},"tolerations":[{"key":"node-role.kubernetes.io/master","operator":"Equal","effect":"NoSchedule"}]}}}}' ``` * Create HttpProxy ``` apiVersion: projectcontour.io/v1 kind: HTTPProxy metadata: name: cowsay spec: virtualhost: fqdn: local.daniel.io routes: - services: - name: cowsay port: 1323 conditions: - prefix: / ``` **Note:** * You might want to add `127.0.0.1 local.daniel.io` to your `/etc/hosts` to make the fqnd work Now you should be able to access the cowsay web service by `curl http://local.daniel.io/` ## (Optional) Create TLS for HttpProxy * Create self signed TLS cert ``` openssl req -x509 -newkey rsa:4096 -sha256 -nodes -keyout tls.key -out tls.crt -subj "/CN=local.daniel.io" -days 5 ``` **Note:** The CN should match the one you specified for your fqdn * Create k8s secret ``` kubectl create secret tls local-daniel-io-tls --cert=tls.crt --key=tls.key ``` * Add the secret in your HttpProxy spec https://github.com/projectcontour/contour/blob/master/apis/projectcontour/v1/httpproxy.go ``` apiVersion: projectcontour.io/v1 kind: HTTPProxy metadata: name: cowsay spec: virtualhost: fqdn: local.daniel.io tls: secretName: local-daniel-io-tls routes: - services: - name: cowsay-blue port: 1323 conditions: - prefix: / ``` kubectl apply above changes. Then you should be able to access `https://local.daniel.io` ## References https://github.com/bryanl/websay https://echo.labstack.com/guide https://github.com/Code-Hex/Neo-cowsay https://paketo.io/docs/getting-started/build-your-application/ https://kind.sigs.k8s.io/docs/user/ingress/ https://projectcontour.io/docs/v1.4.0/httpproxy/