Containers on EOS
Container-based deployments make creating cloud portable applications extremely easy. An application can be written on normal build infrastructure, that in turn can be run on a EOS switch or any Linux device that runs docker run time engine. So the same applications that are ran on a server for microservices can be run on switch with Arista EOS. Since Arista extensible operating system is simply linux (CentOS at this time – 2021) we are able to integrate docker run time engine into the operating system.
Containers give us the agility and control to run any application without worrying much about the dependency issues with the existing EOS packages. They are also lightweight as compared to full VMs.
Container-Manager provides a way to manage docker containers natively via EOS CLI. By default, this is disabled.
Note: Via bash the direct docker commands can be used, but these would need to be completely managed by the user, as they would not be visible to EOS.
Enabling container manager
Check the status
Switch(config-container-mgr)#show container-manager info Total Number of Containers: 0 Total Number of paused Containers: 0 Total Number of stopped Containers: 0 Total Number of Images: 0 Storage Driver: overlay Backing Filesystem: tmpfs Logging Driver: json-file Cgroup Driver: cgroupfs Plugins: Volume: local Network: bridge, host, macvlan, null, overlay ID: EL6P:CUNS:V4Y3:IQQ2:KTHT:UVVJ:CHJ7:FY4Q:U73Q:UXW7:DEFX:DMLZ ContainerMgr Root Dir: /var/lib/docker CPUs: 4 Total Memory: 3.81 GB
Adding a registry
By default the docker public registry is configured, but of course an internal/private registry could be used.
Switch(config-container-mgr)# registry <name> [secure] Switch(config-container-mgr-registry-name)# Switch(config-container-mgr-registry-name)# username <name> Switch(config-container-mgr-registry-name)# password <password> Switch(config-container-mgr-registry-name)# email <email-Id> Switch(config-container-mgr-registry-name)# server <registry URL>
For other options to start container-manager daemon with we can give an args option which takes a string of all the commands that the user wishes to start container-manager daemon with.
Switch(config-container-mgr)# daemon args <space separated>
The configuration for specific containers exists under a per container submode of configuration.
Note 1: We will always start a container in detached mode and prevent options for interactive and pseudo-TTY. In other words options -i and -t would be accepted only with option -d.
Note 2: DNS IP and search domains are set based on EOS configuration by default. The container ‘options’ CLI can be used to change this
container-manager container TEST image hello-world on-boot !
on-boot is an option which will enable the user to run the container after reboot. The image will be picked up from persistence storage, if present, otherwise will be pulled from configured registry – see Storage & Persistence.
Other container configuration options
- cpu shares: This command is used to allocate the CPU cycles to the container. This is a relative quantity and can have value of 2 or higher. Default value is 1024. This takes effect only when CPU intensive processes are running.
- cpu cores: This command is used to allocate the CPU cores where container should be running.
- memory: This command is used to allocate the memory used by the container. Optional unit can be b( bytes ), k( kilobytes ), m( megabytes ), g( gigabytes ). By default, bytes will be considered.
- options: To start the container using some user-configured options, space separated
- command: To provide the command that the container will start with. Space separated command and args can be given.
- container-manager start <containerName> – Start a container if its not running
- container-manager stop <containerName> – Stop a container if its running
- container-manager push <containerName> – Push a modified image to the configured repo, provided the credentials are correct
- container-manager pull <containerName> – Pull an image from the configured repo
- container-manager commit<containerName> – This command creates a new image by committing the changes made in the container. This allows to debug a container and even export it to another server.
- container-manager backup <containerName> – This command will export the contents of a container’s filesystem as a tar archive given the container name to a path. Path will be an optional parameter defaulting to /mnt/flash. Kindly note, this command will cause the image to lose it’s history and metadata.
- container-manager restore <containerName> – This command takes container name as the argument and then tries to check if we have tarred archive present locally. If it’s present, then it simply creates an empty filesystem image and imports the contents of the tarball. In case, the tarred archive is not present for the given container name then, it tries to pull the corresponding image from the docker registry using the image used to create that container from the config.
- container-manager search <search term> – Search the docker repo for images
Storage & Persistence
By default the container storage volumes (and the image itself) are only in-memory for 2 reasons;
- The amount of flash on most systems is relatively limited (unless SSD variant is ordered)
- Writes to flash storage are relatively slow
This does have the side effect that any and all modifications done to a container are lost after a reboot, as is the container image itself.
This can be addressed in two ways;
- Push the image back to the repo periodically / before a reload. The image (and modifications) are downloaded back from the repo on-boot
- Commit the container and save a local copy
#2 is accomplished with the
container-manager backup container <containerName> [imageName] [path]
When we are committing the container we should generate the similar image:tag as present in container config (imageName). This is because on reboot the image config for that container should match otherwise the switch will start downloading the latest version from the repo. In the case where there are multiple containers with the same image, and all the on-boot is configured with different changes, they would overwrite each other after the switch comes up on reboot.
To avoid this container-manager backup container <containerName> command takes another optional argument for imageName . If this is specified we would do docker commit <imageName> and then save this image. But the imageName in the container config needs to match this imageName so that on-reboot we can start the correct image.
switch1#container-manager search hello-world NAME DESCRIPTION STARS OFFICIAL AUTOMATED hello-world Hello World! (an example of minimal Docker... 1397 [OK] kitematic/hello-world-nginx A light-weight nginx container that demons... 147 tutum/hello-world Image to test docker deployments. Has Apac... 79 [OK] dockercloud/hello-world Hello World! 19 [OK] ... switch1#container-manager pull hello-world Using default tag: latest latest: Pulling from library/hello-world Digest: sha256:308866a43596e83578c7dfa15e27a73011bdd402185a84c5cd7f32a88b501a24 Status: Image is up to date for hello-world:latest switch1#container-manager start TEST TEST switch1# switch1#show container-manager log TEST Hello from Docker! This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. (i386) 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal. To try something more ambitious, you can run an Ubuntu container with: $ docker run -it ubuntu bash Share images, automate workflows, and more with a free Docker ID: https://hub.docker.com/ For more examples and ideas, visit: https://docs.docker.com/get-started/ switch1#