<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Safak Ulusoy</title>
    <description>The latest articles on DEV Community by Safak Ulusoy (@polarbit).</description>
    <link>https://dev.to/polarbit</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F181552%2F69424fc6-eeb8-4917-8375-a406ef6e2ef2.png</url>
      <title>DEV Community: Safak Ulusoy</title>
      <link>https://dev.to/polarbit</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/polarbit"/>
    <language>en</language>
    <item>
      <title>How Docker Container Networking Works - Mimic It Using Linux Network Namespaces</title>
      <dc:creator>Safak Ulusoy</dc:creator>
      <pubDate>Wed, 15 Apr 2020 00:56:53 +0000</pubDate>
      <link>https://dev.to/polarbit/how-docker-container-networking-works-mimic-it-using-linux-network-namespaces-9mj</link>
      <guid>https://dev.to/polarbit/how-docker-container-networking-works-mimic-it-using-linux-network-namespaces-9mj</guid>
      <description>&lt;p&gt;Docker (and probably any container technology) uses &lt;em&gt;linux network namespaces&lt;/em&gt; to isolate container network from host network. When Docker creates and runs a container; it creates a separate network namespace (container network) and puts the container into it.&lt;/p&gt;

&lt;p&gt;Then, Docker connects the new container network to linux bridge &lt;strong&gt;docker0&lt;/strong&gt; using a &lt;em&gt;veth pair&lt;/em&gt;. This also enables container be connected to the host network and other container networks in the same bridge. &lt;/p&gt;

&lt;p&gt;So let's try to define &lt;em&gt;network namespace&lt;/em&gt;, &lt;em&gt;veth pair&lt;/em&gt; and &lt;em&gt;linux bridge&lt;/em&gt; in one sentence:&lt;/p&gt;

&lt;p&gt;A "&lt;strong&gt;linux network namespace&lt;/strong&gt;" is virtual network barrier encapsulating a process to isolate its network connectivity(in/out) and resources (i.e. network interfaces, route tables and rules) from linux core and other processes.&lt;/p&gt;

&lt;p&gt;A "&lt;strong&gt;veth pair&lt;/strong&gt;" is basically a virtual network cable which have a virtual network interface device (NIC) on each end.&lt;/p&gt;

&lt;p&gt;A "&lt;strong&gt;linux bridge&lt;/strong&gt;" is switch like virtual device that enables communication between network devices connected to the bridge, creating something kinda LAN. &lt;/p&gt;

&lt;p&gt;The diagram below may help you visualize and understand container networking better. Please refer to this diagram frequently while reading the rest of the post. &lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpszchqfvcjpl13dextrc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpszchqfvcjpl13dextrc.png" alt="Docker Container Networking"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The plan is to first investigate a docker container's network structure.&lt;br&gt;
After that we will try to mimic a docker container network by manually creating a &lt;em&gt;network namespace&lt;/em&gt; and &lt;em&gt;veth pair&lt;/em&gt;; then do required configurations. &lt;/p&gt;
&lt;h2&gt;
  
  
  1- Let's Demystify Docker Container Networking
&lt;/h2&gt;

&lt;p&gt;Now we investigate docker's container networking.&lt;/p&gt;

&lt;p&gt;I have three ubuntu containers running locally, &lt;em&gt;"con1"&lt;/em&gt;, &lt;em&gt;"con2"&lt;/em&gt;, and &lt;em&gt;"con3"&lt;/em&gt; namely. First let's have a look at them. See that &lt;em&gt;con3&lt;/em&gt; is not in default &lt;em&gt;docker0&lt;/em&gt; bridge. I run it in a custom docker bridge network named 'testnet'.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ filter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'Name={{.Name}} Hostname={{.Config.Hostname}} '&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; filter+&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'IP={{or .NetworkSettings.IPAddress .NetworkSettings.Networks.testnet.IPAddress}} '&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; filter+&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'Mac={{or .NetworkSettings.MacAddress .NetworkSettings.Networks.testnet.MacAddress}} '&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; filter+&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'Bridge={{if .NetworkSettings.IPAddress}} docker0 {{else}} testnet {{end}}'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; docker inspect con1 con2 con3 &lt;span class="nt"&gt;--format&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$filter&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="s1"&gt;'s/=\//=/g'&lt;/span&gt;
&lt;span class="nv"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;con1 &lt;span class="nv"&gt;Hostname&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;f267c8cc5b55 &lt;span class="nv"&gt;IP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;172.18.0.2 &lt;span class="nv"&gt;Mac&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;02:42:ac:12:00:02 &lt;span class="nv"&gt;Bridge&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; docker0
&lt;span class="nv"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;con2 &lt;span class="nv"&gt;Hostname&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;fe0bb3dcedd8 &lt;span class="nv"&gt;IP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;172.18.0.3 &lt;span class="nv"&gt;Mac&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;02:42:ac:12:00:03 &lt;span class="nv"&gt;Bridge&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; docker0
&lt;span class="nv"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;con3 &lt;span class="nv"&gt;Hostname&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;bd3c200eca8b &lt;span class="nv"&gt;IP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;172.19.0.2 &lt;span class="nv"&gt;Mac&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;02:42:ac:13:00:02 &lt;span class="nv"&gt;Bridge&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; testnet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we will have a look at existing containers' network namespaces. However, Docker does not add container namespaces as visible from host by default. So we first need to make docker container network namespaces be visible from host so that we can see them using &lt;code&gt;ip netns list&lt;/code&gt; command. Since this part is not too critical to understand I will dump all commands here.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Try to list docker network namespaces. But the result will be empty.&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;ip netns list
&amp;lt;no result&amp;gt;

