Remote Docker Workflow Overview

Remote Docker workflow is an alternative to traditional app deployment approaches that are using Local Manager or ioxclient tools. Remote Docker workflow is designed for developers, so we Cisco recommends that it is used only during application development and not on a production gateway.

Remote Docker workflow enables developers to use the familiar Docker CLI (or Docker-compose) tool for the entire IOx app lifecycle operations on Cisco devices. This article describes how to use the feature for a sample Docker app.

Note Although the developer can use Docker tools for the app development lifecycle, there are some operations of Docker engine which are restricted for security and maintenance reasons. Check the caveat section at the bottom of the page for more details.

Caution Because Remote Docker can run containers by bypassing and therefore invisible to the Local Manager or IOx Management Application, the Remote Docker workflow is meant to be used only on development systems and not in production systems.

Supported Platforms

For the supported platforms, see the Compatibility Matrix on DevNet: https://developer.cisco.com/docs/iox/#!feature-compatibility-matrix

Initial Setup

Before starting with the Docker tool-based app lifecycle operation, use the following steps to set up the Cisco device and local development machine:

  • Enable Remote Docker access.
  • Create the Docker application profile.
  • Setup local development machine environment.

Enable Remote Docker Access

By default, the Docker engine on Cisco platforms does not listen for external requests originating from outside the device. Therefore, you must enable Remote Docker access from Cisco IOx Local Manager.

If your image supports Remote Docker workflow, use the “Remote Docker Workflow” tab in the Cisco IOx Local Manager web interface to set up Cisco devices to use this feature.

Disabled_Remote_Docker_Access

This operation enables the docker engine to listen for external requests and generates docker client Transport Layer Security (TLS) certificates that must be copied and extracted to your local machine in either the $HOME/.docker directory on macOS or Linux, or the %USERPROFILE%/.docker directory for Windows.

Enabled_Remote_Docker_Access

Create the Docker Application Profile

Any 3rd party container application running on Cisco devices has a set of dependencies on the platform, for example, minimum compute resources required for the application, required network interfaces, and a list of peripherals that must be mounted into the container for reading and writing data from southbound sensors.

To simplify the application development process, IOx provides a way to setup pre-provision platform dependencies of the docker app with the creation of a docker app profile. Using this profile allow you to focus on the core part of application logic instead of the platform configurations and dependencies during the iterative app development cycle.

Here are the outcomes of app profile creation.

  • App dependencies are setup in the device ready for app consumption
  • IOx generates docker run command options representing these app dependencies for direct usage from the Docker CLI.

create_app_profile

The following example shows how to create a sample app profile for nginx Docker application, which needs to expose the web server running on port 80 inside the container to the external world on host port 8000. Set up the appropriate compute resources and network interfaces for the nginx application as shown below.

nginx_app_profile

Configure port mapping needed by nginx web server.

nginx_port_mapping

Once you submit the app profile definition, IOx generates the docker run options associated to the app profile dependencies as shown below.

generated_docker_run_options

Also, you can download the defined app profile dependencies in IOx Package descriptor format (package.yaml). This package.yaml can be used to package IOx application.

Note When you disable Remote Docker access, all of the docker app profiles, containers, images, and volumes are automatically deleted.

Set Up the Local Development Machine Environment

After setting up the environment on your Cisco device, set up the local development machine for the Docker CLI client tool to remotely communicate with Docker engine on the Cisco device. The local Docker client needs to know how to access your gateway (IP address) with valid credentials (the TLS certificates or Username/password).

Pre-requisite

Install Docker client locally on your development machine.

Setup steps - IC3000 platform

Follow below steps to setup local development machine, if your target cisco platform is IC3000. If your target cisco platform is IOS-XE OS based platforms, then skip to next section (Setup steps - IOSXE OS platforms).

local_dev_machine_setup

