简介
本文档介绍如何为基于IR1101 ARM的物联网(IoT)网关准备、构建和部署基于Docker的IOx软件包。
先决条件
要求
Cisco 建议您了解以下主题:
使用的组件
本文档中的信息基于以下软件和硬件版本:
本文档中的信息都是基于特定实验室环境中的设备编写的。本文档中使用的所有设备最初均采用原始(默认)配置。如果您使用的是真实网络,请确保您已经了解所有命令的潜在影响。
背景信息
与大多数其他IOx平台相比,IR1101略有不同,因为这些平台主要基于x86。IR1101基于ARM64v8架构,因此您不能直接在平台上部署为x86构建的容器或IOx软件包。本文档从头开始,为构建基于ARM64v8的Docker容器准备环境,并说明如何使用x86 PC在IR1101上构建、包装和部署这些容器。
例如,使用非常小的Python脚本(即简单的Web服务器),并构建Docker容器,最终将其打包以在IR1101上运行。Web服务器仅会侦听预定义端口(9000),并在收到GET请求时返回简单页面。这使您可以测试运行您自己的代码的功能,并可以在开始运行IOx应用后测试对该应用的网络访问。
软件包由Docker工具使用Alpine Linux构建。Alpine Linux是一个小型Linux镜像(约5MB),通常用作Docker容器的基础。
由于大多数台式机/笔记本电脑/虚拟机都基于x86,因此您需要在构建容器的基于x86的计算机上模拟ARM64v8架构。使用快速仿真程序(QEMU)用户仿真可以轻松完成此操作。这允许在非本机体系结构中执行可执行文件,就像在本机体系结构中执行一样。
配置
第1部分。构建IR1101的IOx包
1. 在Linux主机上安装和准备IOx客户端
您需要ioxclient,以便在构建Docker容器时将其打包为IOx包,因此让我们首先准备一下。
首先复制或下载ioxclient软件包。可从https://software.cisco.com/download/release.html?mdfid=286306005&softwareid=286306762获得。
jedepuyd@deb9:~$ scp jedepuyd@192.168.56.101:/home/jedepuyd/ioxclient_1.7.0.0_linux_amd64.tar.gz .
jedepuyd@192.168.56.101's password:
ioxclient_1.7.0.0_linux_amd64.tar.gz 100% 4798KB 75.2MB/s 00:00
解压包:
jedepuyd@deb9:~$ tar -xvzf ioxclient_1.7.0.0_linux_amd64.tar.gz
ioxclient_1.7.0.0_linux_amd64/ioxclient
ioxclient_1.7.0.0_linux_amd64/README.md
向PATH变量添加路径,以使其在不使用完整位置的情况下可用。如果重新启动计算机或切换用户,则不要忘记重复此步骤:
jedepuyd@deb9:~$ export PATH=$PATH:/home/jedepuyd/ioxclient_1.7.0.0_linux_amd64/
首次启动ioxclient以创建强制配置文件。由于您仅使用ioxclient来封装Docker容器,因此这些值可以保留为默认值:
jedepuyd@deb9:~$ ioxclient -v
ioxclient version 1.7.0.0
jedepuyd@deb9:~/iox_aarch64_webserver$ ioxclient profiles reset
Active Profile : default
Your current config details will be lost. Continue (y/N) ? : y
Current config backed up at /tmp/ioxclient731611124
Config data deleted.
jedepuyd@deb9:~/iox_aarch64_webserver$ ioxclient -v
Config file not found : /home/jedepuyd/.ioxclientcfg.yaml
Creating one time configuration..
Your / your organization's name :
Your / your organization's URL :
Your IOx platform's IP address[127.0.0.1] :
Your IOx platform's port number[8443] :
Authorized user name[root] :
Password for root :
Local repository path on IOx platform[/software/downloads]:
URL Scheme (http/https) [https]:
API Prefix[/iox/api/v2/hosting/]:
Your IOx platform's SSH Port[2222]:
Your RSA key, for signing packages, in PEM format[]:
Your x.509 certificate in PEM format[]:
Activating Profile default
Saving current configuration
ioxclient version 1.7.0.0
2. 在Linux生成计算机上安装和准备Docker环境
此Docker用于从Alpine基本映像构建容器并包括使用案例所需的文件。所给步骤基于用于Debian的Docker Community Edition (CE)的官方安装指南:https://docs.docker.com/install/linux/docker-ce/debian/
更新计算机上的包列表:
jedepuyd@deb9:~$ sudo apt-get update
...
Reading package lists... Done
安装依赖项以使用Docker回购:
jedepuyd@deb9:~$ sudo apt-get install apt-transport-https ca-certificates curl gnupg2 software-properties-common
Reading package lists... Done
Building dependency tree
...
Processing triggers for dbus (1.10.26-0+deb9u1) ...
添加Docker GNU Privacy Guard (GPG)密钥作为有效的GPG密钥:
jedepuyd@deb9:~$ curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -
OK
验证已安装的GPG密钥的指纹:
jedepuyd@deb9:~$ sudo apt-key fingerprint 0EBFCD88
pub rsa4096 2017-02-22 [SCEA]
9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
uid [ unknown] Docker Release (CE deb) <docker@docker.com>
sub rsa4096 2017-02-22 [S]
添加Docker稳定回购:
jedepuyd@deb9:~$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable"
在添加Docker回购时再次更新程序包列表:
jedepuyd@deb9:~$ sudo apt-get update
...
Reading package lists... Done
安装Docker:
jedepuyd@deb9:~$ sudo apt-get install docker-ce docker-ce-cli containerd.io
Reading package lists... Done
Building dependency tree
...
Processing triggers for systemd (232-25+deb9u9) ...
为了能够作为常规用户访问/运行Docker,请将此用户添加到Docker组并刷新组成员身份:
jedepuyd@deb9:~$ sudo usermod -a -G docker jedepuyd
jedepuyd@deb9:~$ newgrp docker
3. 安装QEMU用户仿真软件包
在安装Docker之后,您需要安装QEMU用户仿真程序。使用位于Docker容器中的静态链接QEMU仿真程序,以便在基于x86的Linux计算机上运行ARM64v8的容器,尽管目标容器是针对ARM64v8体系结构设计的。
安装软件包:
jedepuyd@deb9:~$ sudo apt-get install qemu-user qemu-user-static
Reading package lists... Done
Building dependency tree
...
Processing triggers for man-db (2.7.6.1-2) ...
安装完成后,以下是在/usr/bin中可用的静态链接QEMU仿真程序:
jedepuyd@deb9:~$ ls -al /usr/bin/qemu-*static
-rwxr-xr-x 1 root root 3468784 Nov 8 16:41 /usr/bin/qemu-aarch64-static
-rwxr-xr-x 1 root root 2791408 Nov 8 16:41 /usr/bin/qemu-alpha-static
-rwxr-xr-x 1 root root 3399344 Nov 8 16:41 /usr/bin/qemu-armeb-static
-rwxr-xr-x 1 root root 3391152 Nov 8 16:41 /usr/bin/qemu-arm-static
-rwxr-xr-x 1 root root 2800400 Nov 8 16:41 /usr/bin/qemu-cris-static
...
列表中的第一个是您需要的:aarch64是适用于Linux的ARM64v8的arch-name。
4. 测试aarch64/ARV64v8容器是否在x86 Linux计算机上运行
现在您已安装了Docker和必要的QEMU二进制文件,您可以测试是否可以在x86计算机上运行为ARM64v8构建的Docker容器:
jedepuyd@deb9:~$ docker run -v /usr/bin/qemu-aarch64-static:/usr/bin/qemu-aarch64-static --rm -ti arm64v8/alpine:3.7
Unable to find image 'arm64v8/alpine:3.7' locally
3.7: Pulling from arm64v8/alpine
40223db5366f: Pull complete
Digest: sha256:a50c0cd3b41129046184591963a7a76822777736258e5ade8445b07c88bfdcc3
Status: Downloaded newer image for arm64v8/alpine:3.7
/ # uname -a
Linux 1dbba69b60c5 4.9.0-8-amd64 #1 SMP Debian 4.9.144-3.1 (2019-02-19) aarch64 Linux
从输出中您可以看到,获取了arm64v8 Alpine容器,并且使其可通过访问仿真器运行。
如果您请求容器的体系结构,您可以看到代码是为aarch64编译的。与IR1101的容器目标拱完全相同。
5. 准备文件以构建Docker Webserver容器
完成所有准备后,您可以为需要在IR1101上运行的Web服务器容器创建必要的文件。
第一个文件是webserver.py,即在容器中运行的Python脚本。由于这只是一个示例,很明显,您需要将其替换为实际代码,以便在IOx应用程序中运行:
jedepuyd@deb9:~$ mkdir iox_aarch64_webserver
jedepuyd@deb9:~$ cd iox_aarch64_webserver
jedepuyd@deb9:~/iox_aarch64_webserver$ vi webserver.py
jedepuyd@deb9:~/iox_aarch64_webserver$ cat webserver.py
#!/usr/bin/env python
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
import SocketServer
import os
class S(BaseHTTPRequestHandler):
def _set_headers(self):
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
def do_GET(self):
self._set_headers()
self.wfile.write("<html><body><h1>IOX python webserver on arm64v8</h1></body></html>")
logf.write('Got GET\n')
logf.flush()
def run(server_class=HTTPServer, handler_class=S, port=9000):
server_address = ('', port)
httpd = server_class(server_address, handler_class)
print 'Starting webserver...'
logf.write('Starting webserver....\n')
logf.flush()
httpd.serve_forever()
if __name__ == "__main__":
log_file_dir = os.getenv("CAF_APP_LOG_DIR", "/tmp")
log_file_path = os.path.join(log_file_dir, "webserver.log")
logf = open(log_file_path, 'w')
run()
logf.close()
此代码包含写入日志文件的逻辑,可从本地管理器中进行咨询。
需要的第二个文件是Dockerfile。这定义了容器的构建方式:
jedepuyd@deb9:~/iox_aarch64_webserver$ vi Dockerfile
jedepuyd@deb9:~/iox_aarch64_webserver$ cat Dockerfile
FROM arm64v8/alpine:3.7
COPY qemu-aarch64-static /usr/bin
RUN apk add --no-cache python
COPY webserver.py /webserver.py
Dockerfile定义了容器的构建方式。从ARM64v8的Apline基础映像开始,复制容器中的仿真程序,运行apk以添加Python软件包,并将Web服务器脚本复制到容器中。
在构建容器之前需要的最后一个准备是将qemu-aarch64-static复制到从中构建容器的目录中:
jedepuyd@deb9:~/iox_aarch64_webserver$ cp /usr/bin/qemu-aarch64-static .
6. 构建Docker容器
完成所有准备后,您可以使用Dockerfile来构建容器:
jedepuyd@deb9:~/iox_aarch64_webserver$ docker build -t iox_aarch64_webserver .
Sending build context to Docker daemon 3.473MB
Step 1/4 : FROM arm64v8/alpine:3.7
---> e013d5426294
Step 2/4 : COPY qemu-aarch64-static /usr/bin
---> addf4e1cc965
Step 3/4 : RUN apk add --no-cache python
---> Running in ff3768926645
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/main/aarch64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/community/aarch64/APKINDEX.tar.gz
(1/10) Installing libbz2 (1.0.6-r6)
(2/10) Installing expat (2.2.5-r0)
(3/10) Installing libffi (3.2.1-r4)
(4/10) Installing gdbm (1.13-r1)
(5/10) Installing ncurses-terminfo-base (6.0_p20171125-r1)
(6/10) Installing ncurses-terminfo (6.0_p20171125-r1)
(7/10) Installing ncurses-libs (6.0_p20171125-r1)
(8/10) Installing readline (7.0.003-r0)
(9/10) Installing sqlite-libs (3.25.3-r0)
(10/10) Installing python2 (2.7.15-r2)
Executing busybox-1.27.2-r11.trigger
OK: 51 MiB in 23 packages
Removing intermediate container ff3768926645
---> eda469dab9c6
Step 4/4 : COPY webserver.py /webserver.py
---> ccf7ee7227c9
Successfully built ccf7ee7227c9
Successfully tagged iox_aarch64_webserver:latest
作为测试,请运行您刚才构建的容器,并检查脚本是否有效:
jedepuyd@deb9:~/iox_aarch64_webserver$ docker run -ti iox_aarch64_webserver
/ # uname -a
Linux dae047f1a6b2 4.9.0-8-amd64 #1 SMP Debian 4.9.144-3.1 (2019-02-19) aarch64 Linux
/ # python webserver.py &
/ # Starting webserver...
/ # netstat -tlpn
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:9000 0.0.0.0:* LISTEN 13/qemu-aarch64-sta
/ # exit
在此输出中您可以看到,容器的体系结构是目标aarch64。启动脚本后,您会看到它在侦听端口9000上的请求。
7. 构建IOx包
该容器已准备好进行包装。在要求ioxclient执行此操作之前,您首先需要创建包描述符:package.yaml。
此文件介绍软件包的外观、需要运行多少资源以及启动什么。
jedepuyd@deb9:~/iox_aarch64_webserver$ vi package.yaml
jedepuyd@deb9:~/iox_aarch64_webserver$ cat package.yaml
descriptor-schema-version: "2.7"
info:
name: "iox_aarch64_webserver"
description: "simple docker webserver for arm64v8"
version: "1.0"
author-link: "http://www.cisco.com"
author-name: "Jens Depuydt"
app:
cpuarch: "aarch64"
type: "docker"
resources:
profile: c1.tiny
network:
-
interface-name: eth0
ports:
tcp: ["9000"]
startup:
rootfs: rootfs.tar
target: ["python","/webserver.py"]
如您所见,CPU架构设置为aarch64。要获得访问TCP端口9000的权限,请使用rootfs.tar作为rootfs,并在启动时运行python/webserver.py。
在打包之前的最后一步是从Docker容器中提取rootfs.tar:
jedepuyd@deb9:~/iox_aarch64_webserver$ docker save -o rootfs.tar iox_aarch64_webserver
此时,您可以使用ioxclient来构建用于IR1101的IOx包:
jedepuyd@deb9:~/iox_aarch64_webserver$ ioxclient package .
Currently active profile : default
Command Name: package
No rsa key and/or certificate files provided to sign the package
Checking if package descriptor file is present..
Validating descriptor file /home/jedepuyd/iox_aarch64_webserver/package.yaml with package schema definitions
Parsing descriptor file..
Found schema version 2.7
Loading schema file for version 2.7
Validating package descriptor file..
File /home/jedepuyd/iox_aarch64_webserver/package.yaml is valid under schema version 2.7
Created Staging directory at : /tmp/017226485
Copying contents to staging directory
Creating an inner envelope for application artifacts
Generated /tmp/017226485/artifacts.tar.gz
Calculating SHA1 checksum for package contents..
Updated package metadata file : /tmp/017226485/.package.metadata
Root Directory : /tmp/017226485
Output file: /tmp/475248592
Path: .package.metadata
SHA1 : 95abe28fc05395fc5f71f7c28f59eceb1495bf9b
Path: artifacts.tar.gz
SHA1 : bdf5596a0747eae51bb0a1d2870fd09a5a16a098
Path: package.yaml
SHA1 : e65a6fcbe96725dd5a09b60036448106acc0c138
Generated package manifest at package.mf
Generating IOx Package..
Package generated at /home/jedepuyd/iox_aarch64_webserver/package.tar
现在,有一个软件包可以部署在IR1101上,并准备为package.tar。下一部分介绍如何为部署准备设备。
第2部分。为IR1101配置IOx
1. 启用Web界面、IOx和本地管理器
本地管理器是一种GUI,用于部署、激活、启动、管理IOx应用并对其进行故障排除。对于IR1101,它嵌入在常规管理Web界面中。因此,您需要先启用该功能。
在IR1101上执行以下步骤以启用IOx和Web界面。
BRU_IR1101_20#conf t
Enter configuration commands, one per line. End with CNTL/Z.
BRU_IR1101_20(config)#iox
BRU_IR1101_20(config)#ip http server
BRU_IR1101_20(config)#ip http secure-server
BRU_IR1101_20(config)#ip http authentication local
BRU_IR1101_20(config)#username admin privilege 15 password 0 cisco
最后一行添加一个具有15个权限的用户。此用户有权访问Web界面和IOx本地管理器。
2. 配置IOx网络
在访问Web界面之前,让我们添加IOx网络所需的配置。有关IOx的背景信息,请参阅IR1101文档:https://www.cisco.com/c/en/us/td/docs/routers/access/1101/software/configuration/guide/b-cisco-ir1101-scg.html
简而言之,IOx应用可使用VirtualPortGroup0接口与外界通信(与IR809上的Gi2和IR829接口上的Gi5相当)。
BRU_IR1101_20(config)#interface VirtualPortGroup0
BRU_IR1101_20(config-if)# ip address 192.168.1.1 255.255.255.0
BRU_IR1101_20(config-if)# ip nat inside
BRU_IR1101_20(config-if)# ip virtual-reassembly
BRU_IR1101_20(config-if)#exit
将VirtualPortGroup0接口配置为内部网络地址转换(NAT)时,需要在Gi 0/0/0接口上添加ip nat outside语句,以允许使用NAT与IOx应用程序进行双向通信:
BRU_IR1101_20(config)#interface gigabitEthernet 0/0/0
BRU_IR1101_20(config-if)#ip nat outside
BRU_IR1101_20(config-if)#ip virtual-reassembly
为了允许访问容器端口9000(可以提供192.168.1.15),您需要添加一个端口转发:
BRU_IR1101_20(config)#$ip nat inside source static tcp 192.168.1.15 9000 interface GigabitEthernet0/0/0 9000
对于本指南,请使用每个IOx应用的静态配置的IP。如果要为应用程序动态分配IP地址,则需要为VirtualPortGroup0子网中的DHCP服务器添加配置。
第3部分。访问本地管理器并部署IOx应用
在将这些行添加到配置后,可以使用Web界面访问IR1101。使用您的浏览器导航至Gi 0/0/0 IP地址,如图所示。
使用步骤1中创建的权限15帐户,以登录Web界面并导航到配置 - IOx(如图所示)。
在IOx本地管理器登录中,使用相同的帐户继续,如图所示。
单击Add New,为IOx应用程序选择名称,然后选择在第1部分中构建的package.tar,如图所示。
上传软件包后,您可以激活它,如图所示。
在Resources选项卡中,打开接口设置以指定要为应用分配的固定IP(如图所示)。
单击OK,然后单击Activate。操作完成后,导航回主Local Manager页面(顶部菜单上的Applications按钮),然后启动应用程序(如图所示)。
完成这些步骤后,您的应用程序将运行,并可通过使用IR1101的Gi 0/0/0接口通过端口9000使用。
验证
使用本部分可确认配置能否正常运行。
要进行验证,您可以使用端口9000访问IR1101上Gi 0/0/0接口的IP地址。
如果一切顺利的话,这将会显示,就像在Python脚本中创建的一样。
故障排除
本部分提供了可用于对配置进行故障排除的信息。
为了排除故障,您可以使用本地管理器检查您在Python脚本中创建的日志文件。
导航到应用,点击iox_web应用上的管理,然后选择日志选项卡,如图所示。