&lt;span class="c"&gt;# Make docker network namespaces visible.&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /var/run/netns
&lt;span class="nv"&gt;$ pid1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;docker inspect con1 &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s1"&gt;'{{.State.Pid}}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nv"&gt;$ pid2&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;docker inspect con2 &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s1"&gt;'{{.State.Pid}}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nv"&gt;$ pid3&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;docker inspect con3 &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s1"&gt;'{{.State.Pid}}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo ln&lt;/span&gt; &lt;span class="nt"&gt;-sf&lt;/span&gt; /proc/&lt;span class="nv"&gt;$pid1&lt;/span&gt;/ns/net /var/run/netns/con1
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo ln&lt;/span&gt; &lt;span class="nt"&gt;-sf&lt;/span&gt; /proc/&lt;span class="nv"&gt;$pid2&lt;/span&gt;/ns/net /var/run/netns/con2
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo ln&lt;/span&gt; &lt;span class="nt"&gt;-sf&lt;/span&gt; /proc/&lt;span class="nv"&gt;$pid3&lt;/span&gt;/ns/net /var/run/netns/con3

&lt;span class="c"&gt;# Now we can see the container network namespaces.&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;ip netns list
con3 &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;: 3&lt;span class="o"&gt;)&lt;/span&gt;
con2 &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;: 2&lt;span class="o"&gt;)&lt;/span&gt;
con1 &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;: 1&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now as you see, we have three container namespaces, namely &lt;strong&gt;con1&lt;/strong&gt;, &lt;strong&gt;con2&lt;/strong&gt; and &lt;strong&gt;con3&lt;/strong&gt;. They have same names with their corresponding container. &lt;/p&gt;

&lt;p&gt;Let's see the details of each containers' network interfaces (NIC) on both side of their veth pairs. We will interpret the result afterwards.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Remember, a &lt;em&gt;veth pair&lt;/em&gt; is kinda a network cable which has two NICs on each end which connects a container network namespace to other devices which are also connected to same linux bridges.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="c"&gt;# See 'con1' virtual network interface and ipv4 address.&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;ip netns &lt;span class="nb"&gt;exec &lt;/span&gt;con1 ip a | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s1"&gt;'inet.*eth0'&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s1"&gt;'eth0@'&lt;/span&gt;
22: eth0@if23: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc noqueue state UP group default
    inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0

&lt;span class="c"&gt;# See 'con2' virtual network interface and ipv4 address.&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;ip netns &lt;span class="nb"&gt;exec &lt;/span&gt;con2 ip a | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s1"&gt;'inet.*eth0'&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s1"&gt;'eth0@'&lt;/span&gt;
24: eth0@if25: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc noqueue state UP group default
    inet 172.18.0.3/16 brd 172.18.255.255 scope global eth0

&lt;span class="c"&gt;# See 'con3' virtual network interface and ipv4 address.&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;ip netns &lt;span class="nb"&gt;exec &lt;/span&gt;con3 ip a | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s1"&gt;'inet.*eth0'&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s1"&gt;'eth0@'&lt;/span&gt;
34: eth0@if35: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc noqueue state UP group default
    inet 172.19.0.2/16 brd 172.19.255.255 scope global eth0

&lt;span class="c"&gt;# See docker bridges' and containers' NICs on the host side.&lt;/span&gt;
...
3: docker0: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc noqueue state UP group default
    &lt;span class="nb"&gt;link&lt;/span&gt;/ether 02:42:7c:72:8a:f2 brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.1/16 brd 172.18.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:7cff:fe72:8af2/64 scope &lt;span class="nb"&gt;link
       &lt;/span&gt;valid_lft forever preferred_lft forever