local_dev_machine_setup

  • From the Cisco IOx Local Manager-> Remote docker workflow tab, download the docker client TLS certificate by clicking the "Download" button next to "Docker client (CLI) TLS certs". The tlscerts.tar file will be downloaded.

  • Extract the TAR archive to docker client config directory, $HOME/.docker/ on macOS or Linux. In Windows, extract the tar archive to %USERPROFILE%/.docker/

tlscerts.tar
  |- ca.pem
  |- cert.pem
  |- key.pem
  • Export remote docker engine configuration via environment variables. Replace with your cisco platform's externally reachable IP address. In case of linux and MacOS, do as below. For Window, update cert path accordingly.
$ export DOCKER_HOST=tcp://<device_ip>:2376 DOCKER_TLS=1 DOCKER_API_VERSION=1.37 export DOCKER_CERT_PATH=$HOME/.docker/

Setup steps - IOSXE OS platform

Note: Make sure HTTPS secure server is enabled on Cisco platform's IOS config before proceeding with this section. If not, use below in IOS configuration command on the Cisco device CLI.

<cisco_device>[conf]# ip http secure-server 

local_dev_machine_setup_polaris

Below steps are to be executed on local development machine.

  • Retrive server certificate from Cisco platform using below command and store it in directory $HOME/.docker/ for macOS or Linux. For Windows, store the cert in dir %USERPROFILE%/.docker/
$ echo | openssl s_client -connect <externally_reacheable_cisco_device_ip>:443 2>/dev/null | openssl x509 -text -out $HOME/.docker/ca.pem
  • Export remote docker engine configuration via environment variables. Replace with your cisco platform's externally reachable IP address. In case of linux and MacOS, do as below.
$ export DOCKER_HOST=tcp://<device_ip>:443 DOCKER_TLS=1 DOCKER_API_VERSION=1.37
  • Setup docker client httpheader requests with basic authorization as below. This is needed for successful authentication with server. Add HttpHeaders section in docker client configuration file at $USER/.docker/config.json. Replace <base64("username:password")> with base64 encoded value of actual device credentials in the format of username:password. For example, if the device username and password is adminuser, adminpwd respectively, then generate basee64 encoded value of string "adminuser:adminpwd" and add the HttpHeader section as "Authorization": "Basic YWRtaW51c2VyOmFkbWlucHdk"
...
"HttpHeaders": {
    "Authorization": "Basic <base64("username:password")>"
}
...

Testing Docker Commands

Once the local development machine is set up correctly, any commands executed with local Docker CLI will be sent to the remote Docker engine on the Cisco device and will retrieve the output of that remote device.

For example, when you execute the following command, it returns your remote Docker engine's details:

$ docker info

Note 1 Environment variables are applicable only to the current terminal. If you create a new terminal, you must set up the environment variables again.

Note 2 To have the Docker CLI talk back to the local Docker engine (reset to local context), close the terminal and open new terminal. Alternatively, you can unset the environment variables in the same terminal to switch back to the local context.

Docker-Native Developer experience

Now that you completed the setup on both the Cisco device and local development machine, you can use pure Docker tools for the entire app development lifecycle.

To complete the nginx example reference, spin up nginx application in a container on Cisco device and access the web server.

Load nginx Image Onto the Cisco Device

Since the nginx Docker image is not present on the Cisco device, you must load the Docker image on to the remote Cisco device. If the Cisco device is connected to the public internet, you can Docker pull from Dockerhub as well.

If the Cisco device is not connected to public internet, save the dockerhub nginx image into tar archive file using docker save command. This produces the nginx.tar archive file.

(docker_cli_local_context)$ docker pull nginx
(docker_cli_local_context)$ docker save nginx -o nginx.tar

Now you can load this tar archive onto the remote Cisco device.

(docker_cli_remote_context)$ docker load -i nginx.tar

Run nginx Container

(docker_cli_remote_context)$ docker run <generated runtime options of app profile> <custom user defined options> <image name>

Run the nginx Docker container using generated docker runtime options from Local Manager.

(docker_cli_remote_context)$ docker run  --network=container:nginx_pr_sleep  --volume=/software/caf/work/repo-docker/docker-data/nginx@pr:/iox_data  --volume=/tmp/cores/nginx@pr:/tmp/cores  --cpu-shares=195  --memory=64m nginx

