From aba5706f2c170e46138bf3405c163ad0e275101e Mon Sep 17 00:00:00 2001 From: Mike McKiernan Date: Thu, 15 Jul 2021 15:28:05 -0400 Subject: [PATCH] OSDOCS-2174: MetalLB Operator and load balancer * Mohamed clarified that the namespace doesn't matter. * Add the 10s typical client fail over duration. fix: ipv4 or ipv6 with dual-stack Remove the IP failover procedure. That is covered in the IP failover section. Feedback from Arti. Review from Samantha. --- _topic_map.yml | 11 ++ images/nw-metallb-layer2.png | Bin 0 -> 107304 bytes modules/nw-metallb-addresspool-cr.adoc | 69 ++++++++ .../nw-metallb-configure-address-pool.adoc | 66 +++++++ modules/nw-metallb-configure-svc.adoc | 72 ++++++++ modules/nw-metallb-example-addresspool.adoc | 61 +++++++ modules/nw-metallb-infra-considerations.adoc | 16 ++ .../nw-metallb-installing-operator-cli.adoc | 126 ++++++++++++++ .../nw-metallb-layer2-extern-traffic-pol.adoc | 21 +++ modules/nw-metallb-layer2-limitations.adoc | 31 ++++ modules/nw-metallb-layer2.adoc | 42 +++++ .../nw-metallb-operator-custom-resources.adoc | 20 +++ .../nw-metallb-operator-initial-config.adoc | 61 +++++++ modules/nw-metallb-software-components.adoc | 25 +++ modules/nw-metallb-when-metallb.adoc | 8 + ...ng-from-operatorhub-using-web-console.adoc | 3 +- .../overview-traffic.adoc | 27 +++ networking/metallb/about-metallb.adoc | 65 +++++++ networking/metallb/images | 1 + .../metallb-configure-address-pools.adoc | 23 +++ .../metallb/metallb-configure-services.adoc | 162 ++++++++++++++++++ .../metallb/metallb-operator-install.adoc | 32 ++++ networking/metallb/modules | 1 + 23 files changed, 942 insertions(+), 1 deletion(-) create mode 100644 images/nw-metallb-layer2.png create mode 100644 modules/nw-metallb-addresspool-cr.adoc create mode 100644 modules/nw-metallb-configure-address-pool.adoc create mode 100644 modules/nw-metallb-configure-svc.adoc create mode 100644 modules/nw-metallb-example-addresspool.adoc create mode 100644 modules/nw-metallb-infra-considerations.adoc create mode 100644 modules/nw-metallb-installing-operator-cli.adoc create mode 100644 modules/nw-metallb-layer2-extern-traffic-pol.adoc create mode 100644 modules/nw-metallb-layer2-limitations.adoc create mode 100644 modules/nw-metallb-layer2.adoc create mode 100644 modules/nw-metallb-operator-custom-resources.adoc create mode 100644 modules/nw-metallb-operator-initial-config.adoc create mode 100644 modules/nw-metallb-software-components.adoc create mode 100644 modules/nw-metallb-when-metallb.adoc create mode 100644 networking/metallb/about-metallb.adoc create mode 120000 networking/metallb/images create mode 100644 networking/metallb/metallb-configure-address-pools.adoc create mode 100644 networking/metallb/metallb-configure-services.adoc create mode 100644 networking/metallb/metallb-operator-install.adoc create mode 120000 networking/metallb/modules diff --git a/_topic_map.yml b/_topic_map.yml index 525b5fc2ab..5b4e8352b5 100644 --- a/_topic_map.yml +++ b/_topic_map.yml @@ -1078,6 +1078,17 @@ Topics: Distros: openshift-enterprise,openshift-origin - Name: Load balancing on OpenStack File: load-balancing-openstack +- Name: Load balancing with MetalLB + Dir: metallb + Topics: + - Name: About MetalLB and the MetalLB Operator + File: about-metallb + - Name: Installing the MetalLB Operator + File: metallb-operator-install + - Name: Configuring MetalLB address pools + File: metallb-configure-address-pools + - Name: Configuring services to use MetalLB + File: metallb-configure-services - Name: Associating secondary interfaces metrics to network attachments File: associating-secondary-interfaces-metrics-to-network-attachments --- diff --git a/images/nw-metallb-layer2.png b/images/nw-metallb-layer2.png new file mode 100644 index 0000000000000000000000000000000000000000..3cc343622e1770ad6c935bffe62e07e2c851ce2e GIT binary patch literal 107304 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 z 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�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 <.> + namespace: metallb-system <.> +spec: + protocol: <.> + autoAssign: true <.> + addresses: <.> + - + ... +---- +<.> Specify the name for the address pool. When you add a service, you can specify this pool name in the `metallb.universe.tf/address-pool` annotation to select an IP address from a specific pool. + +<.> Specify the namespace for the address pool. + +<.> Specify the protocol for announcing the load balancer IP address to peer nodes. The only supported value is `layer2`. + +<.> Optional: Specify whether MetalLB automatically assigns IP addresses from this pool. Specify `false` if you want explicitly request an IP address from this pool with the `metallb.universe.tf/address-pool` annotation. The default value is `true`. + +<.> Specify a list of IP addresses for MetalLB to assign to services. You can specify multiple ranges in a single pool. Specify each range in CIDR notation or as starting and ending IP addresses separated with a hyphen. +//// diff --git a/modules/nw-metallb-configure-address-pool.adoc b/modules/nw-metallb-configure-address-pool.adoc new file mode 100644 index 0000000000..a0445bfe0c --- /dev/null +++ b/modules/nw-metallb-configure-address-pool.adoc @@ -0,0 +1,66 @@ +[id="nw-metallb-configure-address-pool_{context}"] += Configuring an address pool + +As a cluster administrator, you can add address pools to your cluster to control the IP addresses that MetaLLB can assign to load-balancer services. + +.Prerequisites + +* Install the OpenShift CLI (`oc`). + +* Log in as a user with `cluster-admin` privileges. + +.Procedure + +. Create a file, such as `addresspool.yaml`, with content like the following example: ++ +[source,yaml] +---- +apiVersion: metallb.io/v1alpha1 +kind: AddressPool +metadata: + namespace: metallb-system + name: doc-example +spec: + protocol: layer2 + addresses: + - 203.0.113.1-203.0.113.10 + - 203.0.113.65-203.0.113.75 +---- + +. Apply the configuration for the address pool: ++ +[source,terminal] +---- +$ oc apply -f addresspool.yaml +---- + +.Verification + +* View the address pool: ++ +[source,terminal] +---- +$ oc describe -n metallb-system addresspool doc-example +---- ++ +.Example output +[source,terminal] +---- +Name: doc-example +Namespace: metallb-system +Labels: +Annotations: +API Version: metallb.io/v1alpha1 +Kind: AddressPool +Metadata: + ... +Spec: + Addresses: + 203.0.113.1-203.0.113.10 + 203.0.113.65-203.0.113.75 + Auto Assign: true + Protocol: layer2 +Events: +---- + +Confirm that the address pool name, such as `doc-example`, and the IP address ranges appear in the output. diff --git a/modules/nw-metallb-configure-svc.adoc b/modules/nw-metallb-configure-svc.adoc new file mode 100644 index 0000000000..0aaf7d471b --- /dev/null +++ b/modules/nw-metallb-configure-svc.adoc @@ -0,0 +1,72 @@ +[id="nw-metallb-configure-svc_{context}"] += Configuring a service with MetalLB + +You can configure a load-balancing service to use an external IP address from an address pool. + +.Prerequisites + +* Install the OpenShift CLI (`oc`). + +* Install the MetalLB Operator and start MetalLB. + +* Configure at least one address pool. + +* Configure your network to route traffic from the clients to the host network for the cluster. + +.Procedure + +. Create a `.yaml` file. In the file, ensure that the `spec.type` field is set to `LoadBalancer`. ++ +Refer to the examples for information about how to request the external IP address that MetalLB assigns to the service. + +. Create the service: ++ +[source,terminal] +---- +$ oc apply -f .yaml +---- ++ +.Example output +[source,terminal] +---- +service/ created +---- + +.Verification + +* Describe the service: ++ +[source,terminal] +---- +$ oc describe service +---- ++ +.Example output +---- +Name: +Namespace: default +Labels: +Annotations: metallb.universe.tf/address-pool: doc-example <.> +Selector: app=service_name +Type: LoadBalancer <.> +IP Family Policy: SingleStack +IP Families: IPv4 +IP: 10.105.237.254 +IPs: 10.105.237.254 +LoadBalancer Ingress: 192.168.100.5 <.> +Port: 80/TCP +TargetPort: 8080/TCP +NodePort: 30550/TCP +Endpoints: 10.244.0.50:8080 +Session Affinity: None +External Traffic Policy: Cluster +Events: <.> + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal nodeAssigned 32m (x2 over 32m) metallb-speaker announcing from node "" +---- +<.> The annotation is present if you request an IP address from a specific pool. +<.> The service type must indicate `LoadBalancer`. +<.> The load-balancer ingress field indicates the external IP address if the service is assigned correctly. +<.> The events field indicates the node name that is assigned to announce the external IP address. +If you experience an error, the events field indicates the reason for the error. diff --git a/modules/nw-metallb-example-addresspool.adoc b/modules/nw-metallb-example-addresspool.adoc new file mode 100644 index 0000000000..959c1e957c --- /dev/null +++ b/modules/nw-metallb-example-addresspool.adoc @@ -0,0 +1,61 @@ +[id="nw-metallb-example-addresspool_{context}"] += Example address pool configurations + +== Example: IPv4 and CIDR ranges + +You can specify a range of IP addresses in CIDR notation. +You can combine CIDR notation with the notation that uses a hyphen to separate lower and upper bounds. + +[source,yaml] +---- +apiVersion: metallb.io/v1beta1 +kind: AddressPool +metadata: + name: doc-example-cidr + namespace: metallb-system +spec: + protocol: layer2 + addresses: + - 192.168.100.0/24 + - 192.168.200.0/24 + - 192.168.255.1-192.168.255.5 +---- + +== Example: Reserve IP addresses + +You can set the `autoAssign` field to `false` to prevent MetalLB from automatically assigning the IP addresses from the pool. +When you add a service, you can request a specific IP address from the pool or you can specify the pool name in an annotation to request any IP address from the pool. + + +[source,yaml] +---- +apiVersion: metallb.io/v1beta1 +kind: AddressPool +metadata: + name: doc-example-reserved + namespace: metallb-system +spec: + protocol: layer2 + addresses: + - 10.0.100.0/28 + autoAssign: false +---- + +== Example: IPv6 address pool + +You can add address pools that use IPv6. +The following example shows a single IPv6 range. +However, you can specify multiple ranges in the `addresses` list, just like several IPv4 examples. + +[source,yaml] +---- +apiVersion: metallb.io/v1beta1 +kind: AddressPool +metadata: + name: doc-example-ipv6 + namespace: metallb-system +spec: + protocol: layer2 + addresses: + - 2002:2:2::1-2002:2:2::100 +---- diff --git a/modules/nw-metallb-infra-considerations.adoc b/modules/nw-metallb-infra-considerations.adoc new file mode 100644 index 0000000000..98c2efd58a --- /dev/null +++ b/modules/nw-metallb-infra-considerations.adoc @@ -0,0 +1,16 @@ +[id="nw-metallb-infra-considerations_{context}"] += Infrastructure considerations for MetalLB + +MetalLB is primarily useful for on-premise, bare metal installations because these installations do not include a native load-balancer capability. +In addition to bare metal installations, installations of {product-title} on some infrastructures might not include a native load-balancer capability. +For example, the following infrastructures might benefit from adding the MetalLB Operator: + +* Bare metal + +* VMware vSphere + +* {rh-virtualization-first} + +* {rh-openstack-first} when it is installed without Octavia + +MetalLB Operator and MetalLB are supported with the OpenShift SDN and OVN-Kubernetes network providers. diff --git a/modules/nw-metallb-installing-operator-cli.adoc b/modules/nw-metallb-installing-operator-cli.adoc new file mode 100644 index 0000000000..3bd3b3e257 --- /dev/null +++ b/modules/nw-metallb-installing-operator-cli.adoc @@ -0,0 +1,126 @@ +[id="nw-metallb-installing-operator-cli_{context}"] += Installing from OperatorHub using the CLI + +Instead of using the {product-title} web console, you can install an Operator from OperatorHub using the CLI. Use the `oc` command to create or update a `Subscription` object. + +.Prerequisites + +* Install the OpenShift CLI (`oc`). + +* Log in as a user with `cluster-admin` privileges. + +.Procedure + +. Confirm that the MetalLB Operator is available: ++ +[source,terminal] +---- +$ oc get packagemanifests -n openshift-marketplace metallb-operator +---- ++ +.Example output +[source,terminal] +---- +NAME CATALOG AGE +metallb-operator Community Operators 9h +---- + +. Create the `metallb-system` namespace: ++ +[source,terminal] +---- +$ cat << EOF | oc apply -f - +apiVersion: v1 +kind: Namespace +metadata: + name: metallb-system +EOF +---- + +. Create an Operator group custom resource in the namespace: ++ +[source,terminal] +---- +$ cat << EOF | oc apply -f - +apiVersion: operators.coreos.com/v1 +kind: OperatorGroup +metadata: + name: metallb-operator + namespace: metallb-system +spec: + targetNamespaces: + - metallb-system +EOF +---- + +. Confirm the Operator group is installed in the namespace: ++ +[source,terminal] +---- +$ oc get operatorgroup -n metallb-system +---- ++ +.Example output +[source,terminal] +---- +NAME AGE +metallb-operator 14m +---- + +. Confirm the install plan is in the namespace: ++ +[source,terminal] +---- +$ oc get installplan -n metallb-system +---- ++ +.Example output +[source,terminal] +---- +NAME CSV APPROVAL APPROVED +install-wzg94 metallb-operator.4.9.0-nnnnnnnnnnnn Automatic true +---- + +. Subscribe to the MetalLB Operator. + +.. Run the following command to get the {product-title} major and minor version. You use the values to set the `channel` value in the next +step. ++ +[source,terminal] +---- +$ OC_VERSION=$(oc version -o yaml | grep openshiftVersion | \ + grep -o '[0-9]*[.][0-9]*' | head -1) +---- + +.. To create a subscription custom resource for the Operator, enter the following command: ++ +[source,terminal] +---- +$ cat << EOF| oc apply -f - +apiVersion: operators.coreos.com/v1alpha1 +kind: Subscription +metadata: + name: metallb-operator-sub + namespace: metallb-system +spec: + channel: "${OC_VERSION}" + name: metallb-operator + source: community-operators + sourceNamespace: openshift-marketplace +EOF +---- + +. To verify that the Operator is installed, enter the following command: ++ +[source,terminal] +---- +$ oc get clusterserviceversion -n metallb-system \ + -o custom-columns=Name:.metadata.name,Phase:.status.phase +---- ++ +.Example output +[source,terminal] +---- +Name Phase +metallb-operator.4.9.0-nnnnnnnnnnnn Succeeded +---- diff --git a/modules/nw-metallb-layer2-extern-traffic-pol.adoc b/modules/nw-metallb-layer2-extern-traffic-pol.adoc new file mode 100644 index 0000000000..d015df6412 --- /dev/null +++ b/modules/nw-metallb-layer2-extern-traffic-pol.adoc @@ -0,0 +1,21 @@ +[id="nw-metallb-layer2-extern-traffic-pol_{context}"] += Layer 2 and external traffic policy + +With layer 2 mode, one node in your cluster receives all the traffic for the service IP address. +How your cluster handles the traffic after it enters the node is affected by the external traffic policy. + +`cluster`:: +This is the default value for `spec.externalTrafficPolicy`. ++ +With the `cluster` traffic policy, after the node receives the traffic, the service proxy distributes the traffic to all the pods in your service. +This policy provides uniform traffic distribution across the pods, but it obscures the client IP address and it can appear to the application in your pods that the traffic originates from the node rather than the client. + +`local`:: +With the `local` traffic policy, after the node receives the traffic, the service proxy only sends traffic to the pods on the same node. +For example, if the `speaker` pod on node A announces the external service IP, then all traffic is sent to node A. +After the traffic enters node A, the service proxy only sends traffic to pods for the service that are also on node A. +Pods for the service that are on additional nodes do not receive any traffic from node A. +Pods for the service on additional nodes act as replicas in case failover is needed. ++ +This policy does not affect the client IP address. +Application pods can determine the client IP address from the incoming connections. diff --git a/modules/nw-metallb-layer2-limitations.adoc b/modules/nw-metallb-layer2-limitations.adoc new file mode 100644 index 0000000000..d1e6a1a7a2 --- /dev/null +++ b/modules/nw-metallb-layer2-limitations.adoc @@ -0,0 +1,31 @@ +[id="nw-metallb-layer2-limitations_{context}"] += Limitations for layer 2 mode + +[id="nw-metallb-layer2-limitations-bottleneck_{context}"] +== Single-node bottleneck + +MetalLB routes all traffic for a service through a single node, the node can become a bottleneck and limit performance. + +Layer 2 mode limits the ingress bandwidth for your service to the bandwidth of a single node. +This is a fundamental limitation of using ARP and NDP to direct traffic. + +[id="nw-metallb-layer2-limitations-failover_{context}"] +== Slow failover performance + +Failover between nodes depends on cooperation from the clients. +When a failover occurs, MetalLB sends gratuitous ARP packets to notify clients that the MAC address associated with the service IP has changed. + +Most client operating systems handle gratuitous ARP packets correctly and update their neighbor caches promptly. +When clients update their caches quickly, failover completes within a few seconds. +Clients typically fail over to a new node within 10 seconds. +However, some client operating systems either do not handle gratuitous ARP packets at all or have outdated implementations that delay the cache update. + +Recent versions of common operating systems such as Windows, macOS, and Linux implement layer 2 failover correctly. +Issues with slow failover are not expected except for older and less common client operating systems. + +// FIXME: I think "leadership" is from an old algorithm. +// If there is a way to perform a planned failover, let's cover it. `oc drain`? +To minimize the impact from a planned failover on outdated clients, keep the old node running for a few minutes after flipping leadership. +The old node can continue to forward traffic for outdated clients until their caches refresh. + +During an unplanned failover, the service IPs are unreachable until the outdated clients refresh their cache entries. diff --git a/modules/nw-metallb-layer2.adoc b/modules/nw-metallb-layer2.adoc new file mode 100644 index 0000000000..ad6303bc31 --- /dev/null +++ b/modules/nw-metallb-layer2.adoc @@ -0,0 +1,42 @@ +[id="nw-metallb-layer2_{context}"] += MetalLB concepts for layer 2 mode + +In layer 2 mode, the `speaker` pod on one node announces the external IP address for a service to the host network. +From a network perspective, the node appears to have multiple IP addresses assigned to a network interface. + +The `speaker` pod responds to ARP requests for IPv4 services and NDP requests for IPv6. + +In layer 2 mode, all traffic for a service IP address is routed through one node. +After traffic enters the node, the service proxy for the CNI network provider distributes the traffic to all the pods for the service. + +Because all traffic for a service enters through a single node in layer 2 mode, in a strict sense, MetalLB does not implement a load balancer for layer 2. +Rather, MetalLB implements a failover mechanism for layer 2 so that when a `speaker` pod becomes unavailable, a `speaker` pod on a different node can announce the service IP address. + +When a node becomes unavailable, failover is automatic. +The `speaker` pods on the other nodes detect that a node is unavailable and a new `speaker` pod and node take ownership of the service IP address from the failed node. + +image::nw-metallb-layer2.png[Conceptual diagram for MetalLB and layer 2 mode] + +The preceding graphic shows the following concepts related to MetalLB: + +* An application is available through a service that has a cluster IP on the `172.130.0.0/16` subnet. +That IP address is accessible from inside the cluster. +The service also has an external IP address that MetalLB assigned to the service, `192.168.100.200`. + +* Nodes 1 and 3 have a pod for the application. + +* The `speaker` daemon set runs a pod on each node. +The MetalLB Operator starts these pods. + +* Each `speaker` pod is a host-networked pod. +The IP address for the pod is identical to the IP address for the node on the host network. + +* The `speaker` pod on node 1 uses ARP to announce the external IP address for the service, `192.168.100.200`. +The `speaker` pod that announces the external IP address must be on the same node as an endpoint for the service and the endpoint must be in the `Ready` condition. + +* Client traffic is routed to the host network and connects to the `192.168.100.200` IP address. +After traffic enters the node, the service proxy sends the traffic to the application pod on the same node or another node according to the external traffic policy that you set for the service. + +* If node 1 becomes unavailable, the external IP address fails over to another node. +On another node that has an instance of the application pod and service endpoint, the `speaker` pod begins to announce the external IP address, `192.168.100.200` and the new node receives the client traffic. +In the diagram, the only candidate is node 3. diff --git a/modules/nw-metallb-operator-custom-resources.adoc b/modules/nw-metallb-operator-custom-resources.adoc new file mode 100644 index 0000000000..aa051c7475 --- /dev/null +++ b/modules/nw-metallb-operator-custom-resources.adoc @@ -0,0 +1,20 @@ +[id="nw-metallb-operator-custom-resources_{context}"] += MetalLB Operator custom resources + +The MetalLB Operator monitors its own namespace for two custom resources: + +`MetalLB`:: +When you add a `MetalLB` custom resource to the cluster, the MetalLB Operator deploys MetalLB on the cluster. +The Operator only supports a single instance of the custom resource. +If the instance is deleted, the Operator removes MetalLB from the cluster. + +`AddressPool`:: +MetalLB requires one or more pools of IP addresses that it can assign to a service when you add a service of type `LoadBalancer`. +When you add an `AddressPool` custom resource to the cluster, the MetalLB Operator configures MetalLB so that it can assign IP addresses from the pool. +An address pool includes a list of IP addresses. +The list can be a single IP address, a range specified in CIDR notation, a range specified as a starting and ending address separated by a hyphen, or a combination of the three. +An address pool requires a name. +The documentation uses names like `doc-example`, `doc-example-reserved`, and `doc-example-ipv6`. +An address pool specifies whether MetalLB can automatically assign IP addresses from the pool or whether the IP addresses are reserved for services that explicitly specify the pool by name. + +After you add the `MetalLB` custom resource to the cluster and the Operator deploys MetalLB, the MetalLB software components, `controller` and `speaker`, begin running. diff --git a/modules/nw-metallb-operator-initial-config.adoc b/modules/nw-metallb-operator-initial-config.adoc new file mode 100644 index 0000000000..96326b44f8 --- /dev/null +++ b/modules/nw-metallb-operator-initial-config.adoc @@ -0,0 +1,61 @@ +[id="nw-metallb-operator-initial-config_{context}"] += Starting MetalLB on your cluster + +After you install the Operator, you need to configure a single instance of a MetalLB custom resource. After you configure the custom resource, the Operator starts MetalLB on your cluster. + +.Prerequisites + +* Install the OpenShift CLI (`oc`). + +* Log in as a user with `cluster-admin` privileges. + +* Install the MetalLB Operator. + +.Procedure + +. Create a single instance of a MetalLB custom resource: ++ +[source,terminal] +---- +$ cat << EOF | oc apply -f - +apiVersion: metallb.io/v1alpha1 +kind: MetalLB +metadata: + name: metallb + namespace: metallb-system +EOF +---- + +.Verification + +Confirm that the deployment for the MetalLB controller and the daemon set for the MetalLB speaker are running. + +. Check that the deployment for the controller is running: ++ +[source,terminal] +---- +$ oc get deployment -n metallb-system controller +---- ++ +.Example output +[source,terminal] +---- +NAME READY UP-TO-DATE AVAILABLE AGE +controller 1/1 1 1 11m +---- + +. Check that the daemon set for the speaker is running: ++ +[source,terminal] +---- +$ oc get daemonset -n metallb-system speaker +---- ++ +.Example output +[source,terminal] +---- +NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE +speaker 6 6 6 6 6 kubernetes.io/os=linux 18m +---- ++ +The example output indicates 6 speaker pods. The number of speaker pods in your cluster might differ from the example output. Make sure the output indicates one pod for each node in your cluster. diff --git a/modules/nw-metallb-software-components.adoc b/modules/nw-metallb-software-components.adoc new file mode 100644 index 0000000000..e7e4aa2e29 --- /dev/null +++ b/modules/nw-metallb-software-components.adoc @@ -0,0 +1,25 @@ +[id="nw-metallb-software-components_{context}"] += MetalLB software components + +When you install the MetalLB Operator, the `metallb-operator-controller-manager` deployment starts a pod. +The pod is the implementation of the Operator. +The pod monitors for changes to the `MetalLB` custom resource and `AddressPool` custom resources. + +When the Operator starts an instance of MetalLB, it starts a `controller` deployment and a `speaker` daemon set. + +`controller`:: +The Operator starts the deployment and a single pod. +When you add a service of type `LoadBalancer`, Kubernetes uses the `controller` to allocate an IP address from an address pool. + +`speaker`:: +The Operator starts a daemon set with one `speaker` pod for each node in your cluster. ++ +For layer 2 mode, after the `controller` allocates an IP address for the service, each `speaker` pod determines if it is on the same node as an endpoint for the service. +An algorithm that involves hashing the node name and the service name is used to select a single `speaker` pod to announce the load balancer IP address. +// IETF treats protocol names as proper nouns. +The `speaker` uses Address Resolution Protocol (ARP) to announce IPv4 addresses and Neighbor Discovery Protocol (NDP) to announce IPv6 addresses. ++ +Requests for the load balancer IP address are routed to the node with the `speaker` that announces the IP address. +After the node receives the packets, the service proxy routes the packets to an endpoint for the service. +The endpoint can be on the same node in the optimal case, or it can be on another node. +The service proxy chooses an endpoint each time a connection is established. diff --git a/modules/nw-metallb-when-metallb.adoc b/modules/nw-metallb-when-metallb.adoc new file mode 100644 index 0000000000..e6c004be1d --- /dev/null +++ b/modules/nw-metallb-when-metallb.adoc @@ -0,0 +1,8 @@ +[id="nw-metallb-when-metallb_{context}"] += When to use MetalLB + +Using MetalLB is valuable when you have a bare-metal cluster, or an infrastructure that is like bare metal, and you want fault-tolerant access to an application through an external IP address. + +You must configure your networking infrastructure to ensure that network traffic for the external IP address is routed from clients to the host network for the cluster. + +After deploying MetalLB with the MetalLB Operator, when you add a service of type `LoadBalancer`, MetalLB provides a platform-native load balancer. diff --git a/modules/olm-installing-from-operatorhub-using-web-console.adoc b/modules/olm-installing-from-operatorhub-using-web-console.adoc index 2dae8913fe..e1e7eea075 100644 --- a/modules/olm-installing-from-operatorhub-using-web-console.adoc +++ b/modules/olm-installing-from-operatorhub-using-web-console.adoc @@ -8,7 +8,8 @@ // https://projects.engineering.redhat.com/projects/RHEC/summary // Add additional ifevals here, but before context == olm-adding-operators-to-a-cluster -ifeval::["{context}" != "olm-adding-operators-to-a-cluster"] +ifndef::filter-type[] +//ifeval::["{context}" != "olm-adding-operators-to-a-cluster"] :filter-type: jaeger :filter-operator: Jaeger :olm-admin: diff --git a/networking/configuring_ingress_cluster_traffic/overview-traffic.adoc b/networking/configuring_ingress_cluster_traffic/overview-traffic.adoc index a332ed28eb..e96cd940e1 100644 --- a/networking/configuring_ingress_cluster_traffic/overview-traffic.adoc +++ b/networking/configuring_ingress_cluster_traffic/overview-traffic.adoc @@ -26,6 +26,11 @@ with the SNI header, use an Ingress Controller. |xref:../../networking/configuring_ingress_cluster_traffic/configuring-ingress-cluster-traffic-load-balancer.adoc#configuring-ingress-cluster-traffic-load-balancer[Automatically assign an external IP using a load balancer service] |Allows traffic to non-standard ports through an IP address assigned from a pool. +Most cloud platforms offer a method to start a service with a load-balancer IP address. + +|xref:../../networking/metallb/about-metallb.adoc#about-metallb[About MetalLB and the MetalLB Operator] +|Allows traffic to a specific IP address or address from a pool on the machine network. +For bare-metal installations or platforms that are like bare metal, MetalLB provides a way to start a service with a load-balancer IP address. |xref:../../networking/configuring_ingress_cluster_traffic/configuring-ingress-cluster-traffic-service-external-ip.adoc#configuring-ingress-cluster-traffic-service-external-ip[Manually assign an external IP to a service] |Allows traffic to non-standard ports through a specific IP address. @@ -33,3 +38,25 @@ with the SNI header, use an Ingress Controller. |xref:../../networking/configuring_ingress_cluster_traffic/configuring-ingress-cluster-traffic-nodeport.adoc#configuring-ingress-cluster-traffic-nodeport[Configure a `NodePort`] |Expose a service on all nodes in the cluster. |=== + +[id="overview-traffic-comparision_{context}"] +== Comparision: Fault tolerant access to external IP addresses + +For the communication methods that provide access to an external IP address, fault tolerant access to the IP address is another consideration. +The following features provide fault tolerant access to an external IP address. + +IP failover:: +IP failover manages a pool of virtual IP address for a set of nodes. +It is implemented with Keepalived and Virtual Router Redundancy Protocol (VRRP). +IP failover is a layer 2 mechanism only and relies on multicast. +Multicast can have disadvantages for some networks. + +MetalLB:: +MetalLB has a layer 2 mode, but it does not use multicast. +Layer 2 mode has a disadvantage that it transfers all traffic for an external IP address through one node. + +Manually assigning external IP addresses:: +You can configure your cluster with an IP address block that is used to assign external IP addresses to services. +By default, this feature is disabled. +This feature is flexible, but places the largest burden on the cluster or network administrator. +The cluster is prepared to receive traffic that is destined for the external IP, but each customer has to decide how they want to route traffic to nodes. diff --git a/networking/metallb/about-metallb.adoc b/networking/metallb/about-metallb.adoc new file mode 100644 index 0000000000..cc0d31f7db --- /dev/null +++ b/networking/metallb/about-metallb.adoc @@ -0,0 +1,65 @@ +[id="about-metallb"] += About MetalLB and the MetalLB Operator +include::modules/common-attributes.adoc[] +:context: about-metallb-and-metallb-operator + +toc::[] + +As a cluster administrator, you can add the MetalLB Operator to your cluster so that when a service of type `LoadBalancer` is added to the cluster, MetalLB can add a fault-tolerant external IP address for the service. +The external IP address is added to the host network for your cluster. + +// When to deploy MetalLB +include::modules/nw-metallb-when-metallb.adoc[leveloffset=+1] + +// MetalLB Operator custom resources +include::modules/nw-metallb-operator-custom-resources.adoc[leveloffset=+1] + +// MetalLB software components +include::modules/nw-metallb-software-components.adoc[leveloffset=+1] + +// Layer 2 +include::modules/nw-metallb-layer2.adoc[leveloffset=+1] + +// Layer 2 and external traffic policy +include::modules/nw-metallb-layer2-extern-traffic-pol.adoc[leveloffset=+2] + +[id="limitations-and-restrictions_{context}"] +== Limitations and restrictions + +// With fair confidence, this topic is temporary for 4.9. +[id="support-layer2-only_{context}"] +=== Support for layer 2 only + +When you install and configure MetalLB on {product-title} 4.9 with the MetalLB Operator, support is restricted to layer 2 mode only. +In comparison, the open source MetalLB project offers load balancing for layer 2 mode and a mode for layer 3 that uses border gateway protocol (BGP). + +// Ditto. This limitation should be lifted in 4.10. +[id="support-single-stack_{context}"] +=== Support for single stack networking + +Although you can specify IPv4 addresses and IPv6 addresses in the same address pool, MetalLB only assigns one IP address for the load balancer. + +When MetalLB is deployed on a cluster that is configured for dual-stack networking, MetalLB assigns one IPv4 or IPv6 address for the load balancer, depending on the IP address family of the cluster IP for the service. +For example, if the cluster IP of the service is IPv4, then MetalLB assigns an IPv4 address for the load balancer. +MetalLB does not assign an IPv4 and an IPv6 address simultaneously. + +IPv6 is only supported for clusters that use the OVN-Kubernetes network provider. + +// Infra considerations +include::modules/nw-metallb-infra-considerations.adoc[leveloffset=+2] + +// Layer 2 limitations +include::modules/nw-metallb-layer2-limitations.adoc[leveloffset=+2] + +// Incompat with IP failover +[id="incompatibility-with-ip-failover_{context}"] +=== Incompatibility with IP failover + +MetalLB is incompatible with the IP failover feature. Before you install the MetalLB Operator, remove IP failover. + +[id="additional-resources_{context}"] +== Additional resources + +* xref:../../networking/configuring_ingress_cluster_traffic/overview-traffic.adoc#overview-traffic-comparision_overview-traffic[Comparison: Fault tolerant access to external IP addresses] + +* xref:../../networking/configuring-ipfailover.adoc#nw-ipfailover-remove_configuring-ipfailover[Removing IP failover] diff --git a/networking/metallb/images b/networking/metallb/images new file mode 120000 index 0000000000..5fa6987088 --- /dev/null +++ b/networking/metallb/images @@ -0,0 +1 @@ +../../images \ No newline at end of file diff --git a/networking/metallb/metallb-configure-address-pools.adoc b/networking/metallb/metallb-configure-address-pools.adoc new file mode 100644 index 0000000000..ad9cfe9cf4 --- /dev/null +++ b/networking/metallb/metallb-configure-address-pools.adoc @@ -0,0 +1,23 @@ +[id="metallb-configure-address-pools"] += Configuring MetalLB address pools +include::modules/common-attributes.adoc[] +:context: configure-metallb-address-pools + +toc::[] + +As a cluster administrator, you can add, modify, and delete address pools. +The MetalLB Operator uses the address pool custom resources to set the IP addresses that MetalLB can assign to services. + +// Address pool custom resource +include::modules/nw-metallb-addresspool-cr.adoc[leveloffset=+1] + +// Add an address pool +include::modules/nw-metallb-configure-address-pool.adoc[leveloffset=+1] + +// Examples +include::modules/nw-metallb-example-addresspool.adoc[leveloffset=+1] + +[id="next-steps_{context}"] +== Next steps + +* xref:../../networking/metallb/metallb-configure-services.adoc#metallb-configure-services[Configuring services to use MetalLB] diff --git a/networking/metallb/metallb-configure-services.adoc b/networking/metallb/metallb-configure-services.adoc new file mode 100644 index 0000000000..0a60c592f7 --- /dev/null +++ b/networking/metallb/metallb-configure-services.adoc @@ -0,0 +1,162 @@ +[id="metallb-configure-services"] += Configuring services to use MetalLB +include::modules/common-attributes.adoc[] +:context: configure-services-metallb + +toc::[] + +As a cluster administrator, when you add a service of type `LoadBalancer`, you can control how MetalLB assigns an IP address. + +// Request a specific IP address +[id="request-specific-ip-address_{context}"] +== Request a specific IP address + +Like some other load-balancer implementations, MetalLB accepts the `spec.loadBalancerIP` field in the service specification. + +If the requested IP address is within a range from any address pool, MetalLB assigns the requested IP address. +If the requested IP address is not within any range, MetalLB reports a warning. + +.Example service YAML for a specific IP address +[source,yaml] +---- +apiVersion: v1 +kind: Service +metadata: + name: + annotations: + metallb.universe.tf/address-pool: +spec: + selector: + : + ports: + - port: 8080 + targetPort: 8080 + protocol: TCP + type: LoadBalancer + loadBalancerIP: +---- + +If MetalLB cannot assign the requested IP address, the `EXTERNAL-IP` for the service reports `` and running `oc describe service ` includes an event like the following example. + +.Example event when MetalLB cannot assign a requested IP address +[source,terminal] +---- + ... +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Warning AllocationFailed 3m16s metallb-controller Failed to allocate IP for "default/invalid-request": "4.3.2.1" is not allowed in config +---- + +[id="request-ip-address-from-pool_{context}"] +== Request an IP address from a specific pool + +To assign an IP address from a specific range, but you are not concerned with the specific IP address, then you can use the `metallb.universe.tf/address-pool` annotation to request an IP address from the specified address pool. + +.Example service YAML for an IP address from a specific pool +[source,yaml] +---- +apiVersion: v1 +kind: Service +metadata: + name: + annotations: + metallb.universe.tf/address-pool: +spec: + selector: + : + ports: + - port: 8080 + targetPort: 8080 + protocol: TCP + type: LoadBalancer +---- + +If the address pool that you specify for `` does not exist, MetalLB attempts to assign an IP address from any pool that permits automatic assignment. + +[id="accept-any-ip-address_{context}"] +== Accept any IP address + +By default, address pools are configured to permit automatic assignment. +MetalLB assigns an an IP address from these address pools. + +To accept any IP address from any pool that is configured for automatic assignment, no special annotation or configuration is required. + +.Example service YAML for accepting any IP address +[source,yaml] +---- +apiVersion: v1 +kind: Service +metadata: + name: +spec: + selector: + : + ports: + - port: 8080 + targetPort: 8080 + protocol: TCP + type: LoadBalancer +---- + +[id="share-specific-ip-address_{context}"] +== Share a specific IP address + +By default, services do not share IP addresses. +However, if you need to colocate services on a single IP address, you can enable selective IP sharing by adding the `metallb.universe.tf/allow-shared-ip` annotation to the services. + +[source,yaml] +---- +apiVersion: v1 +kind: Service +metadata: + name: service-http + annotations: + metallb.universe.tf/address-pool: doc-example + metallb.universe.tf/allow-shared-ip: "web-server-svc" <1> +spec: + ports: + - name: http + port: 80 <2> + protocol: TCP + targetPort: 8080 + selector: + : <3> + type: LoadBalancer + loadBalancerIP: 172.31.249.7 <4> +--- +apiVersion: v1 +kind: Service +metadata: + name: service-https + annotations: + metallb.universe.tf/address-pool: doc-example + metallb.universe.tf/allow-shared-ip: "web-server-svc" <1> +spec: + ports: + - name: https + port: 443 <2> + protocol: TCP + targetPort: 8080 + selector: + : <3> + type: LoadBalancer + loadBalancerIP: 172.31.249.7 <4> +---- +<1> Specify the same value for the `metallb.universe.tf/allow-shared-ip` annotation. This value is referred to as the _sharing key_. +<2> Specify different port numbers for the services. +<3> Specify identical pod selectors if you must specify `externalTrafficPolicy: local` so the services send traffic to the same set of pods. If you use the `cluster` external traffic policy, then the pod selectors do not need to be identical. +<4> Optional: If you specify the three preceding items, MetalLB might colocate the services on the same IP address. To ensure that services share an IP address, specify the IP address to share. + +By default, Kubernetes does not allow multiprotocol load balancer services. +This limitation would normally make it impossible to run a service like DNS that needs to listen on both TCP and UDP. +To work around this limitation of Kubernetes with MetalLB, create two services: + +* For one service, specify TCP and for the second service, specify UDP. + +* In both services, specify the same pod selector. + +* Specify the same sharing key and `spec.loadBalancerIP` value to colocate the TCP and UDP services on the same IP address. + +// Configuring a service with MetalLB +include::modules/nw-metallb-configure-svc.adoc[leveloffset=+1] diff --git a/networking/metallb/metallb-operator-install.adoc b/networking/metallb/metallb-operator-install.adoc new file mode 100644 index 0000000000..ad701888d7 --- /dev/null +++ b/networking/metallb/metallb-operator-install.adoc @@ -0,0 +1,32 @@ +[id="metallb-operator-install"] += Installing the MetalLB Operator +include::modules/common-attributes.adoc[] +:context: metallb-operator-install + +toc::[] + +As a cluster administrator, you can add the MetallB Operator so that the Operator can manage the lifecycle for an instance of MetalLB on your cluster. + +The installation procedures use the `metallb-system` namespace. +You can install the Operator and configure custom resources in a different namespace. +The Operator starts MetalLB in the same namespace that the Operator is installed in. + +MetalLB and IP failover are incompatible. If you configured IP failover for your cluster, perform the steps to xref:../../networking/configuring-ipfailover.adoc#nw-ipfailover-remove_configuring-ipfailover[remove IP failover] before you install the Operator. + +// Install the Operator with console +:filter-type: metallb +:filter-operator: MetalLB +include::modules/olm-installing-from-operatorhub-using-web-console.adoc[leveloffset=+1] +:!filter-type: +:!filter-operator: + +// Install the Operator with CLI +include::modules/nw-metallb-installing-operator-cli.adoc[leveloffset=+1] + +// Starting MetalLB on your cluster +include::modules/nw-metallb-operator-initial-config.adoc[leveloffset=+1] + +[id="next-steps_{context}"] +== Next steps + +* xref:../../networking/metallb/metallb-configure-address-pools.adoc#metallb-configure-address-pools[Configuring MetalLB address pools] diff --git a/networking/metallb/modules b/networking/metallb/modules new file mode 120000 index 0000000000..8b0e854007 --- /dev/null +++ b/networking/metallb/modules @@ -0,0 +1 @@ +../../modules \ No newline at end of file