23: vethd1d3c7f@if22: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc noqueue master docker0 state UP
 group default
    &lt;span class="nb"&gt;link&lt;/span&gt;/ether d6:92:c7:41:c6:b9 brd ff:ff:ff:ff:ff:ff link-netnsid 1
    inet6 fe80::d492:c7ff:fe41:c6b9/64 scope &lt;span class="nb"&gt;link
       &lt;/span&gt;valid_lft forever preferred_lft forever
25: veth622799a@if24: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc noqueue master docker0 state UP
 group default
    &lt;span class="nb"&gt;link&lt;/span&gt;/ether fa:47:38:e1:eb:04 brd ff:ff:ff:ff:ff:ff link-netnsid 2
    inet6 fe80::f847:38ff:fee1:eb04/64 scope &lt;span class="nb"&gt;link
       &lt;/span&gt;valid_lft forever preferred_lft forever
30: br-6c1c92f34df9: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc noqueue state UP group default
    &lt;span class="nb"&gt;link&lt;/span&gt;/ether 02:42:a3:0b:d6:71 brd ff:ff:ff:ff:ff:ff
    inet 172.19.0.1/16 brd 172.19.255.255 scope global br-6c1c92f34df9
       valid_lft forever preferred_lft forever
    inet6 fe80::42:a3ff:fe0b:d671/64 scope &lt;span class="nb"&gt;link
       &lt;/span&gt;valid_lft forever preferred_lft forever
35: veth05790ff@if34: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc noqueue master br-6c1c92f34df9
state UP group default
    &lt;span class="nb"&gt;link&lt;/span&gt;/ether de:d4:74:dd:ea:5c brd ff:ff:ff:ff:ff:ff link-netnsid 3
    inet6 fe80::dcd4:74ff:fedd:ea5c/64 scope &lt;span class="nb"&gt;link
       &lt;/span&gt;valid_lft forever preferred_lft forever

&lt;span class="c"&gt;# Ping 'con2' from 'con1' network. (SUCCESS)&lt;/span&gt;
ubuntu@vm0:~&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;ip netns &lt;span class="nb"&gt;exec &lt;/span&gt;con1 ping 172.18.0.3
PING 172.18.0.3 &lt;span class="o"&gt;(&lt;/span&gt;172.18.0.3&lt;span class="o"&gt;)&lt;/span&gt; 56&lt;span class="o"&gt;(&lt;/span&gt;84&lt;span class="o"&gt;)&lt;/span&gt; bytes of data.
64 bytes from 172.18.0.3: &lt;span class="nv"&gt;icmp_seq&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1 &lt;span class="nv"&gt;ttl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;64 &lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0.040 ms
64 bytes from 172.18.0.3: &lt;span class="nv"&gt;icmp_seq&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;2 &lt;span class="nv"&gt;ttl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;64 &lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0.037 ms
&lt;span class="nt"&gt;---&lt;/span&gt; 172.18.0.3 ping statistics &lt;span class="nt"&gt;---&lt;/span&gt;
2 packets transmitted, 2 received, 0% packet loss, &lt;span class="nb"&gt;time &lt;/span&gt;1023ms

