Kubernetes loadbalancer with dedicated servers - kubernetes

I have a problem with setting kubernetes loadbalancer/ingress(under port 80 for example).
I don't use it with any cloud, just VPS servers with only one IP per server.
I'm was trying install traefik but I don't get external-ip - it's stuck on pending.
I have read that I need something when simulating loadbalancer so I installed MetalLB but it more dedicated from local network not VPS servers and didn't work for me or I can't configure it.
My config-map for MetalLB:
apiVersion: v1
kind: ConfigMap
metadata:
namespace: default
name: config
data:
config: |
address-pools:
- name: default
protocol: layer2
addresses:
- node1_ip
- node2_ip
- node3_ip
What I should do to on that cluster to be able to expose websites under normal port type 80, or can using reverse proxy like traefik.

You should not put node_ip addresses to MetalLB config file. You need to modify this to match the IP scheme of the network you are connected to with subnet. LoadBalancer IP addresses will be distributed from this range.
Something like below:
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:
- name: metallb-system
protocol: layer2
addresses:
- 192.168.1.240/28

Related

Can an `ExternalName` service point to the host machine?

I'm working locally (within Docker for Mac) on a Kubernetes cluster that will eventually be deployed to the cloud. We plan to use a database service in that environment. To simulate that, I'd like to have the services in the cluster connect to a database running outside the cluster on my laptop.
Can I do that? Here's what I thought I'd try.
Define a Service with type: ExternalName and externalName: somedb.local
Add 127.0.0.1 somedb.local to /etc/hosts on the laptop
Is that correct? Is there a better way?
After talking with some colleagues, I found a solution.
In Docker for Mac, host.docker.internal points to the host machine, and that lets me connect to the db running there, even from containers running in the K8s cluster.
You may have a Service pointing to an address out of your SDN, by creating an Endpoint object with matching name.
----
apiVersion: v1
kind: Service
metadata:
name: external-db
namespace: my-namespace
spec:
ports:
- name: exporter-3306
port: 3306
selector:
name: external-db
---
apiVersion: v1
kind: Endpoints
metadata:
name: external-db
namespace: my-namespace
subsets:
- addresses:
- ip: 10.42.253.110
ports:
- name: exporter-3306
port: 3306
You may add hosts overrides in your Deployment definition:
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
...
hostAliases:
- ip: 10.42.253.110
hostnames:
- external-db
It seems the Kubernetes docs provide an instruction on how to achieve this.
https://kubernetes.io/docs/concepts/services-networking/service/#services-without-selectors
A note says endpoint IPs must not be: loopback (127.0.0.0/8 for IPv4, ::1/128 for IPv6), or link-local (169.254.0.0/16 and 224.0.0.0/24 for IPv4, fe80::/64 for IPv6).

Metallb Kubernetes Loadbalancer fails without the port

I'm using Metallb for a bare-metal kubernetes cluster.
I've modified the configmap as below,
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:
#- name: default
#protocol: layer2
#addresses:
#- 192.168.1.240-192.168.1.250
- addresses:
- <Public_IP_01>/32
- <Public_IP_02>/32
- <Public_IP_03>/32
name: prod
protocol: layer2
And however the right ip is assigned, it's not reachable at http://<Public_IP_01>, but it's reachable through http://<Public_IP_01>:31158. I feel like it's working as nodeport not the load balancer
k get svc -A
default nginx-service LoadBalancer 10.98.4.122 <Public_IP_01> 80:31158/TCP 7m3s
Any ideas how to enforce traffic on port 80.
Thanks,

Configure metallb with kubernetes running on different vps servers

I have a running Kubernetes cluster consists of 3 nodes and one mater running on a VPS server, each node and master has its own public IP and floating IP also assigned to it and all these IPs are different from other
I am trying to configure metallb as a load balancer for my Kubernetes cluster but I don't know how can I set the metalLb IPs to range in the configuration file
here are the IPs examples of my servers
115.203.150.255
94.217.238.58
46.12.5.65
76.47.79.44
as you can see here, each IP is different so how can I set the Ip ranges in metallb config map?
Here an example of a config map
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:
- name: default
protocol: layer2
addresses:
- PUBLIC_IP-PUBLIC_IP
In the Metallb documentation there is a mention you can use certain IPs metallb.universe.tf/address-pool. See here
apiVersion: v1
kind: Service
metadata:
name: nginx
annotations:
metallb.universe.tf/address-pool: production-public-ips
spec:
ports:
- port: 80
targetPort: 80
selector:
app: nginx
type: LoadBalancer
The production-public-ips must be configured as showed here.
To configure MetalLB, you should create a configmap with your ips. Since you don't have the range, you can set /32 as subnet for your ips, like the example below.
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:
- name: production-public-ips
protocol: layer2
addresses:
- 115.203.150.255/32
- 94.217.238.58/32
- 46.12.5.65/32
- 76.47.79.44/32
It should work for your scenario.
I have the same problem with VPS in different countries, but NGINX ingress controller bare metal considerations doesn't allow IP NODE as IP/32 range in "addresses".
https://kubernetes.github.io/ingress-nginx/deploy/baremetal/
MetalLB requires a pool of IP addresses in order to be able to take
ownership of the ingress-nginx Service. This pool can be defined in a
ConfigMap named config located in the same namespace as the MetalLB
controller. This pool of IPs must be dedicated to MetalLB's use, you
can't reuse the Kubernetes node IPs or IPs handed out by a DHCP
server.

MetalLB External IP to Internet

