Why is there an ADDRESS for the ingress-service? What's the use of that ADDRESS? - kubernetes

I deploy my cluster on GKE with an Ingress Controller
I use Helm to install the following:
Installed Ingress Controller
Deployed Load Balancer Service (Create a Load Balancer on GCP as well)
I also deployed the Ingress Object (Config as below)
Then I observed the following status ...
The Ingress Controller is exposed (By Load Balancer Service) with two endpoints: 35.197.XX.XX:80, 35.197.XX.XX:443
These two endpoints are exposed by the Cloud load balancer.
I have no problem with it.
However, when I execute kubectl get ing ingress-service -o wide, it prints out the following info.
NAME HOSTS ADDRESS PORTS AGE
ingress-service k8s.XX.com.tw 34.87.XX.XX 80, 443 5h50m
I really don't under the use of the IP under the ADDRESS column.
I can also see that Google add some extra info to the end of my Ingress config file about load balancer IP for me.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
....(ommitted)
spec:
rules:
- host: k8s.XX.com.tw
http:
paths:
- backend:
serviceName: client-cluster-ip-service
servicePort: 3000
path: /?(.*)
- backend:
serviceName: server-cluster-ip-service
servicePort: 5000
path: /api/?(.*)
tls:
- hosts:
- k8s.XX.com.tw
secretName: XX-com-tw
status:
loadBalancer:
ingress:
- ip: 34.87.XX.XX
According to Google's doc, this (34.87.XX.XX) looks like an external IP, but I can't access it with http://34.87.XX.XX
My question is that since we already have an external IP (35.197.XX.XX) to receive the traffic, why do we need this ADDRESS for the ingress-service?
If it's an internal or external IP ADDRESS?
What is this ADDRESS bound to?
What exactly is this ADDRESS used for?
Can anyone shed some light? Thanks a lot!

If you simply go take a look at the documentation you will have your answer.
What is an ingress ressource: https://kubernetes.io/docs/concepts/services-networking/ingress/#what-is-ingress
So following the doc:
Ingress exposes HTTP and HTTPS routes from outside the cluster to services within the cluster. Traffic routing is controlled by rules defined on the Ingress resource.
To be more precise on cloud provider, the ingress will create a load-balancer to expose the service to the internet. The cocumentation on the subject specific to gke: https://cloud.google.com/kubernetes-engine/docs/tutorials/http-balancer
That explains why you have an external ip for the ingress.
What you should do now:
If you don't want to expose HTTP or/and HTTPS ports just delete the ingress ressource, you don't use it so it's pretty much useless.
If you are using HTTP/HTTPS ressources, change your service type to nodePort and leave the management of the load balancer to the ingress.
My opinion is that, as you are deploying the ingress-controller, you should select the second option and leave the management of the load-balancer to it. For the ingress of the ingress-controller, don't define rules just the backend to the nodePort service, the rules should be defined in specific ingress for each app and be managed by the ingress-controller.

Related

How to configure HAproxy Ingress controller in Kubernetes

So we have a SQL server deployment with replica=2 in K8s which I need to make load balanced. I'm using Haproxy ingress controller to achieve this goal but I'm stuck in configuring Haproxy. I'm trying to configure the Haproxy based on this link and I don't know how to present my two pods to the ingress!
There is this part of the link says:
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: web-ingress
namespace: default
spec:
rules:
- host: foo.bar
http:
paths:
- path: /
backend:
serviceName: app
servicePort: 80
The issue is that in "spec.rules.host" section, I don't have any domain rather I have two IPs belong to my SQL pods! How am I supposed to represent my pods to the ingress? Am I doing right?
I've looked it up alot, but no luck!
P.S: What is the best practice for Load Balancing SQL server?
A DNS system translates hostname to IPs.With a domain registered with DNS system you can add a mapping of hostname to IP in the /etc/hosts file of the system from where you want to access the hostname.

Ingress expose the service with the type clusterIP

Is it possible to expose the service by ingress with the type of ClusterIP?
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-service
ports:
- name: my-service-port
port: 4001
targetPort: 4001
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: app-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: my.example.com
http:
paths:
- path: /my-service
backend:
serviceName: my-service
servicePort: 4001
I know the service can be exposed with the type of NodePort, but it may cost one more NAT connection, if someone could show me what's the fastest way to detect internal service from the world of internet in the cloud.
No, clusterIP is only reachable from within the cluster. An Ingress is essentially just a set of layer 7 forwarding rules, it does not handle the layer 4 requirements of exposing the internals of your cluster to the outside world. At least 1 NAT step is required.
For Ingress to work, though, you need to have at least one service involved that exposes your workload externally, so nodePort or loadBalancer. Your ingress controller and the infrastructure of your cluster will determine which of the two services you will need to use.
In the case of Nginx ingress, you need to have a single LoadBalancer service which the ingress will use to bridge traffic from outside the cluster to inside it. After that, you can use clusterIP services for each of your workloads.
In your above example, as long as the nginx ingress controller is correctly configured (with a loadbalancer), then the config you are using should work fine.
In short : YES
Now to the elaborate answer...
First thing first, let's have a look at what the official documentation says :
Ingress exposes HTTP and HTTPS routes from outside the cluster to services within the cluster.
[...]
An Ingress controller is responsible for fulfilling the Ingress, usually with a load balancer...
What's confusing here is the term Load balancer. In the definition above, we are talking about the classic and well known in the web load balancer.
This one has nothing to do with kubernetes !
So back to the definition, to use an Ingress and make it work, we need a kubernetes resource called IngressController. And this resource happen to be a load balancer ! That's it.
However, you have to keep in mind that there is a difference between a load balancer in the outside world and a kubernetes service of type type:LoadBalancer.
So in summary (and in order to redirect the traffic from the outside world to your k8s clusterIp service) :
Do you need a Load balancer to make your kind:Ingress works ? Yes, this is the kind:IngressController kubernetes resource.
Do you need a kubernetes service type:LoadBalancer or type:NodePort to make your kind:Ingress works ? Definitely no ! A service type:ClusterIP works just fine !