&lt;span class="c"&gt;# Ping 'con3' from 'con1' network. (FAIL)&lt;/span&gt;
ubuntu@vm0:~&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;ip netns &lt;span class="nb"&gt;exec &lt;/span&gt;con1 ping 172.19.0.2
PING 172.19.0.2 &lt;span class="o"&gt;(&lt;/span&gt;172.19.0.2&lt;span class="o"&gt;)&lt;/span&gt; 56&lt;span class="o"&gt;(&lt;/span&gt;84&lt;span class="o"&gt;)&lt;/span&gt; bytes of data.
&lt;span class="nt"&gt;---&lt;/span&gt; 172.19.0.2 ping statistics &lt;span class="nt"&gt;---&lt;/span&gt;
73 packets transmitted, 0 received, 100% packet loss, &lt;span class="nb"&gt;time &lt;/span&gt;73728ms
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's interpret the results and sum up.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Container&lt;/th&gt;
&lt;th&gt;veth NIC on Container&lt;/th&gt;
&lt;th&gt;veth NIC on Bridge&lt;/th&gt;
&lt;th&gt;Bridge&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;con1&lt;/td&gt;
&lt;td&gt;22: eth0@if23 172.18.0.2&lt;/td&gt;
&lt;td&gt;23: vethd1d3c7f@if22&lt;/td&gt;
&lt;td&gt;docker0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;con2&lt;/td&gt;
&lt;td&gt;24: eth0@if25 172.18.0.3&lt;/td&gt;
&lt;td&gt;25: veth622799a@if24&lt;/td&gt;
&lt;td&gt;docker0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;con3&lt;/td&gt;
&lt;td&gt;34: eth0@if35 172.19.0.2&lt;/td&gt;
&lt;td&gt;35: veth05790ff@if34&lt;/td&gt;
&lt;td&gt;br-6c1c92f34df9&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;One end of veth pair (&lt;em&gt;eth0@if23&lt;/em&gt;) is in container network; and the other (&lt;em&gt;vethd1d3c7f@if22&lt;/em&gt;) is in host network (or docker0 bridge).&lt;/li&gt;
&lt;li&gt;See that NIC names end with other peer NIC's line number. This may help you identify a veth pair when you see them.&lt;/li&gt;
&lt;li&gt;When you run &lt;code&gt;ip addr list&lt;/code&gt; command; you only see NICs in host network.&lt;/li&gt;
&lt;li&gt;In order to execute some command inside container's network you don't need to login to the container. Just execute your command like this: &lt;code&gt;ip netns exec &amp;lt;name of namespace&amp;gt; &amp;lt;shell command&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;NICs on bridges do not have ip addresses.&lt;/li&gt;
&lt;li&gt;Ping is &lt;strong&gt;successful&lt;/strong&gt; from &lt;em&gt;con1&lt;/em&gt; to &lt;em&gt;con2&lt;/em&gt; since they are both connected to default &lt;em&gt;docker0&lt;/em&gt; bridge.&lt;/li&gt;
&lt;li&gt;Ping is &lt;strong&gt;failed from&lt;/strong&gt; &lt;em&gt;con1&lt;/em&gt; to &lt;em&gt;con3&lt;/em&gt; since they are connected to different bridges and they are not connected. That is basically how containers or container groups are isolated from each other.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also just try some commands in container networks and play around using the command we mentioned above "&lt;em&gt;ip netns exec ...&lt;/em&gt;". You can run &lt;em&gt;ip a&lt;/em&gt;, &lt;em&gt;traceroute 8.8.8.8&lt;/em&gt;, &lt;em&gt;ping 172.18.0.3&lt;/em&gt; or whatever you want.&lt;/p&gt;

&lt;p&gt;That's all I want to say for now. I believe that is enough to understand very basics of docker container networking. Let's continue with the next part. &lt;/p&gt;



&lt;h2&gt;
  
  
  2- How to Manually Create A Container Network - Using Linux Network Namespaces and Veth Pair
&lt;/h2&gt;

&lt;p&gt;Now we will create a &lt;em&gt;network namespace&lt;/em&gt; and a &lt;em&gt;veth pair&lt;/em&gt;; then connect &lt;em&gt;"host network"&lt;/em&gt; to &lt;em&gt;"container network"&lt;/em&gt; using this veth pair.&lt;/p&gt;

&lt;p&gt;Let's start with creating a new empty network namespace:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create network namespace.&lt;/span&gt;
ubuntu@vm0:~&lt;span class="nv"&gt;$ &lt;/span&gt;ip netns add sample

&lt;span class="c"&gt;# List namespaces.&lt;/span&gt;
ubuntu@vm0:~&lt;span class="nv"&gt;$ &lt;/span&gt;ip netns list
sample
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we create a veth pair in default network namespace:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create new veth pair.&lt;/span&gt;
ubuntu@vm0:~&lt;span class="nv"&gt;$ &lt;/span&gt;ip &lt;span class="nb"&gt;link &lt;/span&gt;add veth1 &lt;span class="nb"&gt;type &lt;/span&gt;veth peer name veth2

