Kubernetes Bare-Metal: Load Balancer and Ingress

Load Balancer and Ingress

A configuration directory layout used in this page is shown as follows:

> kubernetes
  > config                                <- configurations
  > metallb-operator                      <- MetalLB operator repository
  > nginx-ingress-helm-operator           <- Nginx Ingress operator repository

MetalLB Load Balancer

Bare-metal cluster operators are left with two lesser tools to bring user traffic into their clusters, “NodePort” and “externalIPs” services. Both of these options have significant downsides for production use, which makes bare-metal clusters second-class citizens in the Kubernetes ecosystem.
MetalLB aims to redress this imbalance by offering a network load balancer implementation that integrates with standard network equipment, so that external services on bare-metal clusters also “just work” as much as possible.

To deploy MetalLB, follow this steps:

  • Clone MetalLB Operator repository

    git clone https://github.com/metallb/metallb-operator.git
  • Deploy the operator

    kubectl apply -f metallb-operator/bin/metallb-operator.yaml
    namespace/metallb-system created
    customresourcedefinition.apiextensions.k8s.io/addresspools.metallb.io created
    customresourcedefinition.apiextensions.k8s.io/bfdprofiles.metallb.io created
    customresourcedefinition.apiextensions.k8s.io/bgpadvertisements.metallb.io created
    customresourcedefinition.apiextensions.k8s.io/bgppeers.metallb.io created
    customresourcedefinition.apiextensions.k8s.io/communities.metallb.io created
    customresourcedefinition.apiextensions.k8s.io/ipaddresspools.metallb.io created
    customresourcedefinition.apiextensions.k8s.io/l2advertisements.metallb.io created
    customresourcedefinition.apiextensions.k8s.io/metallbs.metallb.io created
    serviceaccount/manager-account created
    role.rbac.authorization.k8s.io/metallb-manager-role created
    clusterrole.rbac.authorization.k8s.io/metallb-manager-role created
    rolebinding.rbac.authorization.k8s.io/metallb-manager-rolebinding created
    clusterrolebinding.rbac.authorization.k8s.io/metallb-manager-rolebinding created
    secret/metallb-operator-webhook-server-cert created
    secret/webhook-server-cert created
    service/metallb-operator-webhook-service created
    service/webhook-service created
    deployment.apps/metallb-operator-controller-manager created
    deployment.apps/metallb-operator-webhook-server created
    validatingwebhookconfiguration.admissionregistration.k8s.io/metallb-operator-webhook-configuration created
    validatingwebhookconfiguration.admissionregistration.k8s.io/metallb-webhook-configuration created
    serviceaccount/controller created
    serviceaccount/speaker created
    role.rbac.authorization.k8s.io/controller created
    role.rbac.authorization.k8s.io/pod-lister created
    role.rbac.authorization.k8s.io/speaker created
    clusterrole.rbac.authorization.k8s.io/metallb-system:kube-rbac-proxy created
    clusterrole.rbac.authorization.k8s.io/metallb-system:controller created
    clusterrole.rbac.authorization.k8s.io/metallb-system:speaker created
    rolebinding.rbac.authorization.k8s.io/controller created
    rolebinding.rbac.authorization.k8s.io/pod-lister created
    rolebinding.rbac.authorization.k8s.io/speaker created
    clusterrolebinding.rbac.authorization.k8s.io/kube-rbac-proxy created
    clusterrolebinding.rbac.authorization.k8s.io/metallb-system:controller created
    clusterrolebinding.rbac.authorization.k8s.io/metallb-system:speaker created
  • Create MetalLB instance, ip address pool, and L2 advertisement

    vi config/metallb.yaml
    apiVersion: metallb.io/v1beta1
    kind: MetalLB
    metadata:
    name: metallb
    namespace: metallb-system
    ---
    apiVersion: metallb.io/v1beta1
    kind: IPAddressPool
    metadata:
    name: lb-ip-pool
    namespace: metallb-system
    spec:
    addresses:
    - 10.0.0.21-10.0.0.31
    ---
    apiVersion: metallb.io/v1beta1
    kind: L2Advertisement
    metadata:
    name: lb-l2
    namespace: metallb-system
    spec:
    ipAddressPools:
    - lb-ip-pool
    kubectl apply -f config/metallb.yaml
    metallb.metallb.io/metallb created
    ipaddresspool.metallb.io/lb-ip-pool created
    l2advertisement.metallb.io/lb-l2 created

Nginx Ingress Controller

The NGINX Ingress Controller is an Ingress Controller implementation for NGINX and NGINX Plus that can load balance Websocket, gRPC, TCP and UDP applications. It supports standard Ingress features such as content-based routing and TLS/SSL termination. Several NGINX and NGINX Plus features are available as extensions to Ingress resources through Annotations and the ConfigMap resource.

