The Docker Bridge Network - Docker networks part 1

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
First off, many thanks to everyone who answered my poll on what the next – so this – episode should be about. Your wish clearly is my command so today we will talk about docker networking. How are we going to do this ? I thought, rather than making a complex setup like we did in the last episode or me just reading the docker network documentation to you – we will take a top down approach. What do I mean by that ? This episode will be 100% hands on. We will pull one docker image and run it as a container that gives us information about the network as the docker container sees it from the inside and then launch that same container with different network types. We will then be able to see three things: How we can access the container from the outside; what the container sees from the inside and last but not least how that container can communicate with other containers on the same network. That should give you guys a good overview over the different network types that you can use with Docker and at the same time this is something that you can very easily reproduce, practice and experiment with. Stay tuned. (intro) Standard reminder guys – here is the breakdown of this episode - use the chapters if you are in a hurry and want to fast forward or if you want to skip chapter. The chapters are here on the time line and in the description of the video as usual. All command that I type are in the description. Thank you. The container which we will use for our tests is the NGINX hello word example container which is nginxdemos/hello. This container provides a simple webserver that just prints out the IP address of the container itself, so a view from the inside and a handful of other things such as the host name and the local time. Here is what we need: We will do all this on a Linux machine. If you don’t have Linux on your desktop then you can run a Linux image in a virtual machine or on a raspberry pi and run Docker inside that VM or on the Pi. On the linux machine we will of course need docker – you can install docker on a debian by running sudo apt install docker.io. In order to monitor, create and modify the docker networks, we will use portainer as a graphical interface. Portainer can be ran directly as a container with a simple one-liner which you can see here. Don’t worry, everything is in the description. Once we log into portainer we can then go to the networks section here and we can nicely see the existing docker networks. By default you should see bridge, host and none. On the command line this can be seen by typing docker network ls. Cool, that’s all we need. We have a linux host with docker, and we have portainer in order to visualize the docker environment. Let’s pull the image and start the first instance of the nginx demo. On the command line you can type docker run -d nginxdemos/hello. That will launch the container with an automatically created name and just default settings. We will see what those are in a second. You could do the same in Portainer by selecting Containers in the left menu, then click on Add container and specify nginxdemos/hello as the image name. Once you click on “Deploy the container” then the result is similar. If we browse to the containers menu item then we can see the container listed here. As you can see, there are no published ports, so the container would probably not be visible from outside the docker host but we can access it from the docker host itself. But first we need to know where to find it. Let’s click on the container’s name and scroll down to the very bottom. Here we can see the network that it joined and also its IP address. The first thing to note is therefore that if you launch a container without specifying network parameters, then it will default to the bridge network and get an IP address out of that network. Here is the IP address that has been assigned to it. So if I just copy that address and paste it into a new browser tab, then we should get the NGINX demo page. On that page it shows us what it sees from the inside, such as its IP address on the bridge plus the Server name which is in fact the linux hostname of the container which in turn is a shortened version of the container ID. Copy that name to the clipboard. We will need it in a minute. So far, that was very easy. All we had to do was launching an image with default values. We have learnt that the default network is the bridge network, which only exists on the docker host, so it’s not visible or accessible from the outside world. The hostname of a container on the bridge by default is a shortened version of the docker container ID. Let’s see how two of those containers can communicate with each other. In order to do that I need a second instance of that container. In Portainer that can be done by clicking on the container name, then clicking on Duplicate/Edit. I change the name of the new container and untick pull the image – we can use the existing image – and then further down I click on Deploy the container. On the command line we would just have done another docker run -d and then the image name. As expected, we have two containers here in the container section. In Portainer, we can easily execute a shell or console inside the container from the quick actions column here. The command in this demo container is /bin/ash. On the command line you would do docker exec -it /bin/ash. Let’s connect. IP addr shows us the IP address of this new container. It’s on the same bridge of course. So I should be able to ping at least myself – OK – and the other container – that works as well. So we do have IP connectivity between containers that are on the same bridge. Let’s check the default route. IP route shows us that there is a default route via the docker host’s IP on the bridge so presumably the docker host acts as a gateway here. Let’s see if we can get to the internet. I can ping google’s name server – so yes, we have internet access from inside the container. Let’s check name resolution to www.google.com – that works as well. Awesome – we already know so much about Docker networking just by looking at the behavior of the default settings. We know that there is a default bridge that can not be accessed from the outside, but it gives us IP connectivity and name resolution to the outside. Plus we have IP connectivity between containers on the same bridge. Before we do a last test with this setup I want to draw your attention to a very important detail here. That is the hostname of the docker container depending on how we create it. Let’s browse to the NGINX on the second container here – and – surprise – it has the same hostname like the first container. That can easily lead to confusion. The reason is that I cloned it in Portainer from the first one and I did not modify the hostname down in the network section before I cloned it. So we can’t really check name resolution between containers here because we would get a false positive as they both have the same name. Let’s create another instance of the demo container from scratch without cloning. That one got a new hostname. Back to portainer. Launch a console inside that new container. Quickly check the ip address and the hostname Now let’s try to ping the host name of the first container. And – that doesn’t work. We have NO name resolution between containers. Perfect – now we have the complete image of what the default settings and the default bridge network provide us with. Let’s now take this to the next level. So far we can not access the containers from the outside world. The most common way of making a docker container visible from the outside is port mapping. Let’s create a new instance of our demo image here. This time we map a port, let’s say port 81 to port 80 inside the container. We can do this here with this little grey button. 81 on the host to 80 in the container. Deploy. On the command line you would do this with the -p option of the docker run or docker start command. The first apparent difference here in the containers list is that we have an entry in the published ports column. So we can now browse to localhost colon 81 or – from the outside – the IP address of our docker host colon 81 and we will always get the same result – the NGINX page shows us the IP address of the bridge. Great – accessing a docker container from the outside can easily be done by mapping a port on the host to a port inside the container. If you have a bit of experience with VMWare Workstation or Virtualbox then you could say that the docker bridge pretty much acts like the NAT network in Virtualbox. Mapping a port is hence pretty much like a port forward on a router to the LAN. In fact the docker host forwards port 81 on its own network to port 80 on the container’s bridge interface. One thing that is annoying still is the fact that we have no name resolution between docker containers. If you had for example a web server and a database server that need to communicate with each other, it would come in handy if they could access each other by their respective names rather than using IP addresses. Let’s see how we can solve that challenge. The docker bridge network driver provides name resolution in principle. Just not on the default bridge. Hence, we just create our own. Click on Networks, then click on the blue “Add Network” button. I call my new network marcsBridge, I use the bridge driver and assign a new network IP address range to it, for example 172.172.0.0/24. the docker host itself should be reachable under the 172.172.0.1 address. The IP addresses which it should give to containers should just be the upper half of that range, so .128/25 at the end. Click on create the network. Back to the containers section. Let’s scrap all the containers which we don’t need any more. Select all of them and then click on stop if they are running. Do the same thing and then click on remove. Pay attention to not stop or remove the portainer container itself. We still need it. OK – nice and clean environment. Now we recreate two NGINX demo containers. But this time with a hostname and on the new bridge. Add Container Give it a name – I use nginx1 Type in the image name Now browse down the Network tab. Open the Network dropdown and select marcsBridge Important – give it a hostname. I use the same name like the container name. Let’s deploy. Do the same thing again for a second container which I have called nginx2. Now – if I open a console in one of those containers and again check the ip address and the host name then we see here the values which we have defined in portainer. I can of course ping the container itself with its host name and – that is the big difference between this bridge and the system bridge – I can also ping the other container with its host name. So Docker does provide name resolution between containers over a self-defined bridge. Cool – as we could see, a bridge is very flexible. We can access the outside world, we have full routing and name resolution between the containers on the same host and bridge and we can access a container on the bridge from the outside by mapping ports. The only inconvenience here is that if we want to replicate this setup and automate the deployment then it’s actually a lot of clicks or commands. There is however a simple solution to this – and that’s Docker compose. Docker Compose allows us to define multiple containers as so called services in a stack. That’s just terminology. If you have watched my raspberry pi video about the IOTStack project – that is one example. For this episode we will just create a very simple stack of two instances of the nginx demo container. Let’s quickly install a couple of things here. First we need to install docker-compose by typing apt install docker-compose in a shell on the host. Second I want a decent editor. For this I will use Microsoft – yes you heard right – Microsoft Visual Code. I can easily install this by downloading a deb or rpm file from the visualstudio.com website. The reason why I want to use Visual code here is that there are loads of extensions available for different source code types. I have installed an extension for docker compose files here. Now look what happens when I open the folder where my little example compose file is located. The file is called docker-compose.yml and visual code has associated it with the extension. Inside the file you can see that I have defined two services inside that stack. One is called nginx1, the image is the nginxdemo/hello container and I will be mapping host port 81 to port 80 of the container. Same scenario for service nginx2. Before I bring up this stack I want to quickly scrap the containers from the last exercise and also the bridge which I had designed. Back to Visual Code. Here I can just do a right click on the yml file and select compose up. You could also do this on the command line without visual Code by typing the docker-compose command as it is shown here in the terminal window. Very convenient, especially if you are writing docker compose files on your own. Now what has this done in Docker ? Let’s check in portainer. First the containers. Here we see the two containers which have been created with the corresponding port mappings. They are both part of the same stack which by default is the name of the folder where I put the yml file, in my case dockertest. Let me check the properties of that container. If I scroll down to the network part then I can see that this container uses a bridge which is called dockertest_default. Let’s check it out. Clicking on the network name brings me to the details page of that network. It is a bridge network and further down we can see the two containers which are actually using it. In my case nginx1 and nginx2. Please note the little “Leave Network” button here which is another big advantage of user-defined bridges – you can leave and join networks on the fly. Let’s go back to the containers and open the nginx demo pages. Hmmm…. The host name again is that cryptic container name. Will Name resolution work as desired ? Let’s check it out. We open a console on nginx1 hostname shows that cryptic docker name ping nginx2 – and it works!!! Just another quick remark on the docker stack – if you don’t want to use an editor like visual code and you just want to bring up a docker-compose.yml file, then you can also do this from within portainer. Go to stacks, click on Add stack, give it a name and copy paste the content of the yml file into that window. Scroll down and click on “Deploy this stack”. Keep in mind that if you are on one single host only version 2 yml files are supported plus I got that Error message saying the stack could not be deployed but it looked like everything went OK. Might be a bug or a feature in portainer. Just wanted to point this out quickly. Awesome – guys, when I started writing this episode I didn’t think that there was so much to show on bridges alone, so let’s stop here – I think you have a couple of things to play and experiment with – in the next episode we will have a look at the other network types such as the host or macvlan network. And then there is still the overlay network and also maybe we will have a look at how we can import a disk image of a virtual machine into a docker container so that we can for example run OpenWrt in a container and build a dockerized version of our test lab network. Until then, many thanks for watching, liking, commenting and subscribing. Stay safe, stay healthy, bye for now.
Info
Channel: OneMarcFifty
Views: 28,935
Rating: undefined out of 5
Keywords: Docker Networks, Docker bridge Network, Bridge NEtwork docker, Bridge Docker, Portainer, Networks Portainer, Networking Portainer, Docker-compose Networks, Networking Docker, Docker NEtworking
Id: OmZdItNjWNY
Channel Id: undefined
Length: 19min 12sec (1152 seconds)
Published: Thu May 13 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.