Use MetalLB with Oracle Cloud Native Environment

0
0
Send lab feedback

Use MetalLB with Oracle Cloud Native Environment

Introduction

Network load balancers provide a method of externally exposing Kubernetes applications. A Kubernetes LoadBalancer service creates a network load balancer that provides and exposes an external IP address for connecting to an application from outside the cluster.

MetalLB is a network load balancer for Kubernetes applications deployed with Oracle Cloud Native Environment that runs on bare metal hosts. MetalLB allows you to use Kubernetes LoadBalancer services, which traditionally use a cloud provider's network load balancer, in bare metal environments.

Objectives

At the end of this tutorial, you should be able to set up and use the MetalLB module for Kubernetes applications using MetalLB and Oracle Cloud Native Environment.

Prerequisites

The free lab environment uses the following host systems:

  • 6 Oracle Linux instances for Oracle Cloud Native Environment:

    • Operator node (ocne-operator)
    • 3 Kubernetes control plane nodes (ocne-control-01, ocne-control-02, ocne-control-03 )
    • 2 Kubernetes worker nodes (ocne-worker-01, ocne-worker-02)

    Note: We recommend that production environments have a cluster with at least five control plane nodes and three worker nodes.

  • A virtual IP address for the primary control plane node. Do not use this IP address on any of the nodes. The load balancer dynamically sets the IP address to the control plane node assigned as the primary controller.

    Note: If you are deploying to Oracle Cloud Infrastructure, your tenancy requires enabling a new feature introduced in OCI: Layer 2 Networking for VLANs within your virtual cloud networks (VCNs). The OCI Layer 2 Networking feature is not generally available, although the free lab environment's tenancy enables this feature.

    If you have a use case, please work with your technical team to get your tenancy listed to use this feature.

  • Configure each system with the following:

    • The latest Oracle Linux with the Unbreakable Enterprise Kernel Release 7 (UEK R7)
    • An oracle user account with sudo access
    • Key-based SSH, also known as passwordless SSH, between the instances
    • Install Oracle Cloud Native Environment ready for creating the environment and installing modules
    • Create a VLAN and assign IPv4 addresses

Set Up the Lab Environment

Note: When using the free lab environment, see Oracle Linux Lab Basics for connection and other usage instructions.

Important: The free lab environment deploys a fully installed Oracle Cloud Native Environment across the provided nodes. This deployment takes approximately 25-30 minutes to finish after launch. Therefore, you might want to step away while this runs and then return to complete the lab.

  1. Open a terminal and connect via ssh to the ocne-operator node.

    ssh oracle@<ip_address_of_operator_node>
  2. Verify you can run the Kubernetes command line tool.

    ssh ocne-control-01 kubectl get nodes

    The ssh is required before the kubectl command because the kubectl utility installs on the control plane nodes as part of the free lab deployment. The output displays a list of the nodes, along with their status, role, and version.

Install the MetalLB Module

  1. Open the firewall for MetalLB on each of the worker nodes.

    for host in ocne-worker-01 ocne-worker-02 ocne-worker-03
    do
      ssh $host "sudo firewall-cmd --zone=public --add-port=7946/tcp --permanent; sudo firewall-cmd --zone=public --add-port=7946/udp --permanent; sudo firewall-cmd --reload"
    done
  2. Avoid using the --api-server flag in future olcnectl commands.

    Get a list of the module instances and add the --update-config flag.

    olcnectl module instances \
    --config-file myenvironment.yaml \
    --update-config
  3. Create the MetalLB configuration file.

    cat << 'EOF' | tee metallb-config.yaml
    apiVersion: metallb.io/v1beta1
    kind: IPAddressPool
    metadata:
      name: default
      namespace: metallb
    spec:
       addresses:
       - 10.0.12.240-10.0.12.250
    ---
    apiVersion: metallb.io/v1beta1
    kind: L2Advertisement
    metadata:
      name: l2sample
      namespace: metallb
    spec:
      ipAddressPools:
      - default
    EOF
  4. Deploy the MetalLB module.

    olcnectl module create --environment-name myenvironment --module metallb --name mymetallb --metallb-kubernetes-module mycluster --metallb-config metallb-config.yaml
    olcnectl module install --environment-name myenvironment --name mymetallb
  5. Show the installed modules.

    olcnectl module instances --environment-name myenvironment

    Example Output:

    [oracle@ocne-operator ~]$ olcnectl module instances --environment-name myenvironment
    INSTANCE       	MODULE    	STATE    
    mycluster      	kubernetes	installed
    mymetallb      	metallb   	installed
    ...

Create a Kubernetes Application