&lt;span class="c"&gt;# List network interfaces. &lt;/span&gt;
ubuntu@vm0:~&lt;span class="nv"&gt;$ &lt;/span&gt;ip a
20: veth2@veth1: &amp;lt;BROADCAST,MULTICAST,M-DOWN&amp;gt; mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    &lt;span class="nb"&gt;link&lt;/span&gt;/ether de:f9:8e:4c:75:60 brd ff:ff:ff:ff:ff:ff
21: veth1@veth2: &amp;lt;BROADCAST,MULTICAST,M-DOWN&amp;gt; mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    &lt;span class="nb"&gt;link&lt;/span&gt;/ether de:6f:db:d8:58:cd brd ff:ff:ff:ff:ff:ff
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point we have a container network (network namespace) named &lt;em&gt;"sample"&lt;/em&gt; and a veth pair which have network interfaces named &lt;em&gt;"veth1"&lt;/em&gt; and &lt;em&gt;"veth2"&lt;/em&gt; on each end. And now we can connect &lt;em&gt;host network&lt;/em&gt; to &lt;em&gt;sample&lt;/em&gt; network, by moving one end of the vnet pair &lt;em&gt;veth1&lt;/em&gt; to the &lt;em&gt;sample&lt;/em&gt; network. Let's do it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Move veth1 to 'sample' namespace.&lt;/span&gt;
ubuntu@vm0:~&lt;span class="nv"&gt;$ &lt;/span&gt;ip &lt;span class="nb"&gt;link set &lt;/span&gt;veth1 netns sample

&lt;span class="c"&gt;# List interfaces in 'default' namespace.&lt;/span&gt;
ubuntu@vm0:~&lt;span class="nv"&gt;$ &lt;/span&gt;ip a
20: veth2@if21: &amp;lt;BROADCAST,MULTICAST&amp;gt; mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we connected two host and container network namespaces. But we are not there yet. We have still many things to make it work.&lt;/p&gt;

&lt;p&gt;If you look at the last screen, you can see that we can no longer see &lt;em&gt;veth1&lt;/em&gt; in &lt;em&gt;default&lt;/em&gt; network namespace. Because we moved it to the &lt;em&gt;sample&lt;/em&gt; network namespace, but &lt;code&gt;ip netns list&lt;/code&gt; command is executed in &lt;em&gt;default&lt;/em&gt; network namespace. &lt;/p&gt;

&lt;p&gt;In order to see &lt;em&gt;veth1&lt;/em&gt; again, we need to run &lt;code&gt;ip link list&lt;/code&gt; command in the &lt;em&gt;sample&lt;/em&gt; network namespace. For this we will use &lt;code&gt;ip netns exec &amp;lt;command&amp;gt;&lt;/code&gt; command, which executes the given command in the specified network namespace. Let's do it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# List interface in 'sample' namespace.&lt;/span&gt;
ubuntu@vm0:~&lt;span class="nv"&gt;$ &lt;/span&gt;ip netns &lt;span class="nb"&gt;exec &lt;/span&gt;sample ip &lt;span class="nb"&gt;link &lt;/span&gt;list
21: veth1@if20: &amp;lt;BROADCAST,MULTICAST&amp;gt; mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;There is one thing to note. Previously, &lt;em&gt;veth2&lt;/em&gt; was listed as &lt;code&gt;20: veth2@veth1 ..&lt;/code&gt; in response to &lt;code&gt;ip a&lt;/code&gt; command. Now its name is listed as &lt;code&gt;20: veth2@if21 ..&lt;/code&gt;. Similary &lt;em&gt;veth1&lt;/em&gt; is also listed as &lt;code&gt;20: veth1@21 ...&lt;/code&gt; from now on. It seems veth pair's network interfaces started to use other veth end's line number in its names. Knowing this may help identify veth pairs in different network namespaces.    &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h5&gt;
  
  
  Configure Networking Between Host and Container
&lt;/h5&gt;

&lt;p&gt;At this point we have network namespace named &lt;em&gt;"sample"&lt;/em&gt; and this network namespaces is connected to the &lt;em&gt;"default"&lt;/em&gt; network namespace by a veth pair. &lt;br&gt;
&lt;code&gt;(container network) veth1 &amp;lt;--&amp;gt; veth2 (host network)&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Sometimes I may refer &lt;em&gt;sample&lt;/em&gt; network namespace as &lt;em&gt;container network&lt;/em&gt;; and &lt;em&gt;default network namespace&lt;/em&gt; as &lt;em&gt;host network&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;But still we are not there yet.&lt;/em&gt; We still need to configure many things to be able to access to the container network from host network by IPv4 address; or access to internet from container network. Let's do the following steps quickly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a linux bridge &lt;em&gt;samplebr&lt;/em&gt;. (like &lt;em&gt;docker0&lt;/em&gt; bride)&lt;/li&gt;
&lt;li&gt;Join &lt;em&gt;veth2&lt;/em&gt; network interface to &lt;em&gt;samplebr&lt;/em&gt; bridge. &lt;/li&gt;
&lt;li&gt;Assign an ipv4 address to &lt;em&gt;samplebr&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Assign an ipv4 address to &lt;em&gt;veth1&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Up &lt;em&gt;veth1&lt;/em&gt; device.&lt;/li&gt;
&lt;li&gt;Up container localhost.&lt;/li&gt;
&lt;li&gt;Up &lt;em&gt;veth2&lt;/em&gt; device.&lt;/li&gt;
&lt;li&gt;Up &lt;em&gt;samplebr&lt;/em&gt; device.&lt;/li&gt;
&lt;li&gt;Add bridge ip as default gateway for the container network.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create a linux bridge *samplebr*.&lt;/span&gt;
ubuntu@vm0:~&lt;span class="nv"&gt;$ &lt;/span&gt;ip &lt;span class="nb"&gt;link &lt;/span&gt;add name samplebr &lt;span class="nb"&gt;type &lt;/span&gt;bridge

