diff --git a/slides/k8s/healthchecks.md b/slides/k8s/healthchecks.md index 2563da68..fafcae8b 100644 --- a/slides/k8s/healthchecks.md +++ b/slides/k8s/healthchecks.md @@ -1,4 +1,4 @@ -# Healthchecks +# Healthchecks (extra material) - Kubernetes provides two kinds of healthchecks: liveness and readiness diff --git a/slides/wek8s/ingress.md b/slides/wek8s/ingress.md new file mode 100644 index 00000000..fd6e24b3 --- /dev/null +++ b/slides/wek8s/ingress.md @@ -0,0 +1,308 @@ +# Exposing HTTP services with Ingress resources + +- *Services* give us a way to access a pod or a set of pods + +- Services can be exposed to the outside world: + + - with type `NodePort` (on a port >30000) + + - with type `LoadBalancer` (allocating an external load balancer) + +- What about HTTP services? + + - how can we expose `webui`, `rng`, `hasher`? + + - the Kubernetes dashboard? + + - a new version of `webui`? + +--- + +## Exposing HTTP services + +- If we use `NodePort` services, clients have to specify port numbers + + (i.e. http://xxxxx:31234 instead of just http://xxxxx) + +- `LoadBalancer` services are nice, but: + + - they are not available in all environments + + - they often carry an additional cost (e.g. they provision an ELB) + + - they require one extra step for DNS integration +
+ (waiting for the `LoadBalancer` to be provisioned; then adding it to DNS) + +--- + +## Ingress resources + +- Kubernetes API resource (`kubectl get ingress`/`ingresses`/`ing`) + +- Designed to expose HTTP services + +- Basic features: + + - load balancing + - SSL termination + - name-based virtual hosting + +- Can also route to different services depending on: + + - URI path (e.g. `/api`→`api-service`, `/static`→`assets-service`) + - Client headers, including cookies (for A/B testing, canary deployment...) + - and more! + +--- + +## Principle of operation + +- Step 1: deploy an *ingress controller* + + - ingress controller = load balancer + control loop + + - the control loop watches over ingress resources, and configures the LB accordingly + +- Step 2: setup DNS + + - associate DNS entries with the load balancer address + +- Step 3: create *ingress resources* + + - the ingress controller picks up these resources and configures the LB + +- Step 4: profit! + +--- + +## Ingress in action + +- We will deploy the Traefik ingress controller + + - this is an arbitrary choice + + - maybe motivated by the fact that Traefik releases are named after cheeses + +- For DNS, we will use [nip.io](http://nip.io/) + + - `*.1.2.3.4.nip.io` resolves to `1.2.3.4` + +- We will create ingress resources for various HTTP services + +--- + +## Running Traefik on our cluster + +- We provide a YAML file (`k8s/traefik.yaml`) which is essentially the sum of: + + - [Traefik's Daemon Set resources](https://github.com/containous/traefik/blob/v1.7/examples/k8s/traefik-ds.yaml) (patched with `hostNetwork` and tolerations) + + - [Traefik's RBAC rules](https://github.com/containous/traefik/blob/v1.7/examples/k8s/traefik-rbac.yaml) allowing it to watch necessary API objects + +.exercise[ + +- Apply the YAML: + ```bash + kubectl apply -f ~/container.training/k8s/traefik.yaml + ``` + +] + +--- + +## Checking that Traefik runs correctly + +- If Traefik started correctly, we now have a web server listening on each node + +.exercise[ + +- Check that Traefik is serving 80/tcp: + ```bash + curl localhost + ``` + +] + +We should get a `404 page not found` error. + +This is normal: we haven't provided any ingress rule yet. + +--- + +## Setting up DNS + +- To make our lives easier, we will use [nip.io](http://nip.io) + +- Check out `http://webui.A.B.C.D.nip.io` + + (replacing A.B.C.D with the IP address of `node1`) + +- We should get the same `404 page not found` error + + (meaning that our DNS is "set up properly", so to speak!) + +--- + +## Traefik web UI + +- Traefik provides a web dashboard + +- With the current install method, it's listening on port 8080 + +.exercise[ + +- Go to `http://node1:8080` (replacing `node1` with its IP address) + + + +] + +--- + +## Ingress with the wek8s generic chart + +- The wek8s generic chart that we used earlier can generate an Ingress for us + +- All we have to do is add a few lines to the YAML file (`values-webui.yaml`) + +- ... And update the Helm release `webui` to use these new values + +.exercise[ + +- Add the following snippet to the `values-webui.yaml` file: + ```yaml + ingress: + enabled: true + hosts: + - webui.`A.B.C.D`.nip.io + ``` + (Where `A.B.C.D` is the IP address of node1, that we used earlier) + +] + +--- + +## Update the Helm release + +- Now, we need to use these new values + +- We will use `helm upgrade` to run the templates and apply them to the cluster + +.exercise[ + +- Update the Helm release: + ```bash + helm upgrade webui wek8s-generic-service --values=values-webui.yaml + ``` + +] + +We should see an Ingress resource appear in the output. + +--- + +## Access the service + +- Go back to the browser tab where we were loading webui.A.B.C.D.nip.io + +- Hit reload ... + +- ... And we should we the web UI for DockerCoins! + +--- + +## What does an Ingress look like? + +- Let's inspect the Ingress generated by the generic service chart! + +.exercise[ + +- Dump the YAML for the Ingress: + ```bash + kubectl get ingress webui-ingress -o yaml + ``` + +] + +--- + +## Creating an Ingress by hand + +If we need to, here is a minimal host-based ingress resource: + +```yaml +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: webui +spec: + rules: + - host: webui.`A.B.C.D`.nip.io + http: + paths: + - path: / + backend: + serviceName: webui + servicePort: 80 + +``` + +--- + +## Using multiple ingress controllers + +- You can have multiple ingress controllers active simultaneously + + (e.g. Traefik and NGINX) + +- You can even have multiple instances of the same controller + + (e.g. one for internal, another for external traffic) + +- The `kubernetes.io/ingress.class` annotation can be used to tell which one to use + +- It's OK if multiple ingress controllers configure the same resource + + (it just means that the service will be accessible through multiple paths) + +--- + +## Using Ingress on wek8s + +- Each wek8s cluster has a wildcard domain mapped to it + +- For instance, phoenix has `*.phoenix.dev.wwrk.co` + +- To be reachable from outside, we must use the ingress class `nginx-external` + +- This is done through an annotation, like this: + +```yaml +ingress: + enabled: true + hosts: + - webui.phoenix.dev.wwrk.co + annotations: + kubernetes.io/ingress.class: nginx-external +``` + +--- + +## Extra goodies + +- The wek8s generic service chart can also provide: + + - TLS + + - HTTP Basic Auth + + - GRPC with HTTP/2 + +- For more details, we can look at: + + - the `values.yaml` file + + - the chart's README + + - the file `templates/ingress.yaml` in the chart diff --git a/slides/wwrk.yml b/slides/wwrk.yml index f162721a..8503339b 100644 --- a/slides/wwrk.yml +++ b/slides/wwrk.yml @@ -88,10 +88,11 @@ chapters: - k8s/kubectlexpose.md - k8s/shippingimages.md - k8s/buildshiprun-dockerhub.md -- - k8s/ourapponkube.md - - k8s/scalingdockercoins.md + - k8s/ourapponkube.md +- - k8s/scalingdockercoins.md - shared/hastyconclusions.md - k8s/daemonset.md + - k8s/namespaces.md - k8s/rollout.md - k8s/setup-k8s.md - wek8s/connecting.md @@ -101,8 +102,7 @@ chapters: - k8s/localkubeconfig.md - k8s/accessinternal.md - wek8s/helm.md - - k8s/namespaces.md - - k8s/ingress.md + - wek8s/ingress.md - k8s/prometheus.md - k8s/volumes.md - k8s/configuration.md