How to access kubernetes services externally on bare-metal cluster

1/7/2020

I have a api-service with type 'ClusterIp' which is working fine and is accessible on the node with clusterip. I want to access it externally . It's a baremetal installation with kubeadm . I cannot use Loadbalancer or Nodeport.

If I use nginx-ingress that too I will use as 'ClusterIP' so how to get the service externally accessible in either api service or nginx-ingress case .

NAME                   TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
api                    ClusterIP   10.97.48.17      <none>        80/TCP           41s
ingress-nginx          ClusterIP   10.107.76.178    <none>        80/TCP           3h49m

Changes to solve the issue:

  1. nginx configuration on node

in /etc/nginx/sites-available

 upstream backend {
       server node1:8001;
       server node2:8001;
       server node3:8001;
        }
    server_name _;

    location / {
            proxy_pass http://backend;
            # First attempt to serve request as file, then
            # as directory, then fall back to displaying a 404.
            try_files $uri $uri/ =404;
    }
  1. Ran my two services as DaemonSet
-- Charvee Punia
bare-metal-server
kubeadm
kubernetes

2 Answers

1/7/2020

Well, as you can guess by reading the name, ClusterIp is only accessible from inside the cluster.

To make a service accessible from outside the cluster, you havec 3 options :

  1. NodePort Service type
  2. LoadBalancer Service type (you still have to manage your LoadBalancer manually though)
  3. Ingress

There is a fourth option which is hostPort (which is not a service type) but I'd rather keep it from special case when you're absolutely sure that your pod will always be located on the same node (or eventually for debug).

Having this said, then this leaves us only with one solution offered by Kubernetes : Ingress.

-- Marc ABOUCHACRA
Source: StackOverflow

1/7/2020

ClusterIP services are accesible only within the cluster.

For bare metal clusters, you can use any of the following approaches to make a service available externally. Suggestions are from most recommended to least recommended order:

  1. Use metallb to implement LoadBalancer service type support - https://metallb.universe.tf/. You will need a pool of IP addresses for metallb to handout. It also supports IP sharing mode where you can use same IP for multiple LoadBalancer services.

  2. Use NodePort service. You can access your service from any node IP:node_port address. NodePort service selects random port in node port range by default. You can choose a custom port in node port range using spec.ports.nodePort field in the service specification.

    Disadvantage: The node port range by default is 30000-32767. So you cannot bind to any custom port that you want like 8080. Although you can change the node port range with --service-node-port-range flag of kube-api-server, it is not recommended to use it with low port ranges.

  3. Use hostPort to bind a port on the node.

    Disadvantage: You don't have fixed IP address because you don't know which node your pod gets scheduled to unless you use nodeAffinity. You can make your pod a daemonset if you want it to be accessible from all nodes on the given port.

If you are dealing with HTTP traffic, another option is installing an IngressController like nginx or Traefik and use Ingress resource. As part of their installation, they use one of the approaches mentioned above to make themselves available externally.

-- Shashank V
Source: StackOverflow