I can't access to public IP assigned by MetalLB load Balancer
I created a Kubernetes cluster in Contabo. Its 1 master and 2 workers. Each one has its own public IP.
I did it with kubeadm + flannel. Later I did install MetalLB to use Load Balancing.
I used this manifest for installing nginx:
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: nginx
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1
ports:
- name: http
containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
ports:
- name: http
port: 8080
protocol: TCP
targetPort: 80
selector:
app: nginx
type: LoadBalancer
It works, pods are running. I see the external IP adress after:
kubectl get services
From each node/host I can curl to that ip and port and I can get nginx's:
<h1>Welcome to nginx!</h1>
So far, so good. BUT:
What I still miss is to access to that service (nginx) from my computer.
I can try to access to each node (master + 2 slaves) by their IP:PORT and nothing happens. The final goal is to have a domain that access to that service but I can't guess witch IP should I use.
What I'm missing?
Should MetalLB just expose my 3 possible IPs?
Should I add something else on each server as a reverse proxy?
I'm asking this here because all articles/tutorials on baremetal/VPS (non aws,GKE, etc...) do this on a kube on localhost and miss this basic issue.
Thanks.
I am having the very same hardware layout:
a 3-Nodes Kubernetes Cluster - here with the 3 IPs:
| 123.223.149.27
| 22.36.211.68
| 192.77.11.164 |
running on (different) VPS-Providers (connected to a running cluster(via JOIN), of course)
Target: "expose" the nginx via metalLB, so I can access my web-app from outside the cluster via browser via the IP of one of my VPS'
Problem: I do not have a "range of IPs" I could declare for the metallb
Steps done:
create one .yaml file for the Loadbalancer, the kindservicetypeloadbalancer.yaml
create one .yaml file for the ConfigMap, containing the IPs of the 3 nodes, the kindconfigmap.yaml
``
### start of the kindservicetypeloadbalancer.yaml
### for ensuring a unique name: loadbalancer name nginxloady
apiVersion: v1
kind: Service
metadata:
name: nginxloady
annotations:
metallb.universe.tf/address-pool: production-public-ips
spec:
ports:
- port: 80
targetPort: 80
selector:
app: nginx
type: LoadBalancer
``
below, the second .yaml file to be added to the Cluster:
# start of the kindconfigmap.yaml
## info: the "production-public-ips" can be found
## within the annotations-sector of the kind: Service type: loadbalancer / the kindservicetypeloadbalancer.yaml
## as well... ...namespace: metallb-system & protocol: layer2
## note: as you can see, I added a /32 after every of my node-IPs
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:
- name: production-public-ips
protocol: layer2
addresses:
- 123.223.149.27/32
- 22.36.211.68/32
- 192.77.11.164/32
``
add the LoadBalancer:
kubectl apply -f kindservicetypeloadbalancer.yaml
add the ConfigMap:
kubectl apply -f kindconfigmap.yaml
Check the status of the namespace ( "n" ) metallb-system:
kubectl describe pods -n metallb-system
PS:
actually it is all there:
https://metallb.universe.tf/installation/
and here:
https://metallb.universe.tf/usage/#requesting-specific-ips
What you are missing is a routing policy
Your external IP addresses must belong to the same network as your nodes or instead of that you can add a route to your external address at your default gateway level and use a static NAT for each address

Minikube expose MySQL running on localhost as service

I have minikube version v0.17.1 running on my machine. I want to simulate the environment I will have in AWS, where my MySQL instance will be outside of my Kubernetes cluster.
Basically, how can I expose my local MySQL instance running on my machine to the Kubernetes cluster running via minikube?
Kubernetes allows you to create a service without selector, and cluster will not create related endpoint for this service, this feature is usually used to proxy a legacy component or an outside component.
Create a service without selector
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
ports:
- protocol: TCP
port: 1443
targetPort: <YOUR_MYSQL_PORT>
Create a relative Endpoint object
apiVersion: v1
kind: Endpoints
metadata:
name: my-service
subsets:
- addresses:
- ip: <YOUR_MYSQL_ADDR>
ports:
- port: <YOUR_MYSQL_PORT>
Get service IP
$ kubectl get svc my-service
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-service <SERVICE_IP> <none> 1443/TCP 18m
Access your MYSQL from service <SERVICE_IP>:1443 or my-service:1443
As of minikube 1.10, there is a special hostname host.minikube.internal that resolves to the host running the minikube VM or container. You can then configure this hostname in your pod's environment variables or the ConfigMap that defines the relevant settings.
Option 1 - use a headless service without selectors
Because this service has no selector, the corresponding Endpoints object will not be created. You can manually map the service to your own specific endpoints (See doc).
kind: Service
apiVersion: v1
metadata:
name: my-service
spec:
ports:
- port: 80
targetPort: 8080
---
kind: Endpoints
apiVersion: v1
metadata:
name: my-service
subsets:
- addresses:
- ip: 10.0.2.2
ports:
- port: 8080
Option 2 - use ExternalName service
kind: Service
apiVersion: v1
metadata:
name: my-service
spec:
type: ExternalName
externalName: minikube.host
The only caveat is that it needs to be able to resolve minikube.host. Simply add this line to the etc/hosts file should do it.
10.0.2.2 minikube.host
ExternalName doesn't support port mapping at the moment.
Another note: The IP 10.0.2.2 is known to work with Virtual Box only (see SO).
For xhyve, try replacing that with 192.168.99.1 (see GitHub issue and issue). A demo GitHub.
Just a reminder, if on Windows, open your firewall.