Bluemix docker scalable group for non HTTP requests - docker

Can scalable group option on Bluemix container infrastructure work with protocols other than HTTP?
I created a simple TCP server, deployed in a single container on Bluemix and works fine. If I try to deploy it as a scalable group I can only assign HTTP port and it does not respond any more.
Is this a current limitation?
Thank you very much

If you are running a Cloud Foundry app you can only get port 80,433. However if you run a container you can bind to any port you want.

containers environment on Bluemix actually supports a limited list of TCP (not UDP) ports, and 9080 is contained in this list, so your server should work.
If you need any different port from the ones contained in this list you could always ask for the port being opened for your instance, through Bluemix support.

Related

Talk to server on docker container with no exposed ports

I have some docker containers talking together through docker bridge networks. They cannot be accessed from outside (I was said) as they are launched from a script with a default command which does not include 'expose' nor '-p' option. I cannot change that script.
I would like to connect to one of this containers which runs a server and listens for requests on port 8080. I tried connecting that bridge to a newly created docker bridge network, but i did not succede.
Now I am thinking of creating a new container and letting it talk to the server one (through bridge networks). As it is a new contaienr I can use the 'expose' or '-p' options, so it would be able to talk to the host machine.
Is it a good idea? How can I forward every request made to that container to the server one and get responses back to the host machine then?
Thanks
Within the default docker network, all ports are exposed. So you only need a container that exposes a port to the host machine and is in the same network as the other containers you have already created.
This is a relatively normal pattern. You can use a reverse proxy like nginx to achieve something like this.
There are some containers that automate this process:
https://github.com/jwilder/nginx-proxy
If you have no control over the other containers though, you will need to write the proxy config by hand.
If the container to which you are trying to connect is an http server, you may be able to use a ready-made container image that can work as an http forwarder (e.g., nginx - it is relatively easy to configure it as an http forwarder).
If you need plain tcp forwarding, you could make a container running 'socat' (socat can work as a tcp forwarder).
NOTE: in either case, you will be exposing a listener that wasn't meant to be on a public address. Do take measures not to allow unauthorized connections.

Docker app not available with host IP when using automatic port mapping

I am deploying a eureka server on a VM(say host external IP is a.b.c.d) as a docker image. Trying this in 2 ways.
1.I am running the docker image without explicit port mapping : docker run -p 8671 test/eureka-server
Then running docker ps command shows the port mapping as : 0.0.0.0:32769->8761/tcp
Try accessing the eureka server from outside of the VM with http://a.b.c.d:32769 , its not available.
2.I am running the docker image with explicit port mapping : docker run -p 8761:8761 test/eureka-server
Then running docker ps command shows the port mapping as : 0.0.0.0:8761->8761/tcp
Try accessing the eureka server from outside of the VM with http://a.b.c.d:8761 , its available.
Why in the first case the eureka server is not available from out side the host machine even if there is a random port(32769) assigned by docker.
Is it necessary to have explicit port mapping to have docker app available from external network ?
Since you're looking for access from the outside world to the host via the mapped port you'll need to ensure that the source traffic is allowed to reach that port on the host and given protocol. I'm not a network security specialist, but I'd suggest that opening up an entire range of ports simply because you don't know which port docker will pick would be a bad idea. If you can, I'd say pick a port and explicitly map it and ensure the firewall allows access to that port from the appropriate source address(es) e.g. ALLOW TCP/8671 in from 10.0.1.2/32 as an example - obviously your specific address range will vary on your network configuration. Docker compose may help you keep this consistent (as will other orchestration technologies like Kubernetes). In addition if you use cloud hosting services like AWS you may be able to leverage VPC security groups to help you whitelist source traffic to the port without knowing all possible source IP addresses ahead of time.
You either have the firewall blocking this port, or from wherever you are making the requests, for certain ports your outgoing traffic is disabled, so your requests never leave your machine.
Some companies do this. They leave port 80, 443, and couple of more for their intranet, and disable all other destination ports.

Docker swarm mode, internally running several services with unique domain names but each on port 80