Difference between kunernetes Service and Ingress

I want to create a load balancer for 4 http server pods.
I have one mysql pod too.
Everything works fine, i have created a loadbalancer service for http, and another service for mysql.
I have read i should create an ingress too. But i do not understand what is an ingress because everything works with Services.
What is the value-add of an Ingress ?
Thanks
Since you have single service serving http, your current solution using LoadBalancer service type works fine. Imagine you have multiple http based services that you want to make externally available on different routes. You would have to create a LoadBalancer services for each of them and by default you would get a different IP address for each of them. Instead you can use an Ingress, which sits infront of these services and does the routing.
Example ingress manifest:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: test-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /cart
backend:
serviceName: cart
servicePort: 80
- path: /payment
backend:
serviceName: payment
servicePort: 80
Here you have two different HTTP services exposed by an Ingress on a single IP address. You don't need a LoadBalancer per service when using an Ingress.
The Service of type LoadBalancer relies on a third-party LoadBalancer and IP provisioning thing somewhere that deals with getting Layer 3 traffic (IP) from outside to the Nodes on some high-numbered NodePort.
A Ingress relies on a third-party Ingress Controller to accept Layer 3 traffic, open it up to Layer 7 (eg, terminate TLS) and do protocol-specific routing (eg by http fqdn/path) to some other Service (probably of type ClusterIP) inside the cluster.
If all your service should be explictly exposed without any further filtering or other options, a LoadBalancer and no Ingress might be the right choice....but LoadBalancers dont do much on their own....they just expose the Service to the outside world....very little in the way of traffic shpaing, A/B testing, etc
However, if you want to put multiple services behind a single IP/VIP/certificate, or you want to direct traffic in some weird ways (like based on Header:, client type, percentage weighting, etc), you'd probably want an Ingress (which itself would be exposed by a LoadBalancer Service)

Expose pod's tomcat port

I have the bare metall kubernetes pod running tomcat application on port 8085. If it would be common server, the app would be accessible via http://<server-ip>:8085/app. My goal is to expose the tomcat on Kubernetes node's address and the same port as used in tomcat.
I am able to expose and access app using Node Port service - but it is inconvenient that port is always different.
I tried to setup traefik ingress:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test-tag2
spec:
rules:
- host: kubernetes.example.com #in my conf I use node's domain name
http:
paths:
- path: /test
backend:
serviceName: test-tag2
servicePort: 8085
And I can see result in Traefik's dashboard, but still if I navigate to http://kubernetes.example.com/test/app I get nothing.
I've tried a bunch of ways to configure that and still no luck.
Is it actually possible to expose my pod in this way?
Did you try specifying a nodePort value in the service yaml? If specified, kubernetes will create service on the specified NodePort. If the nodePort is not available , kubernetes doesn't create the service.
Refer to this answer for more details:
https://stackoverflow.com/a/43944385/1237402

Whitelist an IP to access deployment with Kubernetes ingress Istio

I'm trying to whitelist an IP to access a deployment inside my Kubernetes cluster.
I looked for some documentation online about this, but I only found the
ingress.kubernetes.io/whitelist-source-range
for ingress to grant access to certain IP range. But still, I couldn't manage to isolate the deployment.
Here is the ingress configuration YAML file:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-internal
annotations:
kubernetes.io/ingress.class: "istio"
ingress.kubernetes.io/whitelist-source-range: "xxx.xx.xx.0/24, xx.xxx.xx.0/24"
spec:
rules:
- host: white.example.com
http:
paths:
- backend:
serviceName: white
servicePort: 80
I can access the deployment from my whitelisted IP and from the mobile phone (different IP not whitelisted in the config)
Has anyone stepped in the same problem using ingress and Istio?
Any help, hint, docs or alternative configuration will be much appreciated.
Have a look at the annotation overview, it seems that whitelist-source-range is not supported by istio:
whitelist-source-range: Comma-separate list of IP addresses to enable access to.
nginx, haproxy, trafficserver
I managed to solve whitelisting ip address problem for my istio-based service (app that uses istio proxy and exposed through the istio ingress gateway via public LB) using NetworkPolicy.
For my case, here is the topology:
Public Load Balancer (in GKE, using preserve clientIP mode) ==> A dedicated Istio Gateway Controller Pods (see my answer here) ==> My Pods (istio-proxy sidecar container, my main container).
So, I set up 2 network policy:
NetworkPolicy that guards the incoming connection from internet connection to my Istio Ingress Gateway Controller Pods. In my network policy configuration, I just have to set the spec.podSelector.matchLabels field to the pod label of Dedicated Istio Ingress Gateway Controller Pods's
Another NetworkPolicy that limits the incoming connection to my Deployment -> only from the Istio Ingress Gateway Controller pods/deployments.