How should dynamic Kubernetes/OpenShift DNS resolution be configured? - docker

I'm unable to find relevant information on this, which is why I'm asking the question here.
Instead of using /etc/hosts which is a hacky solution for resolving Kubernetes container names to their service IP addresses, what would the best method be to automatically or dynamically map new Kubernetes pods to their service IPs?
I've heard using /etc/resolv.conf is one such method, but was unable to find exactly how that file should be configured for this scenario.

If you are using OpenShift it deploys with an internal DNS. When you create a Service object it will automatically have its service name, setup as a hostname in the internal DNS, with it mapping to the IP address of the service.
Further the label selectors on the service are matched against labels on Pods, the IP addresses of the pods will be associated as an endpoint for that service and internal network setup so that connection to the service IP directly, or after DNS lookup by hostname (service name), will route connection through to one of the pods.
So all of this is done for you automatically and you don't need to do anything. The service object is even created for you automatically if you are using oc new-app to deploy applications in OpenShift.

Related

Tweak load balancer for docker swarm mode

I want a lead to the below problem.
My understanding:
Docker swarm incorporates an ingress and a DNS server that identifies services with their names. It also incorporates inbuilt robust load balancers on every node in the cluster.
We can hit any service running on different nodes which are participating in docker swarm mode using any machine's IP address. If a machine does not host service, the load balancer will route the request to a different machine that hosts that service.
For best practice, we can choose a load balancer container(NGINX/HAProxy) as a reverse proxy to route the requests on the basis of some predefined algorithms(round-robin/Hash/IP Hash/Least Connection/Least bandwidth, etc.).
Problem statement:
I want to make a cluster of two/three different machines where I will be deploying all the technical services which are required. A mini QA environment.
As a service is identified by its name, I can not create another service with the same name. Being a developer, I want to have a service up and running on my localHost which is also part of the docker swarm cluster. Obviously, I can not name it the same. So, let's say I name it as myIP_serviceName. Now the DNS entry which docker swarm has will be based on this name.
I want a mechanism where if I make a call for any service using my IP address as host, the load balancer will look for any service which is registered in DNS as myIP_serviceName, if it finds any service with such a name call should be routed to this service, if it doesn't, the call should follow the regular path. This should hold true for every consecutive request which is part of a round trip journey.
I have not explored Kubernetes yet, Please suggest if Kubernetes can be used here to achieve this goal more elegantly.
Please correct my understanding if I am wrong and do provide valuable suggestions.
HAProxy have written about HAProxy on Docker Swarm: Load Balancing and DNS Service Discovery maybe this will point you in the right direction.

Forward all service ports to a singe container

I would like to run a container in kubernetes with a static ip. I found out that only a service can provide an ip address.
Is it possible to map a Service to one pod and forward all ports?
A service discovers pods based on labels and selectors. So it is not necessary to use an IP Address to statically reference a pod from a service. However, if you so wish, you can override the autonomy behind this and manually configure your own ClusterIP for the service.
Once the Pod and Service have been created, other pods in your cluster will be able to interact with the pod via the Name of the Service provided they are in the same namespace. If they are not, you will need to pass the FQDN of the service.
If you are trying to access the pod from outside of Kubernetes, then you will need to use a Service with a different type than ClusterIP. For example, a NodePort or a LoadBalancer. Alternatively, if you have an Ingress Controller with a gateway already provisioned you could use that.
With regards to you desire to forward all ports, this is not possible as port declarations in Service files must be statically mapped. It is not currently possible to pass a Port Range but there is a long standing feature request for it.

Remote Docker container by hostname

How do you access remote Docker container by its hostname?
I need to access remote Docker containers by its hostnames (or some constant IP's) for development and testing purposes. I have tried:
looking for any DNS approach (have not found any clues),
importing /ets/hosts (probably impossible),
creating tunnes (only this works but it is very time consuming).
It's the same as running any other process on a host, Docker or not Docker: you access it via the host name or IP address of the host and the port the service is listening on (the first port of the docker run -p argument). Docker containers don't have externally visible individual IP addresses any more than non-Docker HTTP or ssh daemons do.
If you do have DNS infrastructure available to you, you could set up CNAME records to resolve particular service names to the specific hosts that are running them.
One solution that may help you is some sort of service registry; in the past I've used Consul with some success. You can configure Consul with some health checks or other probes ("look for an HTTP service on port 12345 that answers GET / calls"), and it will provide its own DNS service ("okay, http://whatevername.service.consul:12345/ will reach your service on whichever hosts it happens to be running on").
Nothing in the Docker infrastructure specifically helps this. Using /etc/hosts is distinctly not a best practice: the name-to-IP mapping needs to be kept in sync across all machines and you'll start wishing you had a network service to publish it for you, which is exactly what DNS is for.

rancher 2.0 networking in project namespace

can i ping one workload from other workload by workloadname?
I accustomed on rancher 1.0, where if i created stack with more conteiner so i can ping one from other conteiner by name.
for example: I have api and database and I need api to communicate with databases. When i click on execute shell on api and write "ping database", so not working.
I write connection string to database in api environmental variable.
And YES i can create database and take database ip a write it to ENV, but this ip will change after each restart.
It's possible to call by some not generate name?
thanks
EDIT:
Service discovery:
Shell:
As you see, so translate database name is work. Only ping database container not working.
To communicate between services you can communicate with cluster IP or with Service Name.
Using the ServiceName will be easier.
The service discovery add a DNS for each of your service. So if you have api, app and database you will have a DNS entry for each of those services.
So within your services, you can refer directly to the DNS.
Example: To connect in JDBC to a schema name test in your database, you would do something like this:
jdbc:mysql://database/test
see:
https://rancher.com/docs/rancher/v2.x/en/k8s-in-rancher/service-discovery/
If you want to know the clusterIP of you services you can run this command: kubectl get services --all-namespaces
Edit 1: Adding ClusterIP as a way to communicate with a service.
Kubernetes Service IP is implemented using "iptables" on the linux hosts which are part of the cluster. If you examine those rules closely, ONLY the port specified as part of the Service is exposed, not the ICMP port, which means, one cannot ping the Service IP addresses by default. But you would still be able to communicate with the Service on the designated port.

How to make docker make request on service name instead of IP Address

I am trying to create a fabric Multi-org multi-VM using overlay network. Hyperledger fabric validates the peers(containers) using their service names. Now, the problem here is the peers are providing their IP address not service names in communication causing a failure in TLS validation. Is there a way to make containers make grpcs calls only using service names and not IP address.
In a production scenario you would use DNS servers to map the addresses from host names, and there would be no IP addresses in any of your configuration files. I would encourage you to try and adopt the same approach in a development/test environment the /etc/hosts file is the obvious answer for the VMs themselves to resolve hostnames, and there is a feature in docker-compose for adding extra hosts to the /etc/hosts file in the containers e.g. the following line goes in a docker-compose yaml file:
extra_hosts:
- "peer0.omac.cons.com:192.168.153.157"

Resources