&lt;span class="c"&gt;# Join *veth2* network interface to *samplebr* bridge.&lt;/span&gt;
ubuntu@vm0:~&lt;span class="nv"&gt;$ &lt;/span&gt;ip &lt;span class="nb"&gt;link set &lt;/span&gt;veth2 master samplebr

&lt;span class="c"&gt;# * Assign an ipv4 address to *samplebr*.&lt;/span&gt;
ubuntu@vm0:~&lt;span class="nv"&gt;$ &lt;/span&gt;ip addr add 10.1.1.1/24 brd + dev samplebr

&lt;span class="c"&gt;# Assign an ipv4 address to *veth1*.&lt;/span&gt;
ubuntu@vm0:~&lt;span class="nv"&gt;$ &lt;/span&gt;ip netns &lt;span class="nb"&gt;exec &lt;/span&gt;sample ip addr add 10.1.1.2/24 dev veth1

&lt;span class="c"&gt;# Up *veth1* device.&lt;/span&gt;
ubuntu@vm0:~&lt;span class="nv"&gt;$ &lt;/span&gt;ip netns &lt;span class="nb"&gt;exec &lt;/span&gt;sample ip &lt;span class="nb"&gt;link set &lt;/span&gt;veth1 up

&lt;span class="c"&gt;# Up container localhost.&lt;/span&gt;
ubuntu@vm0:~&lt;span class="nv"&gt;$ &lt;/span&gt;ip netns &lt;span class="nb"&gt;exec &lt;/span&gt;sample ip &lt;span class="nb"&gt;link set &lt;/span&gt;lo up

&lt;span class="c"&gt;# Up *veth2* device.&lt;/span&gt;
ubuntu@vm0:~&lt;span class="nv"&gt;$ &lt;/span&gt;ip &lt;span class="nb"&gt;link set &lt;/span&gt;veth2 up

&lt;span class="c"&gt;# Up *samplebr* device.&lt;/span&gt;
ubuntu@vm0:~&lt;span class="nv"&gt;$ &lt;/span&gt;ip &lt;span class="nb"&gt;link set &lt;/span&gt;samplebr up

&lt;span class="c"&gt;# Add bridge 'samplebr' as default gateway for the container network.&lt;/span&gt;
ubuntu@vm0:~&lt;span class="nv"&gt;$ &lt;/span&gt;ip netns &lt;span class="nb"&gt;exec &lt;/span&gt;sample ip route add default via 10.1.1.1


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;That's it! Now, we did setup networking between host and container network. We can test by pinging our &lt;em&gt;veth1&lt;/em&gt; network interface or container network with ipv4 &lt;code&gt;10.1.1.2&lt;/code&gt; from the host. Or we can ping host network from the container network.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ubuntu@vm0:~&lt;span class="nv"&gt;$ &lt;/span&gt;ping 10.1.1.2
PING 10.1.1.1 &lt;span class="o"&gt;(&lt;/span&gt;10.1.1.2&lt;span class="o"&gt;)&lt;/span&gt; 56&lt;span class="o"&gt;(&lt;/span&gt;84&lt;span class="o"&gt;)&lt;/span&gt; bytes of data.
64 bytes from 10.1.1.2: &lt;span class="nv"&gt;icmp_seq&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1 &lt;span class="nv"&gt;ttl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;64 &lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0.022 ms
64 bytes from 10.1.1.2: &lt;span class="nv"&gt;icmp_seq&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;2 &lt;span class="nv"&gt;ttl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;64 &lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0.028 ms

