|
| 1 | +--- |
| 2 | +title: Docker Containers |
| 3 | +author: troglobit |
| 4 | +date: 2024-03-08 15:44:42 +0100 |
| 5 | +categories: [showcase] |
| 6 | +tags: [container, containers, docker podman] |
| 7 | +--- |
| 8 | + |
| 9 | +{: width="200" .right} |
| 10 | + |
| 11 | +A network operating system for switches and routers, that runs Docker? |
| 12 | + |
| 13 | +Yes, as of Infix v24.02 support for running containers using [podman][1] |
| 14 | +is supported. Because networking is a first class citizen in Infix, you |
| 15 | +can set up quite advanced *virtual topologies* with containers. This |
| 16 | +blog post is the first in a series of posts that aims to show this. |
| 17 | + |
| 18 | +> This post assumes knowledge and familiarity with the [Infix Network |
| 19 | +> Operating System](https://kernelkit.github.io/). Ensure you have |
| 20 | +> either a network connection or console access to your Infix system and |
| 21 | +> can log in to it using SSH. Recommended reading includes the |
| 22 | +> [networking documentation][0]. |
| 23 | +{: .prompt-info } |
| 24 | + |
| 25 | + |
| 26 | +---- |
| 27 | + |
| 28 | +## Introduction |
| 29 | + |
| 30 | +All configuration and administration of networking and containers is |
| 31 | +done through the CLI: |
| 32 | + |
| 33 | +``` |
| 34 | +admin@infix:~$ cli |
| 35 | +
|
| 36 | +See the 'help' command for an introduction to the system |
| 37 | +
|
| 38 | +admin@infix:/> |
| 39 | +``` |
| 40 | + |
| 41 | +Notice the slight change in the prompt. Return to the Bash shell using |
| 42 | +the `exit` command, or Ctrl-D, from the "admin-exec" top level of the |
| 43 | +CLI. |
| 44 | + |
| 45 | + |
| 46 | +## Networking Basics |
| 47 | + |
| 48 | +{: width="430" .right} |
| 49 | + |
| 50 | +In Infix all network access has to be set up explicitly, so there is no |
| 51 | +default container networking setup (it's a security thing). There are |
| 52 | +two types available to choose from: |
| 53 | + |
| 54 | + - `host`: Ethernet interface |
| 55 | + - `bridge`: Masquerading bridge |
| 56 | + |
| 57 | +The first can be any physical port/interface which is handed over to the |
| 58 | +container or, more commonly, one end of a *VETH pair*. |
| 59 | + |
| 60 | +The latter type is usually available as `docker0`, or `podman0`, on your |
| 61 | +host system. These bridges are managed by the container runtime, in the |
| 62 | +case of Infix this is podman. When a container is set to a container |
| 63 | +bridge network, a VETH pair is automatically created when the container |
| 64 | +is started -- one end is attached to the bridge and the other connected |
| 65 | +to the container as a regular interface. |
| 66 | + |
| 67 | +Here's how you create a container bridge: |
| 68 | + |
| 69 | +``` |
| 70 | +admin@infix:/> configure |
| 71 | +admin@infix:/config> edit interface docker0 |
| 72 | +admin@infix:/config/interface/docker0> set container-network |
| 73 | +admin@infix:/config/interface/docker0> leave |
| 74 | +``` |
| 75 | + |
| 76 | + |
| 77 | +## Web Server Container |
| 78 | + |
| 79 | +{: width="60" .left} |
| 80 | + |
| 81 | +Now, time for a basic web server example. For our first container we'll |
| 82 | +be using [docker://nginx:alpine](https://hub.docker.com/_/nginx). It's |
| 83 | +a relatively small container with the Nginx web server built on top of |
| 84 | +the Alpine Linux image. |
| 85 | + |
| 86 | +``` |
| 87 | +admin@infix:/> configure |
| 88 | +admin@infix:/config> edit container web |
| 89 | +admin@infix:/config/container/web/> set image docker://nginx:alpine |
| 90 | +admin@infix:/config/container/web/> edit network |
| 91 | +admin@infix:/config/container/web/network/> set interface docker0 |
| 92 | +admin@infix:/config/container/web/network/> set publish 8080:80 |
| 93 | +admin@infix:/config/container/web/network/> leave |
| 94 | +``` |
| 95 | + |
| 96 | +Issuing the command `leave` queues a job to download the image and |
| 97 | +create a container in the background. To see the progress: |
| 98 | + |
| 99 | +``` |
| 100 | +admin@infix:/> show log container |
| 101 | +``` |
| 102 | + |
| 103 | +or just poll the status command: |
| 104 | + |
| 105 | +``` |
| 106 | +admin@infix:/> show container |
| 107 | +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES |
| 108 | +c60a6deeea4e docker.io/library/nginx:alpine nginx -g daemon o... 2 minutes ago Up 2 minutes 0.0.0.0:8080->80/tcp web |
| 109 | +``` |
| 110 | + |
| 111 | +You should now be able to access the web server on port 8080 of the |
| 112 | +host's IP address. |
| 113 | + |
| 114 | + |
| 115 | +_Nginx default landing page._ |
| 116 | + |
| 117 | +## Customizing Content |
| 118 | + |
| 119 | +Deceivingly enough, Docker containers have a thin writable layer that |
| 120 | +allows changing just about any file in the image. The big *HOWEVER* |
| 121 | +though is that this layer doesn't survive configuration changes or, |
| 122 | +most importantly, image upgrades. |
| 123 | + |
| 124 | +> Use Volumes! They are a specialized type of "mount", for people |
| 125 | +> familiar with UNIX systems. Infix currently supports *named mounts* |
| 126 | +> that provide a *persistent* writable layer for containers. |
| 127 | +{: .prompt-tip } |
| 128 | + |
| 129 | +Here's how to add a volume to your container: |
| 130 | + |
| 131 | +``` |
| 132 | +admin@infix:/> configure |
| 133 | +admin@infix:/config/> edit container web |
| 134 | +admin@infix:/config/container/web/> edit volume content |
| 135 | +admin@infix:/config/container/web/volume/content/> set target /usr/share/nginx/html |
| 136 | +admin@infix:/config/container/web/volume/content/> leave |
| 137 | +``` |
| 138 | + |
| 139 | +Named volumes have the downside of being opaque to the host, so the |
| 140 | +easiest is to upload the content using `scp` or editing it directly |
| 141 | +in the container: |
| 142 | + |
| 143 | +``` |
| 144 | +admin@infix:/> container shell web |
| 145 | +d95ce9f7674d:/# vi /usr/share/nginx/html/ |
| 146 | +50x.html index.html |
| 147 | +d95ce9f7674d:/# vi /usr/share/nginx/html/index.html |
| 148 | +... edit, save & exit from vi ... |
| 149 | +d95ce9f7674d:/# |
| 150 | +``` |
| 151 | + |
| 152 | + |
| 153 | +## Container Content in Device Configuration |
| 154 | + |
| 155 | +Save the best for last? A neat feature is that container content can be |
| 156 | +saved in the system's `startup-config` and therefore be automatically be |
| 157 | +backed up by administrators snapshotting the system. |
| 158 | + |
| 159 | +> This also means that custom(er) builds of Infix can bundle a built-in |
| 160 | +> container's initial configuration in the Infix `factory-config`, which |
| 161 | +> can be very useful when deploying at new installations. |
| 162 | +{: .prompt-info } |
| 163 | + |
| 164 | +This feature is perfectly suited for container applications that need a |
| 165 | +specific site setup. For example a configuration file. Here we use the |
| 166 | +same container image to bundle an `index.html` file: |
| 167 | + |
| 168 | +``` |
| 169 | +admin@infix:/> configure |
| 170 | +admin@infix:/config/> edit container web |
| 171 | +admin@infix:/config/container/web/> edit mount index.html |
| 172 | +admin@infix:/config/container/web/mount/index.html/> set target /usr/share/nginx/html/index.html |
| 173 | +admin@infix:/config/container/web/mount/index.html/> text-editor content |
| 174 | +``` |
| 175 | + |
| 176 | +The `content` setting is an alternative to `source` for file mounts |
| 177 | +which allows providing the contents through the device's configuration. |
| 178 | + |
| 179 | +> The `text-editor` command can be changed to use other editors in the |
| 180 | +> `system` configuration context, by default it starts a Micro Emacs |
| 181 | +> clone, Mg. See the [documentation][3] for more information. |
| 182 | +{: .prompt-tip } |
| 183 | + |
| 184 | +Paste in this: |
| 185 | + |
| 186 | +```html |
| 187 | +<!DOCTYPE html> |
| 188 | +<html> |
| 189 | +<head> |
| 190 | +<title>Welcome to Infix!</title> |
| 191 | +<style> |
| 192 | +html { color-scheme: light dark; } |
| 193 | +body { width: 35em; margin: 0 auto; |
| 194 | +font-family: Tahoma, Verdana, Arial, sans-serif; } |
| 195 | +</style> |
| 196 | +</head> |
| 197 | +<body> |
| 198 | +<h1>Welcome to Infix the Network Operating System!</h1> |
| 199 | +<p>If you see this page, the nginx web server container has been |
| 200 | +installed and is working.</p> |
| 201 | + |
| 202 | +<p>For online documentation and support please refer to the |
| 203 | +<a href="https://kernelkit.github.io/">Infix Homepage</a>.<br/> |
| 204 | + |
| 205 | +Commercial support and customer adaptations are available from |
| 206 | +<a href="https://addiva.se/electronics">Addiva Elektronik AB</a>.</p> |
| 207 | + |
| 208 | +<p><em>Thank you for reading this blog post!</em></p> |
| 209 | +</body> |
| 210 | +</html> |
| 211 | +``` |
| 212 | + |
| 213 | +Save and exit with the usual Emacs salute: C-x C-x (Ctrl-X Ctrl-c, or |
| 214 | +hold down Ctrl while tapping the X and C keys). |
| 215 | + |
| 216 | +Leave configuration context to activate your changes: |
| 217 | + |
| 218 | +``` |
| 219 | +admin@infix:/config/container/web/mount/index.html/> leave |
| 220 | +``` |
| 221 | + |
| 222 | +Reload your browser to see the change. |
| 223 | + |
| 224 | + |
| 225 | +## Fin |
| 226 | + |
| 227 | +That's the end of the first post about containers in Infix. Remember to |
| 228 | +save your changes for next boot: |
| 229 | + |
| 230 | +``` |
| 231 | +admin@infix:/> copy running-config startup-config |
| 232 | +``` |
| 233 | + |
| 234 | +Take care! <3 |
| 235 | + |
| 236 | +[0]: https://github.com/kernelkit/infix/blob/main/doc/networking.md |
| 237 | +[1]: https://podman.io |
| 238 | +[2]: https://www.docker.com/resources/what-container/ |
| 239 | +[3]: https://github.com/kernelkit/infix/blob/main/doc/cli/text-editor.md |
0 commit comments