In this section, you create a Kubernetes application that uses a LoadBalancer service.

  1. Switch to the control-plane-01 node terminal session.

  2. Create a Kubernetes application.

    tee echo-oci-lb.yml > /dev/null << 'EOF'
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: echo-deployment
      labels:
        app: echo1
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: echo1
      template:
        metadata:
          labels:
            app: echo1
        spec:
          containers:
          - name: echoserver
            image: k8s.gcr.io/echoserver:1.4
            ports:
            - containerPort: 80
    ---
    kind: Service
    apiVersion: v1
    metadata:
      name: echo-lb-service
    spec:
      selector:
        app: echo1
      type: LoadBalancer
      ports:
      - name: http
        port: 80
        targetPort: 8080
    EOF
  3. Create the service.

    kubectl apply -f echo-oci-lb.yml

    Example Output:

    [oracle@ocne-control-01 ~]$ kubectl apply -f echo-oci-lb.yml
    deployment.apps/echo-deployment created
    service/echo-lb-service created
  4. Confirm the Kubernetes deployment is running.

    kubectl get deployments

    Example Output:

    [oracle@ocne-control-01 ~]$ kubectl get deployment      
    NAME              READY   UP-TO-DATE   AVAILABLE   AGE
    echo-deployment   2/2     2            2           3m15s
  5. Show the Kubernetes service is running.

    kubectl get svc

    Example Output:

    [oracle@ocne-control-01 ~]$ kubectl get svc
    NAME              TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
    echo-lb-service   LoadBalancer   10.111.72.49   10.0.12.240   80:31727/TCP   4m47s
    kubernetes        ClusterIP      10.96.0.1      <none>        443/TCP        58m

    Notice the EXTERNAL-IP for the echo-lb-service LoadBalancer has an IP address of 10.0.12.240. MetalLB provides this IP address and is the external IP address that you can use to connect to the application.

Testing the Deployment

The next step is to test the newly deployed application. As the EXTERNAL-IP value is dynamically provisioned by MetalLB (in this scenario between the range 10.0.12.240-10.0.12.250), the first two steps store this dynamic value as operating system variables.

  1. Capture the assigned EXTERNAL-IP address.

    LB=$(kubectl get svc -o jsonpath="{.status.loadBalancer.ingress[0].ip}" echo-lb-service)
  2. Capture the port number assigned.

    LBPORT=$(kubectl get svc -o jsonpath="{.spec.ports[0].port}" echo-lb-service)
  3. Confirm the environment variables exist.

    echo $LB
    echo $LBPORT

    Example Output:

    [oracle@ocne-control-01 ~]$ echo $LB
    10.0.12.240
    [oracle@ocne-control-01 ~]$ echo $LBPORT
    80
  4. Use curl to connect to the deployed application.

    curl -i -w "\n" $LB:$LBPORT

    Example Output:

    [oracle@ocne-control-01 ~]$ curl -i -w "\n" $LB:$LBPORT
    HTTP/1.1 200 OK
    Server: nginx/1.10.0
    Date: Wed, 10 Aug 2022 10:52:10 GMT
    Content-Type: text/plain
    Transfer-Encoding: chunked
    Connection: keep-alive
    
    CLIENT VALUES:
    client_address=10.244.2.0
    command=GET
    real path=/
    query=nil
    request_version=1.1
    request_uri=http://10.0.12.240:8080/
    
    SERVER VALUES:
    server_version=nginx: 1.10.0 - lua: 10001
    
    HEADERS RECEIVED:
    accept=*/*
    host=10.0.12.240
    user-agent=curl/7.61.1
    BODY:
    -no body in request-

Test From a Non-Kubernetes Host

  1. Switch to the ocne-operator node terminal session.

  2. This last test confirms that MetalLB is responding to external requests.

    curl -v http://10.0.12.240:80

    Example Output:

    [oracle@ocne-operator ~]$ curl -v http://10.0.12.240:80
    * Rebuilt URL to: http://10.0.12.240:80/
    *   Trying 10.0.12.240...
    * TCP_NODELAY set
    * Connected to 10.0.12.240 (10.0.12.240) port 80 (#0)
    > GET / HTTP/1.1
    > Host: 10.0.12.240
    > User-Agent: curl/7.61.1
    > Accept: */*
    > 
    < HTTP/1.1 200 OK
    < Server: nginx/1.10.0
    < Date: Wed, 10 Aug 2022 11:38:08 GMT
    < Content-Type: text/plain
    < Transfer-Encoding: chunked
    < Connection: keep-alive
    < 
    CLIENT VALUES:
    client_address=10.244.0.0
    command=GET
    real path=/
    query=nil
    request_version=1.1
    request_uri=http://10.0.12.240:8080/
    
    SERVER VALUES:
    server_version=nginx: 1.10.0 - lua: 10001
    
    HEADERS RECEIVED:
    accept=*/*
    host=10.0.12.240
    user-agent=curl/7.61.1
    BODY:
    * Connection #0 to host 10.0.12.240 left intact

Summary

These results confirm the successful configuration of MetalLB and the ability to accept application requests.

For More Information

SSR