边缘计算-镜像开发(基于arm64)
K8S虽然在1.24后与docker解耦,转向cri-containerd。但docker仍然是制作、拉取、上传镜像的主要工具,由于其优秀的开源和广大的社区仓库dockerhub我们仍有学习的必要。如果有linux的基础2h内即可轻易上手。
写在前面
K8S虽然在1.24后与docker解耦,转向cri-containerd。但docker仍然是制作、拉取、上传镜像的主要工具,由于其优秀的开源和广大的社区仓库dockerhub我们仍有学习的必要。如果有linux的基础2h内即可轻易上手。
2023.12.19日更新
本文对镜像进行构建、云仓库进行上传和下载。
涉及内容WSL、Docker Desktop、阿里云、docker.io、dockerhub
1介绍
边缘计算是一种分布式计算架构,它将数据处理和存储从中心化的数据中心转移到网络边缘,即靠近数据源的地方。这种架构能够显著减少数据传输延迟,提高处理速度,并为用户提供更快的响应。在边缘计算的环境中,容器技术的必要性可以从以下几个方面来论述:
- 资源高效利用:
边缘计算环境通常资源受限,与数据中心相比,边缘节点的计算能力、存储空间和内存都可能较为有限。容器技术以其轻量级的特点,可以在不牺牲性能的情况下,更高效地利用这些有限的资源。容器不需要为每个应用程序都运行一个完整的操作系统,从而节省了宝贵的内存和存储空间。 - 快速部署和扩展:
边缘计算场景中,应用程序需要快速部署到多个边缘节点,并能够根据需求动态扩展。容器技术的便携性和可移植性使得应用程序可以在不同的边缘设备上快速启动和运行,这对于需要即时响应的边缘计算应用来说至关重要。 - 环境一致性和可移植性:
在边缘计算中,确保应用程序在不同边缘节点上运行的一致性是至关重要的。容器提供了一致的运行时环境,这意味着在开发环境中测试过的容器可以在任何支持容器的边缘设备上以相同的方式运行,大大减少了因环境差异导致的问题。 - 隔离性和安全性:
边缘节点可能位于不同的地理位置,面临各种安全威胁。容器技术提供了良好的隔离性,即使在资源受限的环境中也能保证应用程序的安全性。容器化的应用程序运行在自己的环境中,与宿主机和其他容器隔离,这有助于防止恶意软件的传播。 - 易于管理和维护:
容器技术提供了强大的管理工具,如Kubernetes,可以用于自动化容器的部署、扩展和管理。在边缘计算环境中,这些工具可以帮助运维人员高效地管理分布在广泛区域的众多边缘节点。 - 支持微服务架构:
边缘计算通常与微服务架构相结合,以提供灵活、可扩展的服务。容器技术天然适合微服务,因为它可以轻松地将应用程序分解为独立的、可管理的组件,这些组件可以独立部署和更新,而不影响整个系统的运行。 - 网络优化:
边缘计算要求减少数据在网络中的传输,容器技术可以帮助优化网络流量,因为它允许在边缘节点上进行更多的本地数据处理,只有必要的数据才需要发送到中心数据中心。
综上所述,容器技术在边缘计算中扮演着至关重要的角色,它不仅提高了资源利用效率,还增强了应用程序的部署速度、一致性和安全性,为边缘计算提供了强有力的支持。
容器技术 vs 虚拟机
我们知道和一个单纯的应用程序相比,操作系统是一个很重而且很笨的程序,简称笨重,有多笨重呢?
我们知道操作系统运行起来是需要占用很多资源的,大家对此肯定深有体会,刚装好的系统还什么都没有部署,单纯的操作系统其磁盘占用至少几十G起步,内存要几个G起步。
如果有一种技术可以让我们避免把内存浪费在“无用”的操作系统上岂不是太香?这是问题一,主要原因在于操作系统太重了。
还有另一个问题,那就是启动时间问题,我们知道操作系统重启是非常慢的,因为操作系统要从头到尾把该检测的都检测了该加载的都加载上,这个过程非常缓慢,动辄数分钟,因此操作系统还是太笨了。
那么有没有一种技术可以让我们获得虚拟机的好处又能克服这些缺点从而一举实现鱼和熊掌的兼得呢?
答案是肯定的,这就是容器技术。
1.1docker
docker是一个用Go语言实现的开源项目,可以让我们方便的创建和使用容器,docker将程序以及程序所有的依赖都打包到docker container,这样你的程序可以在任何环境都会有一致的表现,这里程序运行的依赖也就是容器就好比集装箱,容器所处的操作系统环境就好比货船或港口,程序的表现只和集装箱有关系(容器),和集装箱放在哪个货船或者哪个港口(操作系统)没有关系。
因此我们可以看到docker可以屏蔽环境差异,也就是说,只要你的程序打包到了docker中,那么无论运行在什么环境下程序的行为都是一致的,程序员再也无法施展表演才华了,不会再有“在我的环境上可以运行”,真正实现“build once, run everywhere”。
此外docker的另一个好处就是快速部署,这是当前互联网公司最常见的一个应用场景,一个原因在于容器启动速度非常快,另一个原因在于只要确保一个容器中的程序正确运行,那么你就能确信无论在生产环境部署多少都能正确运行。
docker中有这样几个概念:
- dockerfile
- image
- container
实际上你可以简单的把image理解为可执行程序,container就是运行起来的进程。
那么写程序需要源代码,那么“写”image就需要dockerfile,dockerfile就是image的源代码,docker就是"编译器"。
因此我们只需要在dockerfile中指定需要哪些程序、依赖什么样的配置,之后把dockerfile交给“编译器”docker进行“编译”,也就是docker build命令,生成的可执行程序就是image,之后就可以运行这个image了,这就是docker run命令,image运行起来后就是docker container。
综上所述,一个镜像从build到实例化变成容器运行会经过:build–>push(到云平台或私有仓库)–>pull(到本地)–>run(实例化为容器)
1.2 docker build
当我们写完dockerfile交给docker“编译”时使用这个命令,那么client在接收到请求后转发给docker daemon,接着docker daemon根据dockerfile创建出“可执行程序”image。
dockerfile的一个示例如下,具体指令参考第二章。
FROM python:3.9.18-bullseye
WORKDIR /home/docker/mnist-infer
ADD . .
RUN pip install -r requirements.txt
RUN pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu
WORKDIR /home/docker/mnist-infer/src
CMD ["python","./main.py"]
解释一下:
第一行是导入基础镜像,dockerhub上有很多官方配置好的镜像,经过时间检验过性能良好,避免了自己配置出现意想不到的bug,但镜像未必是针对你的需求,可能臃肿。
第二行是切换工作路径,即linux的cd命令
第三行是复制文件到镜像路径
第四行和第五行是安装python的依赖包的两种形式
最后CMD指令是指明容器启动的运行程序
1.3 docker run
有了“可执行程序”image后就可以运行程序了,接下来使用命令docker run,docker daemon接收到该命令后找到具体的image,然后加载到内存开始执行,image执行起来就是所谓的container。
其中docker run有很多参数可以指定,如暴露端口、后台运行、挂载卷、自动删除等等。
具体参考百度,Docker run 命令 | 菜鸟教程 (runoob.com)
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
docker run --rm busybox bash
docker run -p 8080:80 nignx
1.4docker pull
其实docker build和docker run是两个最核心的命令,会用这两个命令基本上docker就可以用起来了,剩下的就是一些补充。
那么docker pull是什么意思呢?
我们之前说过,docker中image的概念就类似于“可执行程序”,我们可以从哪里下载到别人写好的应用程序呢?很简单,那就是APP Store,即应用商店。与之类似,既然image也是一种“可执行程序”,那么有没有"Docker Image Store"呢?答案是肯定的,这就是Docker Hub,docker官方的“应用商店”,你可以在这里下载到别人编写好的image,这样你就不用自己编写dockerfile了。
docker registry 可以用来存放各种image,公共的可以供任何人下载image的仓库就是docker Hub。那么该怎么从Docker Hub中下载image呢,就是这里的docker pull命令了。
1.5其余指令
具体使用参考百度(很简单)
docker rm 删除镜像或容器
docker stop 停止容器
docker image ls 列出本地镜像
docker container ls列出本地运行中容器
docker ps -a 列出所有容器
docker cp 本地文件 容器名:目标文件地址
2构建镜像
2.1dockerfile
详细介绍参考Docker Dockerfile | 菜鸟教程 (runoob.com)
这里只简单介绍解释dockerfile指令功能和易出bug的地方
常见的指令
FROM
两种形式如下:
FROM <IMAGE>
FROM <IMAGE>:<TAG>
通过FROM指定的镜像名称必须是一个已经存在的镜像,这个镜像称之为基础镜像,必须位于第一条非注释指令
MAINTAINER
MAINTAINER <NAME>
指定镜像的作者信息,包含镜像的所有者和联系人信息
RUN
用于指定构建镜像时运行的命令,两种模式:
RUN <command> (shell模式)
RUN [ "executable", "param1", "param2" ] (exec模式)
在shell模式下,是使用/bin/sh -c COMMAND来运行命令的
在exec模式下可以指定其他的shell来运行命令RUN [“/bin/bash”, “-c”, “echo hello”]
多条RUN指令可以合并为一条:
RUN yum install httpd && yum install ftp
这样在构建的时候会减少产生中间层镜像
CMD
用于提供容器运行的默认命令,如果在docker run
时指定了运行的命令,则CMD命令不会执行。CMD有三种模式:
CMD <command> (shell模式)
CMD [ "executable", "param1", "param2" ] (exec模式)
CMD [ 'param1', 'param2'] (通常与ENTRYPOINT搭配指定ENTRYPOINT的默认参数)
ENTRYPOINT
与CMD类似,ENTRYPOINT不会被docker run
中指定的命令覆盖,如果想覆盖ENTRYPOINT,则需要在docker run
中指定--entrypoint
选项
它有两种模式:
ENTRYPOINT <command> (shell模式)
ENTRYPOINT [ "executable", "param1", "param2" ] (exec模式)
ADD和COPY
作用都是将文件或目录复制到Dockerfile构建的镜像中
ADD <src> <dest>
ADD ["<src>" "<dest>"] (适用于文件路径包含空格的情况)
COPY <src> <dest>
ADD ["<src>" "<dest>"] (适用于文件路径包含空格的情况)
ADD包含了类似tar的解压功能,如果只是单纯复制文件,建议使用COPY,而且,两者的源文件路径使用Dockerfile相对路径,目标路径使用绝对路径。
COPY index.html /var/www/html
WORKDIR
在容器内部设置工作目录,这样ENTRYPOINT和CMD指定的命令都会在容器中这个目录下进行。
WORKDIR /path/to/workdir
ENV
用于设置环境变量
ENV <KEY> <VALUE>
ENV <KEY>=<VALUE>
2.2docker build指令
结合具体案例介绍,如下是一个预构建镜像的文件夹mnist-infer,目前已上传github,可练习使用。https://github.com/kongfuguagua/docker_build
├─mnist-infer
│ │ Dockerfile
│ │ requirements.txt
│ │
│ └─src
│ client.py
│ inference.py
│ main.py
│ model.pkl
│ server.py
mnist-infer为文件名。
Dockerfile为构建镜像的文件。
src中包括镜像内部需要运行的程序。
由于是基于python的,故需要安装一些package,requirements.txt为安装包内容和版本。
构建好mnist-infer文件夹后可构建镜像
首先切换到mnist-infer路径
键入
docker build --platform linux/arm64/v8 -t mnist-infer .
最后的 . 绝对不能省去,其意义为dockerfile文件的路径
–platform是根据你所使用的电脑平台确定.
为什么需要指定–platform。因为不同硬件的thumb指令集不同,像树莓派linux/amd64/v8不能兼容PC机的指令集,无法运行基于PC端构建的镜像。
现在你获得了一个镜像!!!下一章将介绍如何上传到云平台
3阿里云平台
阿里云容器镜像服务(简称 ACR)是面向容器镜像、Helm Chart 等符合 OCI 标准的云原生制品安全托管及高效分发平台。 ACR 支持全球同步加速、大规模/大镜像分发加速、多代码源构建加速等全链路提效,与容器服务 ACK 无缝集成,帮助企业降低交付复杂度,打造云原生应用一站式解决方案。
3.1阿里云开通镜像服务(个人免费)
网上很多教程,可参考如下
Docker(四):使用阿里云容器镜像服务_打开容器镜像服务-CSDN博客
镜像管理网站:容器镜像服务 (aliyun.com)
3.2push和pull镜像
镜像仓库中有参考指令
push
下面这个–username和【】中的内容需要换成你需要的
docker login --username=xxxxxxxx registry.cn-hangzhou.aliyuncs.com
docker tag [ImageId] [仓库地址]:[镜像版本号]
docker push [仓库地址]:[镜像版本号]
pull
下面这个–username和【】中的内容需要换成你需要的
docker pull [仓库地址]:[镜像版本号]
现在恭喜你已经学会如何使用docker了
4从创建镜像到使用容器的示例
4.1创建镜像
本章我将以mnist-infer为例从0开始创建镜像。
按照该文件树格式建立mnist-infer文件夹
├─mnist-infer
│ │ Dockerfile
│ │ requirements.txt
│ │
│ └─src
│ client.py
│ inference.py
│ main.py
│ model.pkl
│ server.py
编写Dockerfile文件
FROM python:3.9.18-bullseye
WORKDIR /home/docker/mnist-infer
ADD . .
RUN pip install -r requirements.txt
RUN pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu
WORKDIR /home/docker/mnist-infer/src
CMD ["python","./main.py"]
编写requirements.txt文件
certifi==2022.12.7
charset-normalizer==2.1.1
filelock==3.9.0
idna==3.4
Jinja2==3.1.2
MarkupSafe==2.1.2
mpmath==1.3.0
networkx==3.0
numpy==1.24.1
Pillow==9.3.0
requests==2.28.1
sympy==1.12
typing_extensions==4.4.0
urllib3==1.26.13
在命令行里启动docker
kongfuguagua@LAPTOP-HJ62ITJR:~$ cd docker/mnist-infer/
kongfuguagua@LAPTOP-HJ62ITJR:~/docker/mnist-infer$ docker build --platform linux/arm64/v8 -t mnist-infer .
kongfuguagua@LAPTOP-HJ62ITJR:~/docker/mnist-infer$ docker tag 6d16b891922b registry.cn-hangzhou.aliyuncs.com/mnist-infer/mnist-infer-infer:v3.0.0
kongfuguagua@LAPTOP-HJ62ITJR:~/docker/mnist-infer$ docker push registry.cn-hangzhou.aliyuncs.com/mnist-infer/mnist-infer-infer:v3.0.0
已上传至云服务器
4.2使用镜像
下面示例拉取镜像和实例化容器,本镜像是构建好的前向神经网络mnist训练镜像,可复制指令操作
docker pull registry.cn-hangzhou.aliyuncs.com/mnist-infer/mnist-infer-overall:v1.1.0
pull完成后查看镜像
docker image ls
实例化镜像,并进入镜像
docker run --rm -it registry.cn-hangzhou.aliyuncs.com/mnist-infer/mnist-infer-overall:v1.1.0
等待一会,命令行出现
Accuracy of the network on the 10000 test images: 95 %
容器实例化成功
更多推荐
所有评论(0)