Tweaks after Caen

This commit is contained in:
Jerome Petazzoni
2020-01-30 14:44:44 -06:00
parent e2f3034a96
commit ed5009c769
7 changed files with 189 additions and 63 deletions

View File

@@ -13,7 +13,7 @@ spec:
mountPath: /usr/share/nginx/html/
- name: git
image: alpine
command: [ "sh", "-c", "apk add --no-cache git && git clone https://github.com/octocat/Spoon-Knife /www" ]
command: [ "sh", "-c", "apk add git && git clone https://github.com/octocat/Spoon-Knife /www" ]
volumeMounts:
- name: www
mountPath: /www/

View File

@@ -10,6 +10,29 @@
---
## What can we do with Kubernetes?
- Let's imagine that we have a 3-tier e-commerce app:
- web frontend
- API backend
- database (that we will keep out of Kubernetes for now)
- We have built images for our frontend and backend components
(e.g. with Dockerfiles and `docker build`)
- We are running them successfully with a local environment
(e.g. with Docker Compose)
- Let's see how we would deploy our app on Kubernetes!
---
## Basic things we can ask Kubernetes to do
--

View File

@@ -427,7 +427,7 @@ class: extra-details
- We need to change the selector of the `rng` service!
- Let's add another label to that selector (e.g. `enabled=yes`)
- Let's add another label to that selector (e.g. `active=yes`)
---
@@ -445,11 +445,11 @@ class: extra-details
## The plan
1. Add the label `enabled=yes` to all our `rng` pods
1. Add the label `active=yes` to all our `rng` pods
2. Update the selector for the `rng` service to also include `enabled=yes`
2. Update the selector for the `rng` service to also include `active=yes`
3. Toggle traffic to a pod by manually adding/removing the `enabled` label
3. Toggle traffic to a pod by manually adding/removing the `active` label
4. Profit!
@@ -464,7 +464,7 @@ be any interruption.*
## Adding labels to pods
- We want to add the label `enabled=yes` to all pods that have `app=rng`
- We want to add the label `active=yes` to all pods that have `app=rng`
- We could edit each pod one by one with `kubectl edit` ...
@@ -474,9 +474,9 @@ be any interruption.*
.exercise[
- Add `enabled=yes` to all pods that have `app=rng`:
- Add `active=yes` to all pods that have `app=rng`:
```bash
kubectl label pods -l app=rng enabled=yes
kubectl label pods -l app=rng active=yes
```
]
@@ -495,7 +495,7 @@ be any interruption.*
.exercise[
- Update the service to add `enabled: yes` to its selector:
- Update the service to add `active: yes` to its selector:
```bash
kubectl edit service rng
```
@@ -504,7 +504,7 @@ be any interruption.*
```wait Please edit the object below```
```keys /app: rng```
```key ^J```
```keys noenabled: yes```
```keys noactive: yes```
```key ^[``` ]
```keys :wq```
```key ^J```
@@ -530,7 +530,7 @@ be any interruption.*
- If we want the string `"42"` or the string `"yes"`, we have to quote them
- So we have to use `enabled: "yes"`
- So we have to use `active: "yes"`
.footnote[For a good laugh: if we had used "ja", "oui", "si" ... as the value, it would have worked!]
@@ -542,7 +542,7 @@ be any interruption.*
- Update the YAML manifest of the service
- Add `enabled: "yes"` to its selector
- Add `active: "yes"` to its selector
<!--
```wait Please edit the object below```
@@ -566,7 +566,7 @@ If we did everything correctly, the web UI shouldn't show any change.
- We want to disable the pod that was created by the deployment
- All we have to do, is remove the `enabled` label from that pod
- All we have to do, is remove the `active` label from that pod
- To identify that pod, we can use its name
@@ -600,7 +600,7 @@ If we did everything correctly, the web UI shouldn't show any change.
- In another window, remove the label from the pod:
```bash
kubectl label pod -l app=rng,pod-template-hash enabled-
kubectl label pod -l app=rng,pod-template-hash active-
```
(The stream of HTTP logs should stop immediately)
@@ -623,7 +623,7 @@ class: extra-details
- If we scale up our cluster by adding new nodes, the daemon set will create more pods
- These pods won't have the `enabled=yes` label
- These pods won't have the `active=yes` label
- If we want these pods to have that label, we need to edit the daemon set spec

