All-Things-Docker-and-Kubernetes

Lab 007: Container Networking

Pre-requisites

Introduction

In this lab, we’ll run containers in the same host and test the connectivity between them. We’ll also get to explore the threee type of networks in containers:

Create the Files

Create the dockerfile. Besides using Ubuntu as base image, we’re also installing some networking tools.

FROM ubuntu:16.04

RUN apt update && apt install -y \
    arp-scan \
    iputils-ping \
    iproute2

COPY webapp /

CMD ["/bin/bash"]

Notice in the dockerfile that we’re also copying the webapp binary which we also used from the previous lab.

Here’s the code for our website.

webapp.go ```go package main import ( "fmt" "net/http" "os" ) func hostHandler(w http.ResponseWriter, r *http.Request) { name, err := os.Hostname() if err != nil { panic(err) } fmt.Fprintf(w, "

HOSTNAME: %s


", name) fmt.Fprintf(w, "

ENVIRONMENT VARS:

") fmt.Fprintf(w, "
    ") for _, evar := range os.Environ() { fmt.Fprintf(w, "
  • %s
  • ", evar) } fmt.Fprintf(w, "
") } func rootHandler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "

Let's do this!


") fmt.Fprintf(w, " Host info
") } func main() { http.HandleFunc("/", rootHandler) http.HandleFunc("/host/", hostHandler) http.ListenAndServe(":8080",nil) } ``` </details> Let's compile the code first and build the packages. ```bash $ env GOARCH=386 GOOS=linux go build webapp.go ``` ```bash $ ll total 6008 drwxrwxr-x 2 ubuntu ubuntu 4096 Jun 23 10:46 ./ drwxr-x--- 9 ubuntu ubuntu 4096 Jun 23 10:34 ../ -rwxrwxr-x 1 ubuntu ubuntu 6137719 Jun 23 10:46 webapp* -rw-rw-r-- 1 ubuntu ubuntu 700 Jun 23 10:44 webapp.go ``` ## Build the Image ```bash $ docker build -t ubuntu_networking . ``` ```bash $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu_networking latest b65babeff71b 11 seconds ago 229MB ubuntu 16.04 b6f507652425 9 months ago 135MB ``` ## Bridge Network Here we'll explore a new command, **docker network.** To see the existing networks, ```bash $ sudo docker network ls NETWORK ID NAME DRIVER SCOPE c42784ebf07e bridge bridge local 11aa2835ceb1 host host local cbc02a1260fb none null local ``` The **bridge** network is the default network that's used when you don't specify a network during the container startup. ### Run the Container Add the "-it" flag so that we can run shell commands on the container. We'll call this container 1. ```bash $ docker run -it ubuntu_networking root@2c5606eb344c:/# root@2c5606eb344c:/# ``` Check if ping is installed on the container. ```bash root@2c5606eb344c:/# ping google.com -c 3 PING google.com (142.251.12.101) 56(84) bytes of data. 64 bytes from se-in-f101.1e100.net (142.251.12.101): icmp_seq=1 ttl=99 time=1.58 ms 64 bytes from se-in-f101.1e100.net (142.251.12.101): icmp_seq=2 ttl=99 time=1.64 ms 64 bytes from se-in-f101.1e100.net (142.251.12.101): icmp_seq=3 ttl=99 time=1.66 ms --- google.com ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2003ms rtt min/avg/max/mdev = 1.580/1.627/1.661/0.047 ms ``` Check its IP address. ```bash root@2c5606eb344c:/# ip addr show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 6: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever ``` IP address of container 1. ```bash 172.17.0.2 ``` To detach from the container without stopping/killing the container, hit **Ctrl-P and Ctrl-Q.**. We can see here that the container is still running. ```bash $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2c5606eb344c ubuntu_networking "/bin/bash" 2 minutes ago Up 2 minutes jolly_wing ``` ### Run three containers from the same image We've spin up the first container. Let's run a second one and see its IP address. We'll call this container 2. Click Ctrl-P,Q to detach. ```bash $ docker run -it ubuntu_networking root@416c4cab13ff:/# root@416c4cab13ff:/# ip addr show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 8: eth0@if9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever ``` IP address of container 2. ```bash 172.17.0.3 ``` Run a third one and detach. We'll call this container 3. IP address of container 3. ```bash 172.17.0.4 ``` We now have three running containers. ```bash $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2cbde76af881 ubuntu_networking "/bin/bash" 23 seconds ago Up 22 seconds charming_hypatia 416c4cab13ff ubuntu_networking "/bin/bash" About a minute ago Up About a minute laughing_ritchie 2c5606eb344c ubuntu_networking "/bin/bash" 6 minutes ago Up 6 minutes jolly_wing ``` ### Test the networking between the three containers Attach to container 1 which we spin up *6 minutes ago*. ```bash $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2cbde76af881 ubuntu_networking "/bin/bash" 23 seconds ago Up 22 seconds charming_hypatia 416c4cab13ff ubuntu_networking "/bin/bash" About a minute ago Up About a minute laughing_ritchie 2c5606eb344c ubuntu_networking "/bin/bash" 6 minutes ago Up 6 minutes jolly_wing ``` ```bash $ docker attach 2c5 root@2c5606eb344c:/# root@2c5606eb344c:/# ``` From container 1, try to ping container 2 and container 3. ```bash root@2c5606eb344c:/# ping 172.17.0.3 -c 3 PING 172.17.0.3 (172.17.0.3) 56(84) bytes of data. 64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.065 ms 64 bytes from 172.17.0.3: icmp_seq=2 ttl=64 time=0.080 ms 64 bytes from 172.17.0.3: icmp_seq=3 ttl=64 time=0.119 ms --- 172.17.0.3 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2024ms rtt min/avg/max/mdev = 0.065/0.088/0.119/0.022 ms ``` ```bash root@2c5606eb344c:/# ping 172.17.0.4 -c 3 PING 172.17.0.4 (172.17.0.4) 56(84) bytes of data. 64 bytes from 172.17.0.4: icmp_seq=1 ttl=64 time=0.116 ms 64 bytes from 172.17.0.4: icmp_seq=2 ttl=64 time=0.072 ms 64 bytes from 172.17.0.4: icmp_seq=3 ttl=64 time=0.076 ms --- 172.17.0.4 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2035ms rtt min/avg/max/mdev = 0.072/0.088/0.116/0.019 ms ``` From container 1, scan all the containers that are residing in the same host. The first entry (172.17.0.1) is the default gateway while the next two are the other two containers. ```bash # arp-scan --interface=eth0 --localnet Interface: eth0, datalink type: EN10MB (Ethernet) Starting arp-scan 1.8.1 with 65536 hosts (http://www.nta-monitor.com/tools/arp-scan/) 172.17.0.1 02:42:bb:1d:06:40 (Unknown) 172.17.0.3 02:42:ac:11:00:03 (Unknown) 172.17.0.4 02:42:ac:11:00:04 (Unknown) ``` ## Host Network Host networks add the container to the host network. This means that if the application inside your container is running on the container's port 8080, it will also be binded to the host's port 8080. Let's spin up a fourth container which will use the host network. It'll also run the webapp binary. We'll call this container 4. ```bash $ docker run -d \ --name container_4 \ --network=host \ ubuntu_networking \ /webapp ``` ```bash $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e9266543a998 ubuntu_networking "/webapp" 40 seconds ago Up 39 seconds container_4 2cbde76af881 ubuntu_networking "/bin/bash" 19 minutes ago Up 19 minutes charming_hypatia 416c4cab13ff ubuntu_networking "/bin/bash" 20 minutes ago Up 20 minutes laughing_ritchie 2c5606eb344c ubuntu_networking "/bin/bash" 25 minutes ago Up 25 minutes jolly_wing ``` To test this, run a cURL to the application inside the container. Recall that we didn't expose any port on the container through the dockerfile and we also didn't map any container ports to the host's ports, but since we're using the host network for container 4, the container port 8080 is binded to the host's port 8080 automatically. ```bash $ curl -i localhost:8080 HTTP/1.1 200 OK Date: Fri, 24 Jun 2022 09:24:35 GMT Content-Length: 65 Content-Type: text/html; charset=utf-8