I'm trying to setup a microservice deployment (deployment file at https://github.com/mojlighetsministeriet/groups/blob/master/docker-compose.example.yml) with several services that will use HTTP (hopefully HTTPS later on) to communicate internally without being exposed outside the network. I later on will add a proxy service that will expose specific features. I want to do this specifically with docker swarm mode and I like the possibility to define the deployment in a docker-compose.yml so I can initiate with:
$ docker stack deploy my-platform -c docker-compose.example.yml
I want the API urls internally to be like GET http://identity-provider/public-key and GET http://groups/b0c44674-58e0-4a8a-87e0-e1de35088964 . I have done this with Kubernetes setups before and that works great but now I want to get this working with docker swarm mode.
The DNS parts works without any problems, but docker swarm mode won't allow me to have each service listening on port 80 (will later be 443). It keeps complaining about port conflicts even though each service has it's unique domain name like identity-provider or groups and so on.
Should I use a specific network driver to get this working? I currently use overlay.
Using domain names without random ports would make calling in between the services much more simple to remember than e.g. http://identity-provider:1234 and http://groups:1235, the ports only adds complexity to the setup.
I'm fine with using any super cutting edge version of docker-ce if that helps somehow.
This should be possible right?
Docker Swarm routes incoming requests based on the published port, you can't have two applications with the same port number in a single Swarm.

How to programmatically specify the IP and port of a dependent docker container created by Marathon?

I am learning Micro-services architecture by writing a small web app. The app has the following components, each of which will be hosted by a docker container.
In my API Gateway which is written in NodeJS, there is some place I will call:
request('http://service_b_ip_addr:port/get_service_b', callback);
However, both service_b_ip_addr and port are not known until Marathon has the Service B's docker container created.
With some Service Discovery mechanism, such as mesos-dns or marathon-lb, I guess that I could just change service_b_ip_addr to something like service_b.marathon.com.
But I've no idea how should I put the port in my program.
Thanks in advance for your help.
PS:
I am using BRIDGED network mode given that multiple instances of a Service could locate on the same Mesos slave. So port is a NATted random number.
Take a look at this answer.
If you use marathon-lb then there is no need to pass a port because it's a proxy and it will know where service is just by name.
If you use mesos-dns you should make a SRV request to get ip and port. In node you can do it with dns.resolveSrv(hostname, callback) but your DNS must be exposed on defaul (53) port and supports SRV request (mesos-dns supports it).

How to tunnel to into the private network of my docker containers on Bluemix?

I have some docker containers running on Bluemix using private IP addresses. I would now like to setup a tunnel from my laptop (running linux) to access the private network on Bluemix.
I had first created a container running an ssh-server. Using ssh -D I was able to setup a SOCKS5 proxy connection. This worked fine with Chrome but not all applications support a SOCKS proxy.
(google-chrome --proxy-server=socks5://localhost:<tunnel port>)
So I tried to create a container with an OpenVPN server. Unfortunately this does not work on Bluemix as the containers are not running privileged and thus can not create a tun device.
Bluemix also has a VPN and a Secure Gateway service, which sound promising but so far I could not figure out how to get those working.
Does anybody know if it is possible to make the private docker network available locally and how to connect to that?
Generally speaking containers should be used to implement services available to external applications (an APIs service, or a runtime, or a dbms, or something like that).
According to this, what you could achieve is a set of services available for you on different containers, and a single container working as SSH tunnel gateway, making your local environment connected to it using SSH and defining a set of local and remote SSH ports forwarding, with different policies according to the service/port and the IP of the service.
It should work for all the services, and you haven't to use a socks proxy to forward requests to different hosts: using remote SSH forwarding your SSH endpoint will redirect your requests to the right service inside the local/private lan.
I found that this guide describes correctly how to work with local&remote port forwarding.
http://www.debianadmin.com/howto-use-ssh-local-and-remote-port-forwarding.html
About the OpenVPN solution, as you already know it is not possible to use software requiring privileged mode on containers, because it couldn't be allowed on Bluemix due to security reasons: if you wish to have this kind of solution I strongly suggest you to use OpenVPN on a VM on Bluemix UK region (still beta but an architecture expected to be the final architecture as soon as VM service will become GA service)
I think that these options are the ones available on Bluemix to achieve what you describe without using the VPN service suggested by #bill-wentworth

Resources