View File

@@ -120,19 +120,13 @@
- We want our ingress load balancer to be available on port 80
- We could do that with a `LoadBalancer` service
- The best way to do that would be with a `LoadBalancer` service
... but it requires support from the underlying infrastructure
- We could use pods specifying `hostPort: 80`
- Instead, we are going to use the `hostNetwork` mode on the Traefik pods
... but with most CNI plugins, this [doesn't work or requires additional setup](https://github.com/kubernetes/kubernetes/issues/23920)
- We could use a `NodePort` service
... but that requires [changing the `--service-node-port-range` flag in the API server](https://kubernetes.io/docs/reference/command-line-tools-reference/kube-apiserver/)
- Last resort: the `hostNetwork` mode
- Let's see what this `hostNetwork` mode is about ...
---
@@ -170,6 +164,26 @@
---
class: extra-details
## Other techniques to expose port 80
- We could use pods specifying `hostPort: 80`
... but with most CNI plugins, this [doesn't work or requires additional setup](https://github.com/kubernetes/kubernetes/issues/23920)
- We could use a `NodePort` service
... but that requires [changing the `--service-node-port-range` flag in the API server](https://kubernetes.io/docs/reference/command-line-tools-reference/kube-apiserver/)
- We could create a service with an external IP
... this would work, but would require a few extra steps
(figuring out the IP address and adding it to the service)
---
## Running Traefik
- The [Traefik documentation](https://docs.traefik.io/user-guide/kubernetes/#deploy-trfik-using-a-deployment-or-daemonset) tells us to pick between Deployment and Daemon Set

View File

@@ -1,20 +1,76 @@
# Exposing containers
- `kubectl expose` creates a *service* for existing pods
- We can connect to our pods using their IP address
- A *service* is a stable address for a pod (or a bunch of pods)
- Then we need to figure out a lot of thigns:
- If we want to connect to our pod(s), we need to create a *service*
- how do we look up the IP address of the pod(s)?
- Once a service is created, CoreDNS will allow us to resolve it by name
- how do we connect from outside the cluster?
(i.e. after creating service `hello`, the name `hello` will resolve to something)
- how do we load balance traffic?
- There are different types of services, detailed on the following slides:
- what if a pod fails?
- Kubernetes has a resource type named *Service*
- Services address all these questions!
---
## Services in a nutshell
- Services give us a *stable endpoint* to connect to a pod or a group of pods
- An easy way to create a service is to use `kubectl expose`
- If we have a deployment named `my-little-deploy`, we can run:
`kubectl expose deployment my-little-deploy --port=80`
... and this will create a service with the same name (`my-little-deploy`)
- Services are automatically added to an internal DNS zone
(in the example above, our code can now connect to http://my-little-deploy/)
---
## Advantages of services
- We don't need to look up the IP address of the pod(s)
(we resolve the IP address of the service using DNS)
- There are multiple service types; some of them allow external traffic
(e.g. `LoadBalancer` and `NodePort`)
- Services provide load balancing
(for both internal and external traffic)
- Service addresses are independent from pods' addresses
(when a pod fails, the service seamlessly sends traffic to its replacement)
---
## Many kinds and flavors of service
- There are different types of services:
`ClusterIP`, `NodePort`, `LoadBalancer`, `ExternalName`
- HTTP services can also use `Ingress` resources (more on that later)
- There are also *headless services*
- Services can also have optional *external IPs*
- There is also another resource type called *Ingress*
(specifically for HTTP services)
- Wow, that's a lot! Let's start with the basics ...
---
@@ -73,24 +129,6 @@
---
class: extra-details
## `ExternalName`
- No load balancer (internal or external) is created
- Only a DNS entry gets added to the DNS managed by Kubernetes
- That DNS entry will just be a `CNAME` to a provided record
Example:
```bash
kubectl create service externalname k8s --external-name kubernetes.io
```
*Creates a CNAME `k8s` pointing to `kubernetes.io`*
---
## Running containers with open ports
- Since `ping` doesn't have anything to connect to, we'll have to run something else
@@ -175,9 +213,7 @@ kubectl create service externalname k8s --external-name kubernetes.io
- As a result: you *have to* indicate the port number for your service
- Running services with arbitrary port (or port ranges) requires hacks
(e.g. host networking mode)
(with some exceptions, like `ExternalName` or headless services, covered later)
---
@@ -218,7 +254,48 @@ Try it a few times! Our requests are load balanced across multiple pods.
class: extra-details
## If we don't need a load balancer
## `ExternalName`
- Services of type `ExternalName` are quite different
- No load balancer (internal or external) is created
- Only a DNS entry gets added to the DNS managed by Kubernetes
- That DNS entry will just be a `CNAME` to a provided record
Example:
```bash
kubectl create service externalname k8s --external-name kubernetes.io
```
*Creates a CNAME `k8s` pointing to `kubernetes.io`*
---
class: extra-details
## External IPs
- We can add an External IP to a service, e.g.:
```bash
kubectl expose deploy my-little-deploy --port=80 --external-ip=1.2.3.4
```
- `1.2.3.4` should be the address of one of our nodes
(it could also be a virtual address, service address, or VIP, shared by multiple nodes)
- Connections to `1.2.3.4:80` will be sent to our service
- External IPs will also show up on services of type `LoadBalancer`
(they will be added automatically by the process provisioning the load balancer)
---
class: extra-details
## Headless services
- Sometimes, we want to access our scaled services directly:
@@ -238,7 +315,7 @@ class: extra-details
class: extra-details
## Headless services
## Creating a headless services
- A headless service is obtained by setting the `clusterIP` field to `None`
@@ -324,18 +401,32 @@ error: the server doesn't have a resource type "endpoint"
class: extra-details
## `ExternalIP`
## The DNS zone
- When creating a servivce, we can also specify an `ExternalIP`
- In the `kube-system` namespace, there should be a service named `kube-dns`
(this is not a type, but an extra attribute to the service)
- This is the internal DNS server that can resolve service names
- It will make the service availableon this IP address
- The default domain name for the service we created is `default.svc.cluster.local`
(if the IP address belongs to a node of the cluster)
.exercise[
- Get the IP address of the internal DNS server:
```bash
IP=$(kubectl -n kube-system get svc kube-dns -o jsonpath={.spec.clusterIP})
```
- Resolve the cluster IP for the `httpenv` service:
```bash
host httpenv.default.svc.cluster.local $IP
```
]
---
class: extra-details
## `Ingress`
- Ingresses are another type (kind) of resource

View File

@@ -102,8 +102,6 @@
]
- Some tools like Helm will create namespaces automatically when needed
---
## Using namespaces

View File

@@ -50,7 +50,7 @@ class: extra-details
- *Volumes*:
- appear in Pod specifications (see next slide)
- appear in Pod specifications (we'll see that in a few slides)
- do not exist as API resources (**cannot** do `kubectl get volumes`)
@@ -232,7 +232,7 @@ spec:
mountPath: /usr/share/nginx/html/
- name: git
image: alpine
command: [ "sh", "-c", "apk add --no-cache git && git clone https://github.com/octocat/Spoon-Knife /www" ]
command: [ "sh", "-c", "apk add git && git clone https://github.com/octocat/Spoon-Knife /www" ]
volumeMounts:
- name: www
mountPath: /www/