Let's do this!


Host info
``` ## None Network The third type is **None** - which actually means the container doesn't belong in any network. ```bash $ docker run -it \ --network=none \ --name=container_5 \ ubuntu_networking \ /bin/bash root@60e87613ae29:/# ``` ```bash $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 60e87613ae29 ubuntu_networking "/bin/bash" 6 minutes ago Up 6 minutes container_5 4b69751c876f ubuntu_networking "/webapp /bin/bas" 18 minutes ago Up 18 minutes container_4 2cbde76af881 ubuntu_networking "/bin/bash" 42 minutes ago Up 42 minutes charming_hypatia 416c4cab13ff ubuntu_networking "/bin/bash" 43 minutes ago Up 43 minutes laughing_ritchie 2c5606eb344c ubuntu_networking "/bin/bash" 48 minutes ago Up 48 minutes jolly_wing ``` Test the networking. ```bash root@60e87613ae29:/# ip addr sh 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever ``` ```bash root@60e87613ae29:/# ping 8.8.8.8 connect: Network is unreachable root@60e87613ae29:/# root@60e87613ae29:/# ping google.com ping: unknown host google.com ``` ## Cleanup When you're done with the lab, you can stop all running containers by running the command below. ```bash $ docker stop $(docker ps) ``` Once all containers have "Exited" status, remove them. ```bash $ docker ps -a ``` ```bash $ docker container prune -f ``` Finally, remove all images. ```bash $ docker image prune -af ```