Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions _topic_map.yml
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,10 @@ Topics:
File: editing-egress-firewall-ovn
- Name: Removing an egress firewall from a project
File: removing-egress-firewall-ovn
- Name: Configuring an egress IP address
File: configuring-egress-ips-ovn
- Name: Assigning an egress IP address
File: assigning-egress-ips-ovn
- Name: Enabling multicast for a project
File: enabling-multicast
- Name: Disabling multicast for a project
Expand Down
1 change: 1 addition & 0 deletions images/nw-egress-ips-diagram.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
120 changes: 119 additions & 1 deletion modules/nw-egress-ips-about.adoc
Original file line number Diff line number Diff line change
@@ -1,7 +1,115 @@
// Module included in the following assemblies:
//
// * networking/assigning-egress-ips.adoc
// * networking/openshift_sdn/assigning-egress-ips.adoc
// * networking/ovn_kubernetes_network_provider/assigning-egress-ips-ovn.adoc

ifeval::["{context}" == "egress-ips"]
:openshift-sdn:
endif::[]
ifeval::["{context}" == "configuring-egress-ips-ovn"]
:ovn:
endif::[]

:rhosp: Red Hat OpenStack Platform

ifdef::ovn[]
[id="nw-egress-ips-about_{context}"]
= Egress IP address architectural design and implementation

The {product-title} egress IP address functionality allows you to ensure that the traffic from one or more pods in one or more namespaces has a consistent source IP address for services outside the cluster network.

For example, you might have a pod that periodically queries a database that is hosted on a server outside of your cluster. To enforce access requirements for the server, a packet filtering device is configured to allow traffic only from specific IP addresses.
To ensure that you can reliably allow access to the server from only that specific pod, you can configure a specific egress IP address for the pod that makes the requests to the server.

An egress IP address is implemented as an additional IP address on the primary network interface of a node and must be in the same subnet as the primary IP address of the node. The additional IP address must not be assigned to any other node in the cluster.

[id="nw-egress-ips-platform-support_{context}"]
== Platform support

While you can use the egress IP address functionality on any platform that {product-title} supports, the following platform specific considerations apply:

Cloud platforms::
Additional IP addresses must be assigned manually to appropriate nodes by an administrator.

{rhosp}::
Additional configuration by an administrator is necessary to allow {product-title} to automatically assign additional IP addresses to nodes.

vSphere::
Additional configuration by an administrator is necessary to allow {product-title} to automatically assign additional IP addresses to nodes.

[id="nw-egress-ips-considerations_{context}"]
== Assignment of egress IPs to pods

To assign one or more egress IPs to a namespace or specific pods in a namespace, the following conditions must be satisfied:

- At least one node in your cluster must have the `k8s.ovn.org/egress-assignable: ""` label.
- An `EgressIP` object exists that defines one or more egress IP addresses to use as the source IP address for traffic leaving the cluster from pods in a namespace.

[IMPORTANT]
====
If you create `EgressIP` objects prior to labeling any nodes in your cluster for egress IP assignment, {product-title} might assign every egress IP address to the first node with the `k8s.ovn.org/egress-assignable: ""` label.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the user know what problem this might cause, or should we note why we might want to avoid this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alexanderConstantinescu, can I elaborate on this? The enhancement doesn't seem to provide any additional insight into why to avoid this:

Points 4.1. - 4.6. means: that if a user creates EgressIP objects before tagging nodes, then there is a risk that most EgressIP objects will be assigned to the same egress node, should that node be able to host them. It would be impossible for OVN-Kubernetes to rectify that situation, as it cannot know how many egress nodes will be available to it, so it will try to assign everything in its queue to the first node it sees. It is thus up to the user to delete and re-create all objects should a lot of them have been created that way.
It is subsequently strongly advised that a user first labels all nodes needed, and then creates EgressIP objects.

Thanks!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason why someone would like to avoid that is: as to not have all egress IPs / majority of then assigned to one node. It would be better if all egress IPs are evenly distributed (or as much so as possible) across all egress nodes across the cluster. And that even distribution can only be made once OVN-Kubernetes knows all egress nodes prior to making each egress IP assignment.


To ensure that egress IP addresses are widely distributed across nodes in the cluster, always apply the label to the nodes you intent to host the egress IP addresses before creating any `EgressIP` objects.
====

[id="nw-egress-ips-node-assignment_{context}"]
== Assignment of egress IPs to nodes

When creating an `EgressIP` object, the following conditions apply to nodes that are labeled with the `k8s.ovn.org/egress-assignable: ""` label:

- An egress IP address is never assigned to more than one node at a time.
- An egress IP address is equally balanced between available nodes that can host the egress IP address.
- If the `spec.EgressIPs` array in an `EgressIP` object specifies more than one IP address, no node will ever host more than one of the specified addresses.
- If a node is deleted by a cluster administrator, any egress IP addresses assigned to it are automatically reassigned, subject to the previously described conditions.

////
(True after BZ-1877273 is resolved.)
- If a node becomes unavailable, any egress IP addresses assigned to it are automatically reassigned, subject to the previously described conditions.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not quite true, due to bug: https://bugzilla.redhat.com/show_bug.cgi?id=1877273 (which will not be fixed in the 4.6 release and will have to be Z-streamed). The impact of that bug is: the egress IP will not fail over if it simply stops functioning for whatever reason. It must be deleted by the user by doing a oc delete node $NODE for that to happen. I would thus re-phrase for the moment and say: If a node is deleted by the cluster admin, any egress IP addresses...

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And possibly add a note for this corner case of having a "silent network failure" for a node, which is not supported today.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alexanderConstantinescu, what might constitute the class of silent network failures? Is there a class of noisy network failures that OCP does detect? I can say:

NOTE: An egress IP address is not reassigned if a connectivity interruption is undetected.

But I'm not sure how to elaborate on that.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You bring up a good point. "Silently" to me is if a node can't be reached anymore networking wise, but Kubernetes/OpenShift seems to think everything is running fine and indicates such. But actually, if a node X's networking is down (even silently), the kubelet will stop reporting the node's status and thus a cluster admin of Kubernetes / OpenShift will know. We will still not be able to handle that today for egress IP, so I would say: If a node is deleted by the cluster admin, any egress IP addresses... because even if it's unavailable (silently or not) we still don't handle that case. But this will need to be fixed in the docs once that bug is solved, but I will contact you then

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alexanderConstantinescu, so I've updated this to:

  • If a node is deleted by a cluster administrator, any egress IP addresses assigned to it are automatically reassigned, subject to the previously described conditions.
    NOTE: An egress IP address is not reassigned if a connectivity interruption is undetected.

But maybe I don't need the note?

Thanks!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I would say the NOTE adds confusion. The text is already explicit IMO

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

////


When a pod matches the selector for multiple `EgressIP` objects, there is no guarantee which of the egress IP addresses that are specified in the `EgressIP` objects is assigned as the egress IP address for the pod.

[id="nw-egress-ips-node-architecture_{context}"]
== Architectural diagram of an egress IP address configuration

The following diagram depicts an egress IP address configuration. The diagram describes the relationship between three nodes in a cluster and four pods running on that cluster in two different namespaces.

// Source: https://github.com/redhataccess/documentation-svg-assets/blob/master/for-web/121_OpenShift/121_OpenShift_engress_IP_Topology_1020.svg
image::nw-egress-ips-diagram.svg[Architectural diagram for the egress IP feature.]

Both Node 1 and Node 3 are labeled with `k8s.ovn.org/egress-assignable: ""` and thus available for the assignment of egress IP addresses.

The following `EgressIP` object describes a configuration that selects all pods in the `namespace1` namespace, with the `192.168.126.10` and `192.168.126.102` egress IP addresses specified.

.`EgressIP` object
[source,yaml]
----
apiVersion: k8s.ovn.org/v1
kind: EgressIP
metadata:
name: egressips
spec:
egressIPs:
- 192.168.126.10
- 192.168.126.102
namespaceSelector:
matchLabels:
name: namespace1
status:
assignments:
- node: node1
egressIP: 192.168.126.10
- node: node3
egressIP: 192.168.126.102
----

After creating the `EgressIP` object, {product-title} assigns both egress IP addresses to the available nodes. The `status` field reflects the whether and where the egress IP addresses are assigned.

The dashed lines in the diagram depict the traffic flow from `pod1`, `pod2`, and `pod3` traveling through the pod network to egress the cluster from Node 1 and Node 3. When an external service receives traffic from any of the pods selected by the example `EgressIP` object, the source IP address is either `192.168.126.10` or `192.168.126.102`.
endif::ovn[]

ifdef::openshift-sdn[]
[id="nw-egress-ips-about_{context}"]
= Egress IP address assignment for project egress traffic

Expand Down Expand Up @@ -59,3 +167,13 @@ When using the manual assignment approach for egress IP addresses the following
When a namespace has multiple egress IP addresses, if the node hosting the first egress IP address is unreachable, {product-title} will automatically switch to using the next available egress IP address until the first egress IP address is reachable again.

This approach is recommended for clusters installed in public cloud environments, where there can be limitations on associating additional IP addresses with nodes.
endif::openshift-sdn[]

ifdef::openshift-sdn[]
:!openshift-sdn:
endif::openshift-sdn[]
ifdef::ovn[]
:!ovn:
endif::ovn[]

:!rhosp:
51 changes: 51 additions & 0 deletions modules/nw-egress-ips-assign.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Module included in the following assemblies:
//
// * networking/ovn_kubernetes_network_provider/assigning-egress-ips-ovn.adoc

[id="nw-egress-ips-assign_{context}"]
= Assigning an egress IP address to a namespace

You can assign one or more egress IP addresses to a namespace or to specific pods in a namespace.

.Prerequisites

* Install the OpenShift CLI (`oc`).
* Log in to the cluster as a cluster administrator.
* Configure at least one node to host an egress IP address.

.Procedure

. Create an `EgressIP` object:
.. Create a `<egressips_name>.yaml` file where `<egressips_name>` is the name of the object.
.. In the file that you created, define an `EgressIPs` object, as in the following example:
+
[source,yaml]
----
apiVersion: k8s.ovn.org/v1
kind: EgressIP
metadata:
name: egress-project1
spec:
egressIPs:
- 192.168.127.10
- 192.168.127.11
namespaceSelector:
matchLabels:
name: project1
----

. To create the object, enter the following command.
+
[source,terminal]
----
$ oc apply -f <egressips_name>.yaml <1>
----
<1> Replace `<egressips_name>` with the name of the object.
+
.Example output
[source,terminal]
----
egressips.k8s.ovn.org/<egressips_name> created
----

. Optional: Save the `<egressips_name>.yaml` file so that you can make changes later.
24 changes: 24 additions & 0 deletions modules/nw-egress-ips-node.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Module included in the following assemblies:
//
// * networking/ovn_kubernetes_network_provider/configuring-egress-ips-ovn.adoc

[id="nw-egress-ips-node_{context}"]
= Labeling a node to host egress IP addresses

You can apply the `k8s.ovn.org/egress-assignable=""` label to a node in your cluster so that {product-title} can assign one or more egress IP addresses to the node.

.Prerequisites

* Install the OpenShift CLI (`oc`).
* Log in to the cluster as a cluster administrator.

.Procedure

* To label a node so that it can host one or more egress IP addresses, enter the following command:
+
[source,terminal]
----
$ oc label nodes <node_name> k8s.ovn.org/egress-assignable="" <1>
----
+
<1> The name of the node to label.
94 changes: 94 additions & 0 deletions modules/nw-egress-ips-object.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// Module included in the following assemblies:
//
// * networking/ovn_kubernetes_network_provider/assigning-egress-ips-ovn.adoc

[id="nw-egress-ips-object_{context}"]
= EgressIP object

The following YAML describes the API for the `EgressIP` object. The scope of the object is cluster-wide; it is not created in a namespace.

[source,yaml]
----
apiVersion: k8s.ovn.org/v1
kind: EgressIP
metadata:
name: <name> <1>
spec:
egressIPs: <2>
- <ip_address>
namespaceSelector: <3>
...
podSelector: <4>
...
----
<1> The name for the `EgressIPs` object.

<2> An array of one or more IP addresses.

<3> One or more selectors for the namespaces to associate the egress IP addresses with.

<4> Optional: One or more selectors for pods in the specified namespaces to associate egress IP addresses with. Applying these selectors allows for the selection of a subset of pods within a namespace.

The following YAML describes the stanza for the namespace selector:

.Namespace selector stanza
[source,yaml]
----
namespaceSelector: <1>
matchLabels:
name: <namespace_name>
----
<1> One or more matching rules for namespaces. If more than one match rule is provided, all matching namespaces are selected.

The following YAML describes the optional stanza for the pod selector:

.Pod selector stanza
[source,yaml]
----
podSelector: <1>
matchLabels:
name: <pod_name>
----
<1> Optional: One or more matching rules for pods in the namespaces that match the specified `namespaceSelector` rules. If specified, only pods that match are selected. Others pods in the namespace are not selected.

In the following example, the `EgressIP` object associates the `192.168.126.11` and `192.168.126.102` egress IP addresses with the pod that is named `my-pod` in the namespace that is named `my-namespace`:

.Example `EgressIP` object
[source,yaml]
----
apiVersion: k8s.ovn.org/v1
kind: EgressIP
metadata:
name: egress-group1
spec:
egressIPs:
- 192.168.126.11
- 192.168.126.102
podSelector:
matchLabels:
name: my-pod
namespaceSelector:
matchLabels:
name: my-namespace
----

In the following example, the `EgressIP` object associates the `192.168.127.30` and `192.168.127.40` egress IP addresses with any pods that do not have the `environment` label set to `development`:

.Example `EgressIP` object
[source,yaml]
----
apiVersion: k8s.ovn.org/v1
kind: EgressIP
metadata:
name: egress-group2
spec:
egressIPs:
- 192.168.127.30
- 192.168.127.40
namespaceSelector:
matchExpressions:
- key: environment
operator: NotIn
values:
- development
----
Loading