// Module included in the following assemblies:
//
// * microshift_networking/microshift-networking.adoc

:_mod-docs-content-type: PROCEDURE
[id="microshift-deploying-a-load-balancer_{context}"]
= Deploying a load balancer for an application

[role="_abstract"]
To expose an application through a `LoadBalancer` service that uses the node IP as the external IP in {microshift-short}, you can create a namespace, deploy the example workload, and apply the service manifest. 

.Prerequisites

* The {oc-first} is installed.
* You installed a node on an infrastructure configured with the OVN-Kubernetes network plugin.
* The `KUBECONFIG` environment variable is set.

.Procedure

. Verify that your pods are running by entering the following command:
+
[source,terminal]
----
$ oc get pods -A
----
+
.Example output
[source,terminal]
----
NAMESPACE                            NAME                                                     READY   STATUS   RESTARTS  AGE
default                              i-06166fbb376f14a8bus-west-2computeinternal-debug-qtwcr  1/1     Running	   0		   46m
kube-system                          csi-snapshot-controller-5c6586d546-lprv4                 1/1     Running	   0		   51m
openshift-dns                        dns-default-45jl7                                        2/2     Running	   0		   50m
openshift-dns                        node-resolver-7wmzf                                      1/1     Running	   0		   51m
openshift-ingress                    router-default-78b86fbf9d-qvj9s                          1/1     Running 	 0		   51m
openshift-multus                     dhcp-daemon-j7qnf                                        1/1     Running    0		   51m
openshift-multus                     multus-r758z                                             1/1     Running    0		   51m
openshift-operator-lifecycle-manager catalog-operator-85fb86fcb9-t6zm7                        1/1     Running    0		   51m
openshift-operator-lifecycle-manager olm-operator-87656d995-fvz84                             1/1     Running    0		   51m
openshift-ovn-kubernetes             ovnkube-master-5rfhh                                     4/4     Running    0		   51m
openshift-ovn-kubernetes             ovnkube-node-gcnt6                                       1/1     Running    0		   51m
openshift-service-ca                 service-ca-bf5b7c9f8-pn6rk                               1/1     Running    0		   51m
openshift-storage                    topolvm-controller-549f7fbdd5-7vrmv                      5/5     Running    0		   51m
openshift-storage                    topolvm-node-rht2m                                       3/3     Running    0		   50m
----

. Create a namespace by running the following commands:
+
[source,terminal]
----
$ NAMESPACE=_<nginx_lb_test>_
----
+
* Replace _<nginx_lb_test>_ with the application namespace that you want to create.
+
[source,terminal]
----
$ oc create ns $NAMESPACE
----
+
The following example deploys three replicas of the test `nginx` application in the created namespace:
+
[source,terminal]
----
oc apply -n $NAMESPACE -f - <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx
data:
  headers.conf: |
    add_header X-Server-IP  \$server_addr always;
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: quay.io/packit/nginx-unprivileged
        imagePullPolicy: Always
        name: nginx
        ports:
        - containerPort: 8080
        volumeMounts:
        - name: nginx-configs
          subPath: headers.conf
          mountPath: /etc/nginx/conf.d/headers.conf
        securityContext:
          allowPrivilegeEscalation: false
          seccompProfile:
            type: RuntimeDefault
          capabilities:
            drop: ["ALL"]
          runAsNonRoot: true
      volumes:
        - name: nginx-configs
          configMap:
            name: nginx
            items:
              - key: headers.conf
                path: headers.conf
EOF
----

. You can verify that the three sample replicas started successfully by running the following command:
+
[source,terminal]
----
$ oc get pods -n $NAMESPACE
----

. Create a `LoadBalancer` service for the `nginx` test application by running the following command:
+
[source,terminal]
----
oc create -n $NAMESPACE -f - <<EOF
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  ports:
  - port: 81
    targetPort: 8080
  selector:
    app: nginx
  type: LoadBalancer
EOF
----
+
[NOTE]
====
You must ensure that the `port` parameter is a host port that is not occupied by other `LoadBalancer` services or {microshift-short} components.
====

. Verify that the service file exists, that the external IP address is properly assigned, and that the external IP is identical to the node IP by running the following command:
+
[source,terminal]
----
$ oc get svc -n $NAMESPACE
----
+
.Example output
[source,terminal]
----
NAME    TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)        AGE
nginx   LoadBalancer   10.43.183.104   192.168.1.241   81:32434/TCP   2m
----

.Verification

The following command forms five connections to the example `nginx` application by using the external IP address of the `LoadBalancer` service configuration. The result of the command is a list of those server IP addresses.

* Verify that the load balancer sends requests to all the running applications by running the following command:
+
[source,terminal]
----
EXTERNAL_IP=192.168.1.241
seq 5 | xargs -Iz curl -s -I http://$EXTERNAL_IP:81 | grep X-Server-IP
----
+
The output of the previous command contains different IP addresses if the `LoadBalancer` service is successfully distributing the traffic to the applications, for example:
+
.Example output
[source,terminal]
----
X-Server-IP: 10.42.0.41
X-Server-IP: 10.42.0.41
X-Server-IP: 10.42.0.43
X-Server-IP: 10.42.0.41
X-Server-IP: 10.42.0.43
----