diff --git a/k8s/k8s.md b/k8s/k8s.md index 5710927..6cf9972 100644 --- a/k8s/k8s.md +++ b/k8s/k8s.md @@ -273,6 +273,38 @@ common properties found on all config objects are the `apiVersion` and `kind` fields, these tell kubernetes what kind the object is, and therefore how to parse the rest of the object. +## The structure of a k8s object + +A simple k8s object defined in yaml will usually look like this: + + apiVersion: v1 + kind: + metadata: + name: + namespace: + annotations: + + labels: + + spec: + + +The `apiVersion` and `kind` fields are always present, and tells k8s +what kind of object this is, which will determine what its `spec` +should look like, which contains the actual configuration itself. + +The `metadata` section contains metadata about the object, such as its +name and namespace. A few kinds of objects can exist without a +namespace, and are cluster wide, but in general all objects will exist +in a namespace. + +The `annotations` and `labels` sections in `metadata` are optional, +and are used by other k8s components to modify how the object should +be handled. This could be things like setting an annotation specifying +a service should only be reachable from a certain range of ips, or +setting a label to identify a group of pods as part of the same +application, so they can all be referenced together. + ## The built in object kinds The built in kubernetes objects will usually be found in `apiVersion: @@ -280,6 +312,18 @@ v1`, or `apiVersion: apps/v1` while other components will usually version their objects prefixed with their name, like `apiVersion: cert-manager.io/v1` for cert-manager objects. +### Namespace + +A namespace is a config object for managing other config objects, it +will group other config objects together, so they are easier to reason +about. + +When you first create a new cluster, you will most likely have 1 or 2 +namespaces to start with: `default` and `kube-system`. If you are +using a cloud-based cluster provider, you might not have access to the +`kube-system` namespace, as it is used for kubernetes components, and +not your own services. + ### Pod A pod is the most basic container building block in k8s. A pod @@ -316,9 +360,9 @@ the web app through the service ip and port, instead of having to choose one of the pods manually. There are different types of service objects, for different methods of -exposing the underlying service: +exposing the underlying service. -#### ClusterIP: +#### type: ClusterIP: This is the default kind of service. It exposes the underlying port on a cluster internal IP, which means it will only be accessible inside @@ -326,7 +370,7 @@ your cluster. This is useful for internal only services like databases, caches or background services which do not need to be exposed to the outside world. -#### NodePort: +#### type: NodePort: NodePort binds a port to an available port on every node. The available ports are specified in a range in the cluster configuration, @@ -339,7 +383,7 @@ range, or not create the port. NodePorts are useful for when you need to export a service to the outside world, but it doesn't need to be a specific port. -#### Load Balancer: +#### type: Load Balancer: Load Balancer services uses your cluster load balancer to create a new external ip and bind the service port to it. @@ -350,4 +394,29 @@ ways, so consult the documentation for your selected load balancer. This is usually the way you will expose services that require specific port to the outside world, like http services, mail, dns, irc, etc. +Usually Load Balancers will always use a new external IP, however some +let you configure re-use of IP addresses if the ports are free. +For example, [KlipperLB](https://github.com/k3s-io/klipper-lb) from +k3s will always use the nodes external IP, like a NodePort, and will +create pods on every node to redirect traffic to the correct node if +it enters to the wrong one. + +Or MetalLB, which lets you tag Load Balancer services with a key, and +every other Load Balancer service sharing the same key can share the +same external IP as long as the ports don't collide. +[Doc Link](https://metallb.universe.tf/usage/#ip-address-sharing). + +#### Service DNS + +In addition to exposing the service with an IP and ports, k8s Services +also creates an entry in the cluster dns server, so you can adress +them by name instead of ip, as the IP may change over time. + +This will be in the form: `..svc.cluster.local`, so if your service is called `my-webapp`, +and is in the namespace `default`, the dns name will be: +`my-webapp.default.svc.cluster.local`. + + +For a much more in-depth explanation of services, consult the [official kubernetes docs](https://kubernetes.io/docs/concepts/services-networking/service/).