|
1 | 1 | = Listener
|
2 | 2 | :description: The Listener exposes Pods based on ListenerClass rules, provides address info via Ingress_addresses, supports PVC mounting, and enables sticky scheduling.
|
3 | 3 |
|
4 |
| -A Listener object exposes a set of Pods according to the rules of a xref:listenerclass.adoc[], but it also adds a couple of other features that are useful for the Stackable data platform at large. |
| 4 | +:fn-kubernetes-service: footnote:[It is actually implemented using them, but don't rely on that.] |
5 | 5 |
|
6 |
| -== ListenerClass |
| 6 | +A Listener object represents a single exposed (possibly) load-balanced service that clients can connect to. |
| 7 | +It can be thought of as the Stackable Data Platform equivalent of a Kubernetes https://kubernetes.io/docs/concepts/services-networking/service/[Service,window=_blank].{fn-kubernetes-service} |
7 | 8 |
|
8 |
| -The exact rules of pod exposure are dictated by the specified xref:listenerclass.adoc[], which allow a single Listener definition to be reused in different clusters, regardless of the Kubernetes distribution or cloud provider. |
| 9 | +The mechanism for the service is controlled by the xref:listenerclass.adoc[]. |
| 10 | +This way, a single Listener definition can be reused in different clusters, expressing the same _intent_ regardless of the Kubernetes distribution or cloud provider's limitations. |
9 | 11 |
|
10 |
| -== Address API |
| 12 | +Listeners only direct traffic to Pods that also mount them as a xref:volume.adoc[volume]. |
| 13 | +The volume allows the operator to xref:#pinning[pin] the Pod to a specific Node, and provides an API for workloads to retrieve their external address. |
11 | 14 |
|
12 |
| -A Listener writes back all addresses that it can be reached on to `Listener.status.ingress_addresses`, which can then be used to generate discovery information. |
13 |
| -Contrary to Kubernetes' Service, this is done regardless of the type of service, and transparently also contains information about remapped ports. |
| 15 | +[#address-api] |
| 16 | +== Address API |
14 | 17 |
|
15 |
| -== Address volume projection |
| 18 | +NOTE: The CRD-based API is intended for external clients that need to retrieve the address. |
| 19 | + The workload can retrieve _its own_ address(es) by using the xref:volume.adoc#downwards-api[downwards API]. |
16 | 20 |
|
17 |
| -Listener objects can be mounted into a Pod as a PersistentVolumeClaim (PVC), which contains information about how the Pod should request that external clients refer to it. |
| 21 | +A Listener writes back all addresses that it can be reached on to `Listener.status.ingressAddresses`, which can then be used to connect to the service (generate discovery information). |
| 22 | +Compared to Kubernetes' Services, this list is provided _regardless_ of the type of the backing Service. |
18 | 23 |
|
19 |
| -For example, if the volume is mounted to `/stackable/listener`, the primary address can be read from `/stackable/listener/default-address/address`, and the public `http` port number can be read from `/stackable/listener/default-address/ports/http`. |
| 24 | +Ports may be remapped from the Service definition. |
| 25 | +Never assume that the exposed port on an address will match your declared port. |
| 26 | +Instead, read the port numbers from `.ports.\{portname\}`. |
| 27 | +Otherwise, it will break when using NodePort services. |
20 | 28 |
|
21 | 29 | == Per-replica listeners
|
22 | 30 |
|
23 |
| -A Listener PVC can also specify a xref:listenerclass.adoc[] rather than a Listener, in which case a Listener object is created automatically. |
24 |
| -These PVCs can automatically be created for each replica using either StatefulSet's `volumeClaimTemplates` (for long-lived listeners that will be kept across replica restarts and upgrades) or Pod's `volumes[].ephemeral` (for temporary listeners that are deleted when their corresponding Pod is deleted). |
| 31 | +A Listener volume can also specify a xref:listenerclass.adoc[] rather than a Listener, in which case a Listener object is created automatically for each volume. |
| 32 | + |
| 33 | +These volumes, in turn, can automatically be created for each replica using either: |
| 34 | + |
| 35 | +- StatefulSet's `volumeClaimTemplates` (for long-lived listeners that will be kept across replica restarts and upgrades), or |
| 36 | +- Pod's `volumes[].ephemeral` (for temporary listeners that are deleted when their corresponding Pod is deleted) |
| 37 | + |
| 38 | +[#pinning] |
| 39 | +== Pinning |
| 40 | + |
| 41 | +When mounting a Listener volume, it will be "pinned" to that node if the xref:listenerclass.adoc[] uses a strategy that depends on the node that the workload is running on. |
| 42 | + |
| 43 | +Keep in mind that this will only work correctly when using long-lived volumes (such as via StatefulSet's `volumeClaimTemplates`). |
| 44 | +Ephemeral volumes will be "reset" for every pod that is created, even if they refer to a long-lived Listener object. |
25 | 45 |
|
26 |
| -== Sticky scheduling |
| 46 | +[#reference] |
| 47 | +== Reference |
27 | 48 |
|
28 |
| -When mounting a Listener PVC, it will be made "sticky" to that node if the xref:listenerclass.adoc[] uses a strategy that depends on the node that the workload is running on. |
| 49 | +[source,yaml] |
| 50 | +---- |
| 51 | +apiVersion: listeners.stackable.tech/v1alpha1 |
| 52 | +kind: Listener |
| 53 | +metadata: |
| 54 | + name: my-listener |
| 55 | +spec: |
| 56 | + className: external-unstable |
| 57 | + ports: |
| 58 | + - name: http |
| 59 | + port: 9864 |
| 60 | + protocol: TCP |
| 61 | + extraPodSelectorLabels: |
| 62 | + foo: bar |
| 63 | + publishNotReadyAddresses: true |
| 64 | +status: |
| 65 | + ingressAddresses: |
| 66 | + - address: 172.18.0.3 |
| 67 | + addressType: IP |
| 68 | + ports: |
| 69 | + http: 32222 |
| 70 | + nodePorts: |
| 71 | + http: 32222 |
| 72 | + serviceName: my-listener |
| 73 | +---- |
29 | 74 |
|
30 |
| -Keep in mind that this will only work correctly when using long-lived PVCs (such as via StatefulSet's `volumeClaimTemplates`). |
31 |
| -Ephemeral PVCs will be "reset" for every pod that is created, even if they refer to a long-lived Listener object. |
| 75 | +`spec.className`:: The name of the xref:listenerclass.adoc[] to use. |
| 76 | +`spec.ports`:: The ports exposed from the backing Pods. |
| 77 | +`spec.ports.name`:: The name of the port. |
| 78 | +`spec.ports.port`:: The number of the port. |
| 79 | + This must match the port number exposed by the container. |
| 80 | +`spec.ports.protocol`:: The IP protocol (TCP/UDP/SCTP). |
| 81 | + Defaults to TCP. |
| 82 | +`spec.extraPodSelectorLabels`:: Traffic will only be forwarded to Pods that apply these labels. |
| 83 | + This field exists for exceptional cases, where Pods sometimes want to stop receiving traffic based on some dynamic condition. |
| 84 | + Normal target selection should use xref:volume.adoc[Listener volumes] instead. |
| 85 | + (Volumes are still required when using `extraPodSelectorLabels`.) |
| 86 | +`spec.publishNotReadyAddresses`:: If false, traffic will only be directed to Pods that are Ready. |
| 87 | + If true, traffic will be directed to any running Pod. Defaults to true. |
| 88 | +`status.ingressAddresses`:: A list of all addresses that the Listener can be reached on. |
| 89 | + See xref:#address-api[]. |
| 90 | +`status.ingressAddresses.address`:: The hostname or IP address of this Listener. |
| 91 | +`status.ingressAddresses.addressType`:: `IP` if `address` is an IP address, `Hostname` if it is a hostname. |
| 92 | +`status.ingressAddresses.ports.\{portName\}`:: The _exposed_ port number for a given port name (as defined in `.spec.ports`). |
| 93 | + Note that this may be different than the port specified in `.spec.ports.port``. |
| 94 | +`status.nodePorts.\{portName\}`:: For internal use only. |
| 95 | + You probably want to use `.status.ingressAddresses` instead. |
| 96 | + _If_ the ListenerClass is configured to use xref:listenerclass.adoc#servicetype-nodeport[NodePort] then this is the port number that each port is accessible on on its respective Node. |
| 97 | +`status.serviceName`:: The name of the Kubernetes Service object backing this Listener. |
0 commit comments