Kubernetes services within cluster - kubernetes

I am trying to set up a conventional web app with a database in Kubernetes. I have accomplished it by configuring 2 services and 2 deployments - one for the app and one for the database. Now I would like to make my database accessible only from the app pods, ie not expose it to outside world like a service. Is it possible using only Kubernetes configuration?

There are following ways to expose the pods.
purpose is inter-service communication
Internally expose
service type=clusterIP
Headless-service clusterIP: None is used for database pods
Sometimes you don’t need or want load-balancing and a single service IP. headless-services
Externally expose
Exposing service to the customers.
service type=NodePort or type=LoadBalancer

Related

Redis Cluster data migration in two differnt Kubernetes Clusters

Is there anyway we can migrate Redis Cluster data that are running inside 2 different Kubernetes cluster? How we can communicate between Redis stateful pods which are running on two different Kubernetes Clusters?
We have two Redis Clusters which are running on two different Kubernetes Clusters X & Y. I want to transfer data from redis-X to redis-Y cluster. How we can establish connection between redis-X and redis-Y clusters so that we can migrate data?
Any help or hint is appreciated.
There are two possible approaches to establish connection between clusters:
Built-in solutions
3rd party solution
Built-in solutions
NodePort - Exposes the service on each Node’s IP at a static port (the NodePort). A ClusterIP service, to which the NodePort service routes, is automatically created. You’ll be able to contact the NodePort service, from outside the cluster, by requesting <NodeIP>:<NodePort>
LoadBalancer - Exposes the Service externally using a cloud provider’s load balancer. NodePort and ClusterIP services, to which the external load balancer routes, are automatically created.
ingress (both 1st and 3rd party implementations) - more flexible then previous two, but only works with HTTP/HTTPS.
Read more: Kubernets services, NGINX ingress
3rd party solution
Istio supports multi-cluster deployment model. However, if you don't have service mesh deployed, doing so may be too much for single task use.
Once you have connection established between clusters you can migrate Redis using MIGRATE command, or redis-migrate-tool proposed in comments.
Here is a new approach using Skupper.
https://github.com/bryonbaker/rhai-redis-demo
It is a full step by step demo I wrote that shows a globally distributed real-time replicated cache from on-premises and across four kubernetes clusters. The Redis cache is replicated from on-premises to Sydney, London and and New York.
No NodePorts, Submariner, or Istio Federation required. It all uses standard routes.
The demo is based on OpenShift - but it will work with any flavour of xKS.

How does Traefik / Ngnix - (Ingress Controllers) forwards request to two different services having configured with same port number.?

Basically I have Following Hdfs Cluster setup using docker-compose:
Node 1 with IP: 192.168.1.1 having service deployed as below:
Namenode1:9000
HMaster1: 8300
ZooKeeper1:1291
Node 2 with IP: 192.168.1.2 having service deployed as below:
Namenode2:9000
ZooKeeper2:1291
How does Traefik / Ngnix - (Ingress Controllers) forwards request to two different services having configured with same port number?
There are several great tutorials on how ingress and load balancing works in kubernetes, e.g. this one by Mark Betz. As a general rule, it helps to think in terms of services and workloads instead of specific nodes where your workloads are running on.
A workload deployed in Kubernetes (a so called Pod) has its own internal IP address, called a ClusterIP. That pod can have one or more ports open, just on that pod-owned ip address.
If you now have several pods to distribute the load, e.g. like 5 web server processes or backend logic, it would be hard for a client (inside the cluster) to keep track of all those pod IPs, because they also change when a pod is updated or just restarted due to a crash. This is why Kubernetes has a so called concept of services. Those provide a stable DNS name and IP which then transparently "forwards" to one of the healthy pods. So your client only needs to know the DNS name and not keep track of the specific pod IPs.
If you now want to expose such a service to the public, there are different ways. Either you set your service to type: LoadBalancer which then sets up some load balancer infrastructure on your cloud provider and routes traffic to the nodes and then to the pods - or - you already have an ingress controller in place and just define the routing based on host names and paths. An ingress controller itself is such a loadbalanced service with an attached cloud load balancer and also has some pods (with e.g. a traefik or nginx container) which then route your packets accordingly.
So coming back to your initial question: If you want to expose a service with several pods of the same kind, then you would first create a Service resource that matches your Pods using the selector and then you create one single ingress resource that provides a hostname/path and references this service. The ingress controller will pick up those ingress resources and configure the traefik or nginx accordingly. The ingress controller doesn't really care about the host IPs and port numbers, because it acts on the internal kubernetes ClusterIPs, so you even don't need (and shouldn't) expose such a service directly when you have an ingress in place.
I hope this answers your question regarding exposing two workloads over an ingress controller. For details, check the Kubernetes docs on Ingresses. Based on the services you named (zookeeper, hdfs) load balancing and ingresses might not be what you need for that case. Zookeeper instances should be internal in most cases and need to be adressed individually, so you might want to check out headless services, for this use case. Also check the Kubernetes docs for a way to run zookeeper.

Exposing service to the internet from a bare metal kubernetes cluster

I'm running a Kuberenets with 1 master and 2 slaves. I have a deployment and service pointing to it with type of NodePort. I'm able to access the service from the workers themselves, but I want to expose the service in a way it will load balance between the workers and without specifying a port. I'm running on bare-metal, so I can't expose the service as a LoadBalancer and use google/amazon load balancing.
How can I do that?
You can use metalLB which hooks into your Kubernetes cluster, and provides a network load-balancer implementation. In short, it allows you to create Kubernetes services of type LoadBalancer in clusters that don’t run on a cloud provider, and thus cannot simply hook into paid products to provide load-balancers.
It has two features that work together to provide this service: address allocation, and external announcemen
MetalLB requires the following to function:
A Kubernetes cluster, running Kubernetes 1.13.0 or later, that does not already have network load-balancing functionality.
A cluster network configuration that can coexist with MetalLB.
Some IPv4 addresses for MetalLB to hand out.
Depending on the operating mode, you may need one or more routers capable of speaking BGP.

expose pgbouncer service to external clients

I am trying to implement pgbouncer on k8s, using a helm chart created deployment,service…now how do I expose the service to outside world? Not much familiar with k8s networking, tried to create an ingress resource and it created an elb in aws…how do I map this elb to the service and expose it?
the service is created with type ClusterIP…the service is a tcp service i.e. not http/https application (edited)
The helm chart used is - https://github.com/futuretechindustriesllc/charts/tree/master/charts/pgbouncer
Ingresses are only used for HTTP and friends. In this case what you want is probably a LoadBalancer type service. That will make a balancer fabric and then expose it via an ELB.

Ingress or Service with type: LoadBalancer

Kubernetes has both Ingress (in front of a Service) and Service with type:
LoadBalancer. These seem to do identical things: allow public traffic into the pods matching the service's selector. What are the benefits and drawbacks of each? In what scenarios would I choose one over the other?
Ingress can be used to expose many services depending on the path or even multiple applications depending on the host or domain in the request.
A load balancer always exposes one service only.
Assume that AWS, GCP or Azure is where your infrastructure located
Ingress:
Only work if you have ingress controller such as nginx-ingress-controller, traefik,...
Many services could share the same ingress
Name based virtual hosting
path based routing
Only one AWS ELB (or GCP load balancer for Google Cloud) is needed
Recommend to follow this approach for most of use cases
serviceType LoadBalancer:
each service would create separated AWS ELB (cost inefficiency, would be super expensive if you have more and more services later)
Could be helpful in case you want to ensure maximum security / workload ( 1 ELB per service)