The nginx application is running on the Cisco device and allows access to the server using external port 8000 and the device management IP address.

nginx_access_demo

Caveats

  • Remote Docker workflow is only meant for a lab or development environment. DO NOT use this feature in production.

  • Clean up of Docker artifacts and reproductionizing the device: The images, containers, and volumes that are deployed via Remote Docker CLI, are not maintained or managed by the IOx app hosting framework. You need to manually cleanup all those artifacts and disable Remote Docker access. Then, you can use the device in production.

  • Since IOx app hosting framework does not manage the containers created by the Remote Docker CLI, only unsigned apps can be installed via this workflow. IOx app signature validation of feature configuration is not applicable to this Remote Docker workflow.

  • Administrator can find the logs in /var/log/Dockerd file on any container or image. Loading operations are done from Remote Docker CLI.

  • App containers deployed via the Remote Docker CLI are not visible and manageable by any other traditional IOx clients, for example, Local Manager, ioxclient, or Field Network Director (FND).

  • For security and maintenance reasons, IOx supports only subset of Docker run command options and Docker CLI commands. Remote Docker client needs to use Docker engine API v1.37.

  • When the Remote Docker workflow for developers is disabled and enabled again, a new set of TLS certificates is generated. This means the new certificates need to be downloaded and installed where the previous ones were installed on the developer machine. This can also be used as a measure to voluntarily revoke the previous certificates.

  • Docker app profiles do not support the Disable MAC learning (mirror mode) IOx feature.

Changes Starting with Release Cisco IOS XE 17.3 (Release Later Than 1.2.1 for IC3000)

  • Remote Wocker workflow will be treated as a mutually exclusive operation with traditional IOx app lifecycle management workflow (via Local Manager, ioxclient, Fog Director, Cisco Kinetic, Cisco DNAC, Cisco FND). When remote docker workflow is enabled, app lifecycle cannot be managed from a traditional client and vice versa.

  • App profiles, Docker containers, volumes, and images will be automatically cleaned up as part of disabling remote docker workflow.

  • List of docker containers, images, and volumes on the device can be seen on the remote docker workflow tab of IOx Local Manager.

Supported Docker Management Commands

$ docker container
$ docker image
$ docker volume
$ docker system

Other Commands:
  attach      Attach local standard input, output, and error streams to a running container
  build       Build an image from a Dockerfile
  commit      Create a new image from a container's changes
  cp          Copy files/folders between a container and the local filesystem
  create      Create a new container
  diff        Inspect changes to files or directories on a container's filesystem
  events      Get real time events from the server
  exec        Run a command in a running container
  export      Export a container's filesystem as a tar archive
  history     Show the history of an image
  images      List images
  import      Import the contents from a tarball to create a filesystem image
  info        Display system-wide information
  inspect     Return low-level information on Docker objects
  kill        Kill one or more running containers
  load        Load an image from a tar archive or STDIN
  login       Log in to a Docker registry
  logout      Log out from a Docker registry
  logs        Fetch the logs of a container
  pause       Pause all processes within one or more containers
  port        List port mappings or a specific mapping for the container
  ps          List containers
  pull        Pull an image or a repository from a registry
  push        Push an image or a repository to a registry
  rename      Rename a container
  restart     Restart one or more containers
  rm          Remove one or more containers
  rmi         Remove one or more images
  run         Run a command in a new container
  save        Save one or more images to a tar archive (streamed to STDOUT by default)
  search      Search the Docker Hub for images
  start       Start one or more stopped containers
  stats       Display a live stream of container(s) resource usage statistics
  stop        Stop one or more running containers
  tag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
  top         Display the running processes of a container
  unpause     Unpause all processes within one or more containers
  update      Update configuration of one or more containers
  version     Show the Docker version information
  wait        Block until one or more containers stop, then print their exit codes

Note Refer to this page under section List of Unsupported Docker Runtime options for all unsupported docker run options.