ubuntu@vm0:~&lt;span class="nv"&gt;$ &lt;/span&gt;ip netns &lt;span class="nb"&gt;exec &lt;/span&gt;sample ping 172.17.52.174
PING 172.17.52.174 &lt;span class="o"&gt;(&lt;/span&gt;172.17.52.174&lt;span class="o"&gt;)&lt;/span&gt; 56&lt;span class="o"&gt;(&lt;/span&gt;84&lt;span class="o"&gt;)&lt;/span&gt; bytes of data.
64 bytes from 172.17.52.174: &lt;span class="nv"&gt;icmp_seq&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1 &lt;span class="nv"&gt;ttl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;64 &lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0.024 ms
64 bytes from 172.17.52.174: &lt;span class="nv"&gt;icmp_seq&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;2 &lt;span class="nv"&gt;ttl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;64 &lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0.143 ms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, we can not reach external networks (internet) yet. We have a little more things to configure.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ubuntu@vm0:~&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;ip netns &lt;span class="nb"&gt;exec &lt;/span&gt;sample ping 8.8.8.8
connect: Network is unreachable

ubuntu@vm0:~&lt;span class="nv"&gt;$ &lt;/span&gt;ip netns &lt;span class="nb"&gt;exec &lt;/span&gt;sample ping github.com
ping: github.com: Temporary failure &lt;span class="k"&gt;in &lt;/span&gt;name resolution
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Configure Networking From Container To Internet
&lt;/h5&gt;

&lt;p&gt;We don't yet have internet connection from container network to internet. DNS resolver also is not working. Let's fix these all.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Make sure *ip_forwarding* is enabled.&lt;/span&gt;
root@test1:~# sysctl &lt;span class="nt"&gt;-w&lt;/span&gt; net.ipv4.ip_forward&lt;span class="o"&gt;=&lt;/span&gt;1

&lt;span class="c"&gt;# Enable sending requests and getting responses to/from internet (ping 8.8.8.8).&lt;/span&gt;
root@test1:~# iptables &lt;span class="nt"&gt;-t&lt;/span&gt; nat &lt;span class="nt"&gt;-A&lt;/span&gt; POSTROUTING &lt;span class="nt"&gt;-s&lt;/span&gt; 10.1.1.0/24 &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; samplebr &lt;span class="nt"&gt;-j&lt;/span&gt; MASQUERADE

&lt;span class="c"&gt;# Find your dns nameserver for the host network interface (eth0)&lt;/span&gt;
root@test1:~#  systemd-resolve &lt;span class="nt"&gt;--status&lt;/span&gt;

&lt;span class="c"&gt;# Create resolv.conf file for container network.&lt;/span&gt;
root@test1:~# &lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /etc/netns/sample/
root@test1:~# &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"nameserver 172.17.52.161"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /etc/netns/sample/resolv.conf

&lt;span class="c"&gt;# Test dns again.&lt;/span&gt;
root@test1:~# ip netns &lt;span class="nb"&gt;exec &lt;/span&gt;sample ping github.com
PING github.com &lt;span class="o"&gt;(&lt;/span&gt;140.82.118.3&lt;span class="o"&gt;)&lt;/span&gt; 56&lt;span class="o"&gt;(&lt;/span&gt;84&lt;span class="o"&gt;)&lt;/span&gt; bytes of data.
64 bytes from lb-140-82-118-3-ams.github.com &lt;span class="o"&gt;(&lt;/span&gt;140.82.118.3&lt;span class="o"&gt;)&lt;/span&gt;: &lt;span class="nv"&gt;icmp_seq&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1 &lt;span class="nv"&gt;ttl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;49 &lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;28.5 ms
64 bytes from lb-140-82-118-3-ams.github.com &lt;span class="o"&gt;(&lt;/span&gt;140.82.118.3&lt;span class="o"&gt;)&lt;/span&gt;: &lt;span class="nv"&gt;icmp_seq&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;2 &lt;span class="nv"&gt;ttl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;49 &lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;27.4 ms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Voila! We made it. Now we have a container network which is able to connect to the host network, internet or other container networks (network namespaces) which is attached to the same linux bridge (if any). &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If still you can not connect to the internet from container network; it is possible that some docker rules in iptables are blocking. Run this command &lt;code&gt;# iptables -L&lt;/code&gt;. If you see &lt;em&gt;"Chain FORWARD (policy DROP)"&lt;/em&gt; somewhere in the result; execute these commands: &lt;code&gt;# iptables -F FORWARD&lt;/code&gt; &lt;code&gt;# iptables -P FORWARD ACCEPT&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  FINAL WORDS
&lt;/h2&gt;

&lt;p&gt;And we are done. I think I explained most of the things I learnt in last weeks. Of course for ease of understanding or simplicity I omitted or did not go much into some parts. But I think we got to the point.&lt;/p&gt;

&lt;p&gt;Please see also the resources I shared below, go over them if you find time. They were beneficial to me.&lt;/p&gt;

&lt;h5&gt;
  
  
  Why All These Information Is Important
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;It makes you happy and satisfies your curiosity. :)&lt;/li&gt;
&lt;li&gt;Personally for me, it makes it very easy to understand and reason about when someone talks or writes about container networking or kubernetes networking generally.&lt;/li&gt;
&lt;li&gt;You are better armed if you face a network issue inside a container or across containers. No You can use various tools inside container namespaces to debug and resolve issues. ('ip a', 'ip netns exec  ', 'ping', 'traceroute', 'nslookup', 'tcpdump' ...) &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I also want to write two follow-up posts. One will be &lt;em&gt;Basic Networking for Cloud: IP, Subnets, and CIDR&lt;/em&gt;; and obviously next will be about &lt;em&gt;Kubernetes Networking 101&lt;/em&gt;. I will also try to keep it shorter this time.&lt;/p&gt;

&lt;p&gt;I hope you enjoy.  &lt;/p&gt;




&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://platform9.com/blog/container-namespaces-deep-dive-container-networking/" rel="noopener noreferrer"&gt;Container Namespaces - Deep Dive Container Networking&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.scottlowe.org/2013/09/04/introducing-linux-network-namespaces/" rel="noopener noreferrer"&gt;Introducing Linux Network Namespaces&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://seagullbird.xyz/posts/linux-netns/" rel="noopener noreferrer"&gt;Linux Network Namespace on seagullbird.xyz&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/google-cloud/understanding-kubernetes-networking-pods-7117dd28727" rel="noopener noreferrer"&gt;Understanding Kubernetes Networking&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=6v_BDHIgOY8&amp;amp;feature=youtu.be" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=6v_BDHIgOY8&amp;amp;feature=youtu.be&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>docker</category>
      <category>linux</category>
      <category>networking</category>
    </item>
    <item>
      <title>How to Change Default DotNet SDK Version</title>
      <dc:creator>Safak Ulusoy</dc:creator>
      <pubDate>Tue, 25 Jun 2019 13:19:24 +0000</pubDate>
      <link>https://dev.to/polarbit/how-to-change-default-dotnet-sdk-version-43ph</link>
      <guid>https://dev.to/polarbit/how-to-change-default-dotnet-sdk-version-43ph</guid>
      <description>&lt;p&gt;When I installed ".Net Core 3 SDK (preview 6)", default version of &lt;em&gt;dotnet core sdk&lt;/em&gt; on my system is changed to this new version. Then I needed to revert the default version to "2.x.x" in some places. So I followed the steps below. &lt;/p&gt;

&lt;p&gt;See &lt;a href="https://docs.microsoft.com/en-us/dotnet/core/tools/global-json" rel="noopener noreferrer"&gt;Official Documentation&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  See Installed DotNet Core SDK and Runtime Versions
&lt;/h4&gt;

&lt;p&gt;In order to see all installed &lt;strong&gt;dotnet SDK&lt;/strong&gt; versions (and currently used default version), run:&lt;br&gt;
&lt;code&gt;dotnet --version&lt;/code&gt;&lt;br&gt;
&lt;code&gt;dotnet --list-sdks&lt;/code&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn4izfg47ahfczor1qbeo.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn4izfg47ahfczor1qbeo.PNG"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In order to see all installed &lt;strong&gt;dotnet Runtime&lt;/strong&gt; versions, run:&lt;br&gt;
&lt;code&gt;dotnet --list-runtimes&lt;/code&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3u7vdo3fcw6nkr7i7jxb.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3u7vdo3fcw6nkr7i7jxb.PNG"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Change Default DotNet SDK Version using global.json File
&lt;/h4&gt;

&lt;p&gt;In order to change default &lt;em&gt;dotnet SDK version&lt;/em&gt;, place a global.json file in the current folder or any parent folder with the contents below. You can create the global.json file manually, or use the dotnet cli command &lt;code&gt;dotnet new globaljson&lt;/code&gt;. &lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Now &lt;em&gt;dotnet core sdk&lt;/em&gt; version is reverted back in the folder which &lt;em&gt;global.json&lt;/em&gt; resides, or in it's subfolders.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fptwb1rhh2mc9oqqs21g8.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fptwb1rhh2mc9oqqs21g8.PNG"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; By default &lt;code&gt;dotnet new globaljson&lt;/code&gt; cli command sets the SDK version using the current effective version. You can change this behaviour by adding optional &lt;code&gt;--sdk-version=2.2.300&lt;/code&gt; parameter.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


</description>
      <category>dotnet</category>
    </item>
  </channel>
</rss>