To deploy Nginx Ingress Controller, follow this steps:

  • Clone Nginx Ingress Operator repository

    git clone https://github.com/nginxinc/nginx-ingress-helm-operator.git
  • Apply CRD for Nginx Ingress

    kubectl apply -f nginx-ingress-helm-operator/helm-charts/nginx-ingress/crds/
    customresourcedefinition.apiextensions.k8s.io/aplogconfs.appprotect.f5.com created
    customresourcedefinition.apiextensions.k8s.io/appolicies.appprotect.f5.com created
    customresourcedefinition.apiextensions.k8s.io/apusersigs.appprotect.f5.com created
    customresourcedefinition.apiextensions.k8s.io/apdoslogconfs.appprotectdos.f5.com created
    customresourcedefinition.apiextensions.k8s.io/apdospolicies.appprotectdos.f5.com created
    customresourcedefinition.apiextensions.k8s.io/dosprotectedresources.appprotectdos.f5.com created
    customresourcedefinition.apiextensions.k8s.io/dnsendpoints.externaldns.nginx.org created
    customresourcedefinition.apiextensions.k8s.io/globalconfigurations.k8s.nginx.org created
    customresourcedefinition.apiextensions.k8s.io/policies.k8s.nginx.org created
    customresourcedefinition.apiextensions.k8s.io/transportservers.k8s.nginx.org created
    customresourcedefinition.apiextensions.k8s.io/virtualserverroutes.k8s.nginx.org created
    customresourcedefinition.apiextensions.k8s.io/virtualservers.k8s.nginx.org created
  • Deploy Nginx Ingress Operator

    cd nginx-ingress-helm-operator && make deploy IMG=nginx/nginx-ingress-operator:2.2.0
    cd config/manager && /home/user/kubernetes/nginx-ingress-helm-operator/bin/kustomize edit set image controller=nginx/nginx-ingress-operator:2.2.0
    /home/user/kubernetes/nginx-ingress-helm-operator/bin/kustomize build config/default | kubectl apply -f -
    namespace/nginx-ingress-operator-system created
    customresourcedefinition.apiextensions.k8s.io/nginxingresses.charts.nginx.org created
    serviceaccount/nginx-ingress-operator-controller-manager created
    role.rbac.authorization.k8s.io/nginx-ingress-operator-leader-election-role created
    clusterrole.rbac.authorization.k8s.io/nginx-ingress-operator-manager-role created
    clusterrole.rbac.authorization.k8s.io/nginx-ingress-operator-metrics-reader created
    clusterrole.rbac.authorization.k8s.io/nginx-ingress-operator-nginx-ingress-admin created
    clusterrole.rbac.authorization.k8s.io/nginx-ingress-operator-proxy-role created
    rolebinding.rbac.authorization.k8s.io/nginx-ingress-operator-leader-election-rolebinding created
    clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-operator-manager-rolebinding created
    clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-operator-proxy-rolebinding created
    service/nginx-ingress-operator-controller-manager-metrics-service created
    deployment.apps/nginx-ingress-operator-controller-manager created
  • Install default TLS certificate

    The certificate can be created directly using:

    kubectl create secret tls nginx-default-certs -n default --cert=cert.crt-combined --key=cert.key

    Or, from config map:

    vi config/nginx-ingress-certs.yaml
    apiVersion: v1
    kind: Secret
    metadata:
    name: nginx-default-certs
    namespace: default
    type: kubernetes.io/tls
    data:
    tls.crt: ...
    tls.key: ...
    kubectl apply -f config/nginx-ingress-certs.yaml
    secret/nginx-default-certs created
  • Deploy Nginx Ingress Controller

    vi config/nginx-ingress-controller.yaml
    kind: Namespace
    apiVersion: v1
    metadata:
    name: nginx-ingress
    ---
    apiVersion: charts.nginx.org/v1alpha1
    kind: NginxIngress
    metadata:
    name: nginx-ingress
    namespace: nginx-ingress
    spec:
    controller:
      defaultTLS:
        secret: default/nginx-default-certs
      enableCustomResources: true
      image:
        pullPolicy: IfNotPresent
        repository: nginx/nginx-ingress
        tag: 3.4.0-ubi
      ingressClass:
        name: nginx
      kind: deployment
      nginxplus: false
      replicaCount: 1
      wildcardTLS:
        secret: default/nginx-default-certs
    rbac:
      create: true
    kubectl apply -f config/nginx-ingress-controller.yaml
    namespace/nginx-ingress created
    nginxingress.charts.nginx.org/nginx-ingress created
  • Verify Nginx Ingress Controller is running

    kubectl get pod -n nginx-ingress -o wide
    NAME                                        READY   STATUS    RESTARTS   AGE     IP             NODE            NOMINATED NODE   READINESS GATES
    nginx-ingress-controller-74cbbbddd8-8vm4w   1/1     Running   0          6d15h   10.244.171.0   k8s-node-five              

What's Next

Accessing cluster using Dashboard
Initialize or upgrade cluster

Leave a Reply