I have a cluster with two nodes. I want to publish some services to internet. So I need to pin my domains to some address. Basically I understand, that I need to install ingress controller. But, am I right I need to glue ingress controller to the particular node?
Ingress controller helps to manage the ingress resources in the cluster. So along with the controller you need to create the ingress resources which will be the "glue" between the domain and the services(target application).
Please read here for more.
One sample from the documentation:
foo.bar.com/bar -> service1
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-wildcard-host
spec:
rules:
- host: "foo.bar.com"
http:
paths:
- pathType: Prefix
path: "/bar"
backend:
service:
name: service1
port:
number: 80
Related
I created an ingress service from the kubernetes documentation, but I found that not putting below annotation made service unavailable. Why was this so?
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/ssl-redirect: "false"
Main reason to ask this question was that in K8s documentation, I found below code for ingress, but this did not work until and unless I put the above annotation. So, why does the below code not work?
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-wear-watch
namespace: app-space
spec:
rules:
- http:
paths:
- path: /wear
pathType: Prefix
backend:
service:
name: wear-service
port:
number: 8080
- path: /watch
pathType: Prefix
backend:
service:
name: video-service
port:
number: 8080
Based on k8s docs, all you need to know in this specific case is that
you can use Kubernetes annotations to attach arbitrary non-identifying metadata to objects. Clients such as tools and libraries can retrieve this metadata.
[annotations are] Directives from the end-user to the implementations to modify behavior or engage non-standard features.
So basically this specific annotations are used to modify behaviour of ingress and are specififc to nginx ingress controller (this means that if you use different controller, this annotations wont work).
All supported annotations for nginx ingress controler are explained in Nginx Ingress Controller documention.
I have multiple pods, that scale up and down automatically.
I am using an ingress as entry point. I need to route external traffic to a specific pod base on some conditions (lets say path). At the point the request is made I am sure the specific pod is up.
For example lets say I have domain someTest.com, that normally routes traffic to pod 1, 2 and 3 (lets say I identify them by internal ips - 192.168.1.10, 192.168.1.11 and 192.168.1.13).
When I call someTest.com/specialRequest/12, I need to route the traffic to 192.168.1.12, when I call someTest.com/specialRequest/13, I want to route traffic to 192.168.1.13. For normal cases (someTest.com/normalRequest) I just want to do the lb do his epic job normally.
If pods scale up and 192.168.1.14 appears, I need to be able to call someTest.com/specialRequest/14 and be routed to the mentioned pod.
Is there anyway I can achieve this?
Yes, you can easily achieve this using Kubernetes Ingress. Here is a sample code that might help:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: app-ingress
spec:
rules:
- host: YourHostName.com
http:
paths:
- path: /
backend:
serviceName: Service1
servicePort: 8000
- path: /api
backend:
serviceName: Service2
servicePort: 8080
- path: /admin
backend:
serviceName: Service3
servicePort: 80
Please not that the ingress rules have serviceNames and not pod names, so you will have to create services for your pods. Here is an example for a service which exposes nginx as a service in Kubernetes:
apiVersion: v1
kind: Service
metadata:
name: nginx-service
labels:
io.kompose.service: nginx
spec:
ports:
- name: "80"
port: 80
targetPort: 80
selector:
io.kompose.service: nginx
I am not aware of built-in functionality to implement this (if this is what your really want). You can achieve this by building your own operator for Kubernetes. Your operator may provision a Pod+Ingress combo which will do exactly what you want - forward your traffic to a single pod, or you can provision 2 pods and 1 ingress to achive HA setup.
Depending on the Ingress you are using, it also may be possible to group multiple ingress resources under the same load balancer.
Here is a brief diagram of how this could look like.
would it be feasible to create another application
that can get the path and target the pod directly via
a pattern in the naming convention? for example
${podnamePrefix+param}.${service name}.${namespace}.svc.cluster.local
I have a deployment which is WEB API. I apply it to Kubernetes. Then add service.yml file to expose it. It is working. I have 12 microservices. All of them have service and deployment .yaml files.
So what is Ingress controller. Why should I use it?
(Except sidecar proxy like istio. Its perfect for resilince and metrics.)
In order for the Ingress resource to work, the cluster must have an ingress controller running. The controller can be for example Nginx Ingress Controller and it can be adjusted in various ways. After you have deployed the controller, all you need is an Ingress resource object deployed in K8s.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-sample
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: web-api
port:
number: 80
service.name: web-api is the place where you specify link between the ingress and the service.
So I have two clusters at the moment (soon to be a few more, once I get this working), ClusterA and ClusterB.
Is it possible for one ingress to interface with services from both clusters?
ClusterA hosts the front end and the ingress, while ClusterB hosts the back end.
The excerpted ingress is below. Everything bar the back end works.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:{...}
selfLink: /apis/extensions/v1beta1/namespaces/default/ingresses/test-frontend-ingress
uid: //
spec:
backend:
serviceName: idu-frontend-XYZ
servicePort: 80
rules:
- http:
paths:
- backend:
serviceName: test-backend-app-service
servicePort: 8080
path: /api/v2/
- backend:
serviceName: idu-frontend-XYZ
servicePort: 80
path: /
tls:
- secretName: tls-cert-name
status:
loadBalancer:
ingress:
- ip: 123.456.789.012
Back end service URL:
https://console.cloud.google.com/kubernetes/service/asia-southeast1-b/test-backend/default/test-backend-app-service...
URL the ingress tries to point to:
https://console.cloud.google.com/kubernetes/service/asia-southeast1-b/standard-cluster-1/default/test-backend-app-service...
So what I've gathered is the ingress can only interface with things in the same cluster as them? test-backend and standard-cluster-1 are the cluster names, and they are both on the default namespace. Isn't that kind of pointless, as you can only deploy one thing to each cluster? Unless your images contain multiple apps, in which case it isn't really microservices anymore.
Connecting two clusters with Kubernetes is hard I guess.
Instead you can deploy both the services on the same cluster. You can create two deployments and expose them as services. And then ingress can redirect traffic between them.
Why do you need a cluster per service though ?
If there is no other alternative you will have to do something like this:
https://appscode.com/products/voyager/7.1.1/guides/ingress/http/external-svc/
I am trying to whitelist IPs that can access my application. I created http-balancer by following this tutorial. https://cloud.google.com/kubernetes-engine/docs/tutorials/http-balancer
After creating the service with NodePort I created an ingress.yaml file that looks like the one below. I have created a global static ip and setup a domain name.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-ingress
annotations:
kubernetes.io/ingress.global-static-ip-name: <global-static-ip>
spec:
rules:
- host: <domain_name>
- http:
paths:
- path: /*
backend:
serviceName: nginx
servicePort: 80
This above yaml file works fine and I am able to access the "Welcome to Nginx" page.
But when I add the IPs to be whitelisted it does not seem to work and still allows other IPs that are not whitelisted.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-ingress
annotations:
kubernetes.io/ingress.global-static-ip-name: <global-static-ip>
ingress.kubernetes.io/whitelist-source-range: "xx.xx.xx.xxx/32"
spec:
rules:
- host: <domain_name>
- http:
paths:
- path: /*
backend:
serviceName: nginx
servicePort: 80
Reference:
http://container-solutions.com/kubernetes-quick-tip/
https://docs.giantswarm.io/guides/advanced-ingress-configuration/
I have not worked with Ingress but as per normal nginx rules you need to deny all and then allow the whitelist IPS
`location / {
proxy_pass https://xxx.xx.xx.xx:8080
allow xx.xx.xx.xxx/32;
deny all;
allow xx.xx.xx.xxx/32;
}`
Which inturn wont allow your non-Whitelisted IP's.
The references you provided use the Nginx-based ingress controller.
Ingress on GKE uses http(s) load balancer. Currently the http(s) load balancer on GCP does not support the firewall rules to allow or deny traffic by IPs.
You can:
Block the source ip in web server or application by yourself.
Or
Try to install nginx-based ingress controller.