// Module included in the following assemblies:
//
// * hosted_control_planes/hcp-manage/hcp-manage-bm.adoc
// * hosted_control_planes/hcp-manage/hcp-manage-non-bm.adoc
// * hosted_control_planes/hcp-networking.adoc

ifeval::["{context}" == "hcp-manage-non-bm"]
:non-bm:
endif::[]

:_mod-docs-content-type: PROCEDURE
[id="hcp-bm-ingress_{context}"]
ifndef::non-bm[]
= Handling ingress in a hosted cluster on bare metal

endif::non-bm[]

ifdef::non-bm[]
= Handling ingress in a hosted cluster on non-bare-metal agent machines

endif::non-bm[]

[role="_abstract"]
Every {product-title} cluster has a default application Ingress Controller that typically has an external DNS record associated with it. 

For example, if you create a hosted cluster named `example` with the base domain `krnl.es`, you can expect the wildcard domain `*.apps.example.krnl.es` to be routable.

To set up a load balancer and wildcard DNS record for the `*.apps` domain, perform the following actions on your hosted cluster.

.Procedure

. Deploy MetalLB by creating a YAML file that has the configuration for the MetalLB Operator:
+
[source,yaml]
----
apiVersion: v1
kind: Namespace
metadata:
  name: metallb
  labels:
    openshift.io/cluster-monitoring: "true"
  annotations:
    workload.openshift.io/allowed: management
---
apiVersion: operators.coreos.com/v1
kind: OperatorGroup
metadata:
  name: metallb-operator-operatorgroup
  namespace: metallb
---
apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
  name: metallb-operator
  namespace: metallb
spec:
  channel: "stable"
  name: metallb-operator
  source: redhat-operators
  sourceNamespace: openshift-marketplace
----

. Save the file as `metallb-operator-config.yaml`.

. Enter the following command to apply the configuration:
+
[source,terminal]
----
$ oc apply -f metallb-operator-config.yaml
----

. After the Operator is running, create the MetalLB instance:

.. Create a YAML file that has the configuration for the MetalLB instance:
+
[source,yaml]
----
apiVersion: metallb.io/v1beta1
kind: MetalLB
metadata:
  name: metallb
  namespace: metallb
----

.. Save the file as `metallb-instance-config.yaml`.

.. Create the MetalLB instance by entering this command:
+
[source,terminal]
----
$ oc apply -f metallb-instance-config.yaml
----

. Create an `IPAddressPool` resource with a single IP address. This IP address must be on the same subnet as the network that the cluster nodes use.

.. Create a file, such as `ipaddresspool.yaml`, with content similar to the following example:
+
[source,yaml]
----
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  namespace: metallb
  name: <ip_address_pool_name>
spec:
  addresses:
    - <ingress_ip>-<ingress_ip>
  autoAssign: false
----
+
* `metadata.name` specifies the `IPAddressPool` resource name.
* `spec.addresses` specifies the IP address for your environment. For example, `192.168.122.23`.

.. Apply the configuration for the IP address pool by entering the following command:
+
[source,terminal]
----
$ oc apply -f ipaddresspool.yaml
----

. Create a L2 advertisement.

.. Create a file, such as `l2advertisement.yaml`, with content similar to the following example:
+
[source,yaml]
----
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: <l2_advertisement_name>
  namespace: metallb
spec:
  ipAddressPools:
   - <ip_address_pool_name>
----
+
* `metadata.name` specifies the `L2Advertisement` resource name.
* `spec.ipAddressPools` specifies the `IPAddressPool` resource name.

.. Apply the configuration by entering the following command:
+
[source,terminal]
----
$ oc apply -f l2advertisement.yaml
----

. After creating a service of the `LoadBalancer` type, MetalLB adds an external IP address for the service.

.. Configure a new load balancer service that routes ingress traffic to the ingress deployment by creating a YAML file named `metallb-loadbalancer-service.yaml`:
+
[source,yaml]
----
kind: Service
apiVersion: v1
metadata:
  annotations:
   metallb.io/address-pool: ingress-public-ip
  name: metallb-ingress
  namespace: openshift-ingress
spec:
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 80
    - name: https
      protocol: TCP
      port: 443
      targetPort: 443
  selector:
    ingresscontroller.operator.openshift.io/deployment-ingresscontroller: default
  type: LoadBalancer
----

.. Save the `metallb-loadbalancer-service.yaml` file.

.. Enter the following command to apply the YAML configuration:
+
[source,terminal]
----
$ oc apply -f metallb-loadbalancer-service.yaml
----

.. Enter the following command to reach the {product-title} console:
+
[source,bash]
----
$ curl -kI https://console-openshift-console.apps.example.krnl.es
----
+
.Example output
[source,terminal]
----
HTTP/1.1 200 OK
----

.. Check the `clusterversion` and `clusteroperator` values to verify that everything is running. Enter the following command:
+
[source,terminal]
----
$ oc --kubeconfig <hosted_cluster_name>.kubeconfig get clusterversion,co
----
+
.Example output
[source,terminal]
----
NAME                                         VERSION   AVAILABLE   PROGRESSING   SINCE   STATUS
clusterversion.config.openshift.io/version   4.x.y      True        False        3m32s   Cluster version is 4.x.y

NAME                                                                             VERSION   AVAILABLE   PROGRESSING   DEGRADED   SINCE   MESSAGE
clusteroperator.config.openshift.io/console                                      4.x.y     True        False         False      3m50s
clusteroperator.config.openshift.io/ingress                                      4.x.y     True        False         False      53m
----
+
Replace `<4.x.y>` with the supported {product-title} version that you want to use, for example, `4.22.0-multi`.


ifeval::["{context}" == "hcp-manage-non-bm"]
:!non-bm:
endif::[]
