diff --git a/k8s/event-node.yaml b/k8s/event-node.yaml new file mode 100644 index 00000000..354ecf87 --- /dev/null +++ b/k8s/event-node.yaml @@ -0,0 +1,30 @@ +kind: Event +apiVersion: v1 +metadata: + generateName: hello- + labels: + container.training/test: "" + +#eventTime: "2020-07-04T00:00:00.000000Z" +#firstTimestamp: "2020-01-01T00:00:00.000000Z" +#lastTimestamp: "2020-12-31T00:00:00.000000Z" +#count: 42 + +involvedObject: + kind: Node + apiVersion: v1 + name: kind-control-plane + # Note: the uid should be the Node name (not the uid of the Node). + # This might be specific to global objects. + uid: kind-control-plane + +type: Warning +reason: NodeOverheat +message: "Node temperature exceeds critical threshold" +action: Hello +source: + component: thermal-probe + #host: node1 +#reportingComponent: "" +#reportingInstance: "" + diff --git a/k8s/event-pod.yaml b/k8s/event-pod.yaml new file mode 100644 index 00000000..b3532d39 --- /dev/null +++ b/k8s/event-pod.yaml @@ -0,0 +1,36 @@ +kind: Event +apiVersion: v1 +metadata: + # One convention is to use ., + # where the timestamp is taken with a nanosecond + # precision and expressed in hexadecimal. + # Example: web-5dcb957ccc-fjvzc.164689730a36ec3d + name: hello.1234567890 + # The label doesn't serve any purpose, except making + # it easier to identify or delete that specific event. + labels: + container.training/test: "" + +#eventTime: "2020-07-04T00:00:00.000000Z" +#firstTimestamp: "2020-01-01T00:00:00.000000Z" +#lastTimestamp: "2020-12-31T00:00:00.000000Z" +#count: 42 + +involvedObject: + ### These 5 lines should be updated to refer to an object. + ### Make sure to put the correct "uid", because it is what + ### "kubectl describe" is using to gather relevant events. + #apiVersion: v1 + #kind: Pod + #name: magic-bean + #namespace: blue + #uid: 7f28fda8-6ef4-4580-8d87-b55721fcfc30 + +type: Normal +reason: BackupSuccessful +message: "Object successfully dumped to gitops repository" +source: + component: gitops-sync +#reportingComponent: "" +#reportingInstance: "" + diff --git a/slides/k8s/events.md b/slides/k8s/events.md new file mode 100644 index 00000000..48a1a1be --- /dev/null +++ b/slides/k8s/events.md @@ -0,0 +1,152 @@ +# Events + +- Kubernetes has an internal structured log of *events* + +- These events are ordinary resources: + + - we can view them with `kubectl get events` + + - they can be viewed and created through the Kubernetes API + + - they are stored in Kubernetes default database (e.g. etcd) + +- Most components will generate events to let us know what's going on + +- Events can be *related* to other resources + +--- + +## Reading events + +- `kubectl get events` (or `kubectl get ev`) + +- Can use `--watch` + + ⚠️ Looks like `tail -f`, but events aren't necessarily sorted! + +- Can use `--all-namespaces` + +- Cluster events (e.g. related to nodes) are in the `default` namespace + +- Viewing all "non-normal" events: + ```bash + kubectl get ev -A --field-selector=type!=Normal + ``` + + (as of Kubernetes 1.19, `type` can be either `Normal` or `Warning`) + +--- + +## Reading events (take 2) + +- When we use `kubectl describe` on an object, `kubectl` retrieves the associated events + +.exercise[ + +- See the API requests happening when we use `kubectl describe`: + ```bash + kubectl describe service kubernetes --namespace=default -v6 >/dev/null + ``` + +] + +--- + +## Generating events + +- This is rarely (if ever) done manually + + (i.e. by crafting some YAML) + +- But controllers (e.g. operators) need this! + +- It's not mandatory, but it helps with *operability* + + (e.g. when we `kubectl describe` a CRD, we will see associated events) + +--- + +## ⚠️ Work in progress + +- "Events" can be : + + - "old-style" events (in core API group, aka `v1`) + + - "new-style" events (in API group `events.k8s.io`) + +- See [KEP 383](https://github.com/kubernetes/enhancements/blob/master/keps/sig-instrumentation/383-new-event-api-ga-graduation/README.md) in particular this [comparison between old and new APIs](https://github.com/kubernetes/enhancements/blob/master/keps/sig-instrumentation/383-new-event-api-ga-graduation/README.md#comparison-between-old-and-new-apis) + +--- + +## Experimenting with events + +- Let's create an event related to a Node, based on @@LINK[k8s/event-node.yaml] + +.exercise[ + +- Edit `k8s/event-node.yaml` + +- Update the `name` and `uid` of the `involvedObject` + +- Create the event with `kubectl create -f` + +- Look at the Node with `kubectl describe` + +] + +--- + +## Experimenting with events + +- Let's create an event related to a Pod, based on @@LINK[k8s/event-pod.yaml] + +.exercise[ + +- Create a pod + +- Edit `k8s/event-pod.yaml` + +- Edit the `involvedObject` section (don't forget the `uid`) + +- Create the event with `kubectl create -f` + +- Look at the Pod with `kubectl describe` + +] + +--- + +## Generating events in practice + +- In Go, use an `EventRecorder` provided by the `kubernetes/client-go` library + + - [EventRecorder interface](https://github.com/kubernetes/client-go/blob/release-1.19/tools/record/event.go#L87) + + - [kubebuilder book example](https://book-v1.book.kubebuilder.io/beyond_basics/creating_events.html) + +- It will take care of formatting / aggregating events + +- To get an idea of what to put in the `reason` field, check [kubelet events]( +https://github.com/kubernetes/kubernetes/blob/release-1.19/pkg/kubelet/events/event.go) + +--- + +## Cluster operator perspective + +- Events are kept 1 hour by default + +- This can be changed with the `--event-ttl` flag on the API server + +- On very busy clusters, events can be kept on a separate etcd cluster + +- This is done with the `--etcd-servers-overrides` flag on the API server + +- Example: + ``` + --etcd-servers-overrides=/events#http://127.0.0.1:12379 + ``` + +??? + +:EN:- Consuming and generating cluster events +:FR:- Suivre l'activité du cluster avec les *events* diff --git a/slides/kube-adv.yml b/slides/kube-adv.yml new file mode 100644 index 00000000..1f668d8c --- /dev/null +++ b/slides/kube-adv.yml @@ -0,0 +1,80 @@ +title: | + Advanced + Kubernetes + +chat: "[Slack](https://dockercommunity.slack.com/messages/C7GKACWDV)" +#chat: "[Gitter](https://gitter.im/jpetazzo/workshop-yyyymmdd-city)" + +gitrepo: github.com/jpetazzo/container.training + +slides: https://container.training/ + +#slidenumberprefix: "#SomeHashTag — " + +exclude: +- self-paced + +content: +- shared/title.md +- logistics.md +- k8s/intro.md +- shared/about-slides.md +#- shared/chat-room-im.md +#- shared/chat-room-zoom-meeting.md +#- shared/chat-room-zoom-webinar.md +- shared/toc.md +- #1 + - k8s/prereqs-admin.md + - k8s/architecture.md + - k8s/deploymentslideshow.md + - k8s/dmuc.md +- #2 + - k8s/multinode.md + - k8s/cni.md + - k8s/interco.md +- #3 + - k8s/apilb.md + - k8s/control-plane-auth.md + #- k8s/setup-overview.md + #- k8s/setup-devel.md + #- k8s/setup-managed.md + #- k8s/setup-selfhosted.md + - k8s/staticpods.md + - k8s/cluster-upgrade.md + #- k8s/cluster-backup.md + #- k8s/cloud-controller-manager.md + #- k8s/healthchecks.md + #- k8s/healthchecks-more.md + ###- k8s/bootstrap.md +- #4 + - k8s/extending-api.md + - k8s/operators.md + - k8s/sealed-secrets.md +- #5 + - k8s/ingress-tls.md + - k8s/cert-manager.md + - k8s/eck.md +- #6 + - k8s/admission.md + - k8s/kyverno.md + - k8s/crd.md + - k8s/apiserver-deepdive.md +- #7 + - k8s/metrics-server.md + - k8s/prometheus.md + - k8s/hpa-v2.md +- #8 + - k8s/operators-design.md + - k8s/kubebuilder.md + - k8s/events.md + - k8s/finalizers.md + - k8s/owners-and-dependents.md + - k8s/record.md +- #9 + - k8s/kustomize.md + - k8s/helm-intro.md + - k8s/helm-chart-format.md + - k8s/helm-create-basic-chart.md + #- k8s/helm-create-better-chart.md + - k8s/helm-secrets.md + - shared/thankyou.md