• [知识分享] 解构HE2E中的Kubernetes技术应用
    本文分享自华为云社区《[解构HE2E中的Kubernetes技术应用](https://bbs.huaweicloud.com/blogs/352564?utm_source=csdn&utm_medium=bbs-ex&utm_campaign=paas&utm_content=content)》,作者: 敏捷小智 。 在《[解构HE2E中的容器技术应用](https://bbs.huaweicloud.com/blogs/345979)》 一文当中,为大家分析了HE2E项目的代码仓库、编译构建、部署等各环节中对于容器技术的应用。今天,我们将从Kubernetes技术应用的角度解构[华为云 DevCloud HE2E DevOps实践](https://support.huaweicloud.com/bestpractice-devcloud/devcloud_practice_2000.html) 。 # 什么是Kubernetes? Kubernetes (也称K8S)是用于自动部署,扩展和管理容器化应用程序的开源系统。 # K8S与CCE 在上一篇文章中,大家已经了解了HE2E项目中通过Docker实现容器化部署,在该实践中通过此方式部署至ECS弹性云服务器中,并称之为ECS部署。在该实践中,提供了另外一套部署方式,将应用部署至CCE集群当中,即CCE部署,使用的工具即K8S。 总之,根据部署目标的不同,HE2E实践中分别介绍了ECS部署与CCE部署。根据部署采用的技术工具不同,也可以将这两种方式称为Docker部署与K8S部署。 # 为什么选择K8S 在正式的生产环境中,企业和团队往往会需要将应用部署至多个服务器主机,而CCE集群和K8S则共同为应用的部署、运行及管理提供了保障。相较而言,HE2E实践中介绍的ECS部署方式更倾向于开发、测试等环境下的单机部署。 # K8S的代码配置 回到项目本身,代码仓库中的./kompose/文件夹下有多个yaml文件。可以看出,每个服务都有两个配置文件(*-deployment.yaml与*-service.yaml)共同进行配置。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20225/20/1653013720068215690.png) 此处以db-deployment.yaml为例,对yaml配置仅作简短的介绍,帮助大家理解配置内容。随着集群版本和产品能力的更迭,也有很多配置信息将发生变化。所以在实践当中,需要调整 yaml 文件配置 。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20225/20/1653013729254244601.png) • apiVersion:此处值为apps/v1,这个版本号需要根据安装的K8S版本和资源类型进行变化。目前实践中对应v1.19版本的K8S集群。 • kind:此处创建的是Deployment,根据实际情况,此处资源类型可以是Pod、Job、Ingress、Service等。如:在*-service.yaml文件中,创建的资源类型则是Service。 • metadata:包含Deployment的一些meta信息。其中,annotations的含义是注解。 • spec:你所期望的该对象的状态。包括replicas、selector、containers等Kubernetes需要的参数。其中,containers定义了该deployment使用的镜像:docker-server/docker-org/postgres:9.4。在上篇文章中提到过,这里的docker-server、docker-org都会在构建任务中替换为实际镜像对应的镜像地址和组织。strategy、restartPolicy等字段共同构成了容器失败时重启的策略。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20225/20/1653013738056986003.png) 在*-service.yaml当中,主体内容与*-deployment.yaml相差也不算大,主要差异集中于spec这部分。*-service.yaml对应的spec主要是定义了集群内访问的方式,使各个服务之间可以互相访问。 可以看出,*-deployment.yaml 与*-service.yaml共同定义了一个服务*。*-deployment.yaml主要定义了该服务的镜像源,或者说工作负载是什么。而*-service.yaml则定义了该服务访问方式。 # K8S的部署配置 在编译构建环节,主体还是制作镜像上传到SWR镜像仓库,与上篇文章的没有区别。相关的配置文件也通过构建任务上传到软件发布库了,所以这里就不赘述了。 镜像、配置和集群资源都准备妥当以后,就是使用K8S部署的环节了。 # - 代理机配置 我们在HE2E实践中采用的是代理机的部署方式,将集群中的一个节点作为代理机进行授信、部署。所以在实践中我们从集群下载Kubectl配置文件并配置到节点主机当中(见《配置 Kubectl 》)。通过配置Kubectl的操作,我们就可以在节点主机上执行命令进而影响整个CCE集群。 # - CCE部署任务 HE2E实践中,phoenix-cd-cce是我们所需执行的部署任务。该任务将配置文件传输到目标主机,即代理机、集群节点。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20225/20/1653013776192877195.png) 而后,通过执行shell命令启动Kubenetes。 kubectl delete secret regcred kubectl create secret docker-registry regcred --docker-server=${docker-server} --docker-username=${docker-username} --docker-password=${docker-password} --docker-email=***@***.cn kubectl delete -f /root/phoenix-sample-deploy/kompose/ kubectl apply -f /root/phoenix-sample-deploy/kompose/ • 这里先是删除原有的secret,这一步主要是为了防止由于使用临时登录命令变化而导致secret错误引发的任务执行失败。 • 接着,创建新的secret。包含docker-server、docker-username、docker-password等信息。 • 按配置文件(/root/phoenix-sample-deploy/kompose/)删除资源。 • 按配置文件(/root/phoenix-sample-deploy/kompose/)对资源进行配置。 成功执行该部署任务后,可以在CCE集群中看到五个工作负载已经处于“运行中”的状态。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20225/20/1653013791361975806.png) 不过目前还需要设置“节点访问”才能正常访问。所以在后续实践中对工作负载vote和result手动添加访问方式。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20225/20/1653013798245600410.png) 节点访问设置完毕后,即可访问项目的用户端与管理端了。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20225/20/1653013805736917160.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20225/20/1653013823631945942.png) # K8S的模板部署方式 理论上,讲到现在,HE2E实践中的K8S部署就已经讲完了。但是,笔者猜到,肯定有很多人不喜欢这种通过代理机部署集群的方式。不过没关系,下面我就来介绍DevCloud当中的Kubernetes模板部署。 新建模板时,现在可以选择模板:Kubernetes部署。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20225/20/1653013841694495933.png) 进入模板以后,可以选择集群类型、区域、命名空间、部署方式等信息。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20225/20/1653013852227197420.png) 由于本项目通过10个yaml文件共同配置,所以需要添加相同的“Kubernetes部署”步骤共计10个,每个步骤都对应一个yaml文件。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20225/20/1653013861289828309.png) 而由于我们在代码仓库中的配置并非我们最终部署时所需的配置(经过编译构建修改docker-server等参数),所以我们需要每个步骤都设置软件发布库中对应的yaml文件。此时,我们会发现,我们原本的构建任务是将所有yaml文件进行了打包压缩后才上传的,没有办法直接选中。所以,我们可以再次创建一个构建任务或者在原有构建任务上进行修改,以使软件发布库中存放有所有的yaml文件。 构建任务上传步骤的配置参考:(上传所有yaml文件而非打包后上传) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20225/20/1653013872326397506.png) 完成以上配置以后,执行Kubernetes部署模板任务,即可将服务部署至选定的CCE集群当中。此时再添加节点访问方式即可访问用户端与管理端。 当然,我们也可以将节点访问也写入yaml文件中,实现进一步的一键部署。这里就暂且留作一个小思考题,感兴趣的小伙伴可以自己尝试一下,将节点访问写入yaml当中。 # 结语 本篇文章一面介绍了HE2E实践中的CCE部署方式,一面又介绍了该实践中未提到的Kubernetes模板部署。两者的主要区别是“CCE部署”是通过代理机控制集群进行K8S部署;Kubernetes模板部署则是直接在集群中部署。此外,本文也对项目中关于K8S的配置进行了一定程度的解析。
  • [容器专区] 【Hi-Grid T1】【Lxc 容器包】制作的Lxc 容器包安装失败
    【操作步骤&问题现象】按照https://bbs.huaweicloud.com/forum/thread-130529-1-1.html 下载eciot-ova_v1.2.rar包,搭建好编译环境,进入最终编译镜像,执行./build_ova.sh armel 2.0.1 huawei download unprivileged,Lxc 容器包能制作成功将制作好的lxc 容器包上传到host,执行container install 安装容器失败
  • [认证交流] 华为云云原生入门级开发者认证学习笔记——第二章
    第二章:云原生基础设置之容器技术学习笔记容器发展背景企业IT业务云化路径传统业务云化:物理机部署云管平台统一管理 VS P2V/V2V虚拟化部署;业务云化创新:容器部署 VS 云原生容器:一种轻量级、可移植、自包含的软件打包技术,使应用程序可以在几乎任何地方以相同的方式运行。容器和虚拟机的区别:虚拟化层的位置和操作系统的使用方式。虚拟机通过hypervisor层提供硬件虚拟化的能力,允许多个操作系统和应用共享硬件,虚拟机上安装完成的OS,有完整的OS内核;所有容器共享一个hostOS。Docker:最常使用的容器引擎,2013年由dotCloud公司开源,GO语言编写,当前有Docker CE和Docker EE两个版本  容器关键技术介绍Open Container Initiative(OCI),制定开发的容器规范:runtime spec定义可移植性image format spec定义互操作性容器runtime:runtime与操作系统kernel紧密协作,为容器提供运行环境。不同公司有不同的runtime工具,但都符合OCI规范,如runC、rkt、Kata、gVisor等Docker Engine(Client/Server结构)Server又叫Daemon进程,长期运行的程序,创建和管理Docker对象( 镜像,容器,网络,卷)Rest API:Client与Daemon进程的通信接口Client(Docker CLI)使用REST API通过脚本或直接的CLI命令与Docker daemon交互  Container容器是从镜像创建的运行实例,它可以被启动、开始、停止、 删除。每个容器都是相互隔离的、保证安全的平台Docker容器通过namespace技术实现进程隔离,通过cgroup技术实现容器进程可用资源的限制。Namespace:命名空间,用于资源隔离,不同类型的namespace隔离不同的资源Cgroups:限制一个进程组对系统资源的使用上限,包括CPU、内存、Block I/O等,Cgroups还可以设置进程优先级,对进程进行挂起和恢复等操作。容器镜像Image是容器的模板,容器是镜像的运行实例,runtime根据容器镜像创建容器。容器镜像打包了整个操作系统的文件和目录(rootfs),也包括应用本身。所有容器共享宿主机Kernel,并且不能修改宿主机KernelUnionFS:Docker镜像分层结构的实现,借助于UnionFS联合文件系统的能力,UnionFS主要的功能是将多个不同位置的目录联合挂载(union mount)到同一个目录下。容器copy–on-write特性,对容器的增删改查操作容器数据卷:卷就是目录或文件,存在于一个或多个容器中,由docker挂载到容器,但不属于联合文件系统;卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷。挂在数据卷的方法:启动容器的时使用-v命令进行数据卷的挂载。在Dockerfile中使用VOLUME指令来给镜像添加一个或多个数据卷。Registry是注册服务器,docker hub就是一个超大的公共registry;Repository是仓库,docker repository一般存放的是一类镜像,这一类镜像只不过是 tag 版本不同。如下图: 如何使用Dockerfile构建镜像Dockerfile是一个文本文件,其内包含了一条条的指令,每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建容器镜像。Docker提供了两种构建镜像的方法:docker commit命令与dockerfile构建文件。Build命令生成docker image;run命令运行docker containerDockerfile文件中的指令执行后,会创建一个个新的镜像层。Dockerfile文件中的注释以”#”开始。Dockerfile一般由4部分组成:基础镜像信息、维护者信息、镜像操作指令、容器启动指令build context:为镜像构建提供所需的文件或目录。Dockerfile在执行过程中,会启动临时容器,然后在临时容器中执行一条指令对容器内容进行修改,再将该容器保存为镜像生成一个新的镜像层,最后删除这个临时容器。若dockerfile中有多条指令,则会重复这个过程,直到执行结束。常见镜像管理命令docker push:上传镜像到registry。docker pull:从registry下载镜像。docker rmi:删除本地镜像。docker images:显示本地镜像。docker search:搜索docker hub上的镜像。docker tag:为镜像标记tag。docker history:显示镜像构建过程。docker commit:将容器保存为镜像。docker build:从dockerfile创建镜像。 容器生命周期管理systemctl status docker.service:查看Docker engine状态docker run -d -p 8080:80 httpd:运行一个容器 (“-d”参数可在后台运行容器;“-p”参数将宿主机8080端口映射到容器80端口)docker ps:查看容器运行状态docker stop:停止一个容器docker start:启动一个容器docker pause:暂停一个容器docker unpause:恢复启动一个容器docker rm:删除一个容器docker attach:进入一个容器docker exec:进入同一个容器docker inspect:获取容器/镜像元数据docker top:查看容器中运行的进程信息docker events:从服务器获取实时事件docker port:列出指定的容器的端口映射docker cp:与主机之间进行数据拷贝docker容器的状态有7种:created(已创建)restarting(重启中)running(运行中)removing(迁移中)paused(暂停)exited(停止)dead(死亡)
  • [技术干货] Prometheus容器化部署的实践方案
    这篇文章主要介绍了Prometheus容器化部署,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下环境主机名IP地址服务prometheus192.168.237.137prometheus、grafananode-exporter192.168.237.131node_exporter容器化部署prometheus1、安装docker1234567891011121314151617181920212223242526272829[root@prometheus ~]# docker versionClient: Docker Engine - Community Version:           20.10.11 API version:       1.41 Go version:        go1.16.9 Git commit:        dea9396 Built:             Thu Nov 18 00:36:58 2021 OS/Arch:           linux/amd64 Context:           default Experimental:      true Server: Docker Engine - Community Engine:  Version:          20.10.11  API version:      1.41 (minimum version 1.12)  Go version:       go1.16.9  Git commit:       847da18  Built:            Thu Nov 18 00:35:20 2021  OS/Arch:          linux/amd64  Experimental:     false containerd:  Version:          1.4.12  GitCommit:        7b11cfaabd73bb80907dd23182b9347b4245eb5d runc:  Version:          1.0.2  GitCommit:        v1.0.2-0-g52b36a2 docker-init:  Version:          0.19.0  GitCommit:        de40ad02、运行prometheus容器12345678910111213141516171819202122232425262728293031323334353637383940//拉取镜像[root@prometheus ~]# docker pull prom/prometheusUsing default tag: latestlatest: Pulling from prom/prometheus3cb635b06aa2: Pull complete 34f699df6fe0: Pull complete 33d6c9635e0f: Pull complete f2af7323bed8: Pull complete c16675a6a294: Pull complete 827843f6afe6: Pull complete 3d272942eeaf: Pull complete 7e785cfa34da: Pull complete 05e324559e3b: Pull complete 170620261a59: Pull complete ec35f5996032: Pull complete 5509173eb708: Pull complete Digest: sha256:cb9817249c346d6cfadebe383ed3b3cd4c540f623db40c4ca00da2ada45259bbStatus: Downloaded newer image for prom/prometheus:latestdocker.io/prom/prometheus:latest //在/opt目录下提供prometheus的默认配置文件[root@prometheus ~]# ls /opt/prometheus.yml //运行容器##--restart always 总是重启,开机自启## 将本地提供的配置文件映射到容器,ro 容器内只读[root@prometheus ~]# docker run --name prometheus -d --restart always -p 9090:9090 -v /opt/prometheus.yml:/etc/prometheus/prometheus.yml:ro prom/prometheus:latest a0ba5535f0ea3b0f44574fd237802f2ef19f4624c3752c3bf8122a4d79a26428[root@prometheus ~]# docker psCONTAINER ID   IMAGE                             COMMAND                  CREATED          STATUS                    PORTS                                       NAMESa0ba5535f0ea   prom/prometheus:latest            "/bin/prometheus --c…"   11 seconds ago   Up 11 seconds             0.0.0.0:9090->9090/tcp, :::9090->9090/tcp   prometheus //查看端口[root@prometheus ~]# ss -anltuNetid     State      Recv-Q      Send-Q           Local Address:Port           Peer Address:Port     Process     tcp       LISTEN     0           128                    0.0.0.0:22                  0.0.0.0:*                    tcp       LISTEN     0           128                    0.0.0.0:9090                0.0.0.0:*                    tcp       LISTEN     0           128                       [::]:22                     [::]:*                    tcp       LISTEN     0           128                       [::]:9090                   [::]:*                    使用ip+9090/targets访问prometheus默认网页部署node_exporter1234567891011121314151617181920212223242526272829303132333435363738394041424344//下载安装包[root@node-exporter ~]# wget https://github.com/prometheus/node_exporter/releases/download/v1.3.0/node_exporter-1.3.0.linux-amd64.tar.gz[root@node-exporter ~]# lsanaconda-ks.cfg  node_exporter-1.3.0.linux-amd64.tar.gz //解压[root@node-exporter ~]# tar xf node_exporter-1.3.0.linux-amd64.tar.gz -C /usr/local/[root@node-exporter ~]# mv /usr/local/node_exporter-1.3.0.linux-amd64/ /usr/local/node_exporter[root@node-exporter ~]# ls /usr/local/bin  etc  games  include  lib  lib64  libexec  node_exporter  sbin  share  src //编写service文件,启动并开机自启[root@node-exporter ~]# cat /usr/lib/systemd/system/node_exporter.service[unit]Description=The node_exporter ServerAfter=network.target [Service]ExecStart=/usr/local/node_exporter/node_exporterRestart=on-failureRestartSec=15sSyslogIdentifier=node_exporter [Install]WantedBy=multi-user.target[root@node-exporter ~]# systemctl daemon-reload [root@node-exporter ~]# systemctl enable --now node_exporter.service Created symlink from /etc/systemd/system/multi-user.target.wants/node_exporter.service to /usr/lib/systemd/system/node_exporter.service.[root@node-exporter ~]# systemctl status node_exporter.service ● node_exporter.service   Loaded: loaded (/usr/lib/systemd/system/node_exporter.service; enabled; vendor preset: disabled)   Active: active (running) since 四 2021-12-30 19:26:59 CST; 8s ago Main PID: 27878 (node_exporter)   CGroup: /system.slice/node_exporter.service           └─27878 /usr/local/node_exporter/node_exporter //查看端口[root@node-exporter ~]# ss -anltuNetid State      Recv-Q Send-Q         Local Address:Port                        Peer Address:Port              tcp   LISTEN     0      128                        *:22                                     *:*                  tcp   LISTEN     0      128                     [::]:22                                  [::]:*                  tcp   LISTEN     0      128                     [::]:9100                                [::]:*                   ## node-exporter部署成功就可以在Prometheus主机上添加节点进行监控添加节点到prometheus中修改本地prometheus.yml文件12345678910111213141516171819202122232425//修改配置文件[root@prometheus ~]# tail -8 /opt/prometheus.yml scrape_configs:  # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.  - job_name: "prometheus"    static_configs:      - targets: ["localhost:9090"]  - job_name: "centos"          //指定一个工作名称    static_configs:      - targets: ["192.168.237.131:9100"]               //指定node-exporter节点的IP和端口号## 如果有多个节点  - job_name: "centos"     static_configs:      - targets:         - "192.168.237.131:9100"        - "192.168.237.132:9100"        - "192.168.237.133:9100"  //重启容器,重新读取配置文件[root@prometheus ~]# docker restart prometheusprometheus[root@prometheus ~]# docker psCONTAINER ID   IMAGE                             COMMAND                  CREATED          STATUS                    PORTS                                       NAMESa0ba5535f0ea   prom/prometheus:latest            "/bin/prometheus --c…"   26 minutes ago   Up 3 seconds              0.0.0.0:9090->9090/tcp, :::9090->9090/tcp   prometheus访问prometheus默认网页成功添加节点部署grafana画图工具1234567891011121314151617181920212223242526272829303132333435363738394041//拉取grafan/grafan官方镜像[root@prometheus ~]# docker pull grafana/grafanaUsing default tag: latestlatest: Pulling from grafana/grafana97518928ae5f: Pull complete 5b58818b7f48: Pull complete d9a64d9fd162: Pull complete 4e368e1b924c: Pull complete 867f7fdd92d9: Pull complete 387c55415012: Pull complete 07f94c8f51cd: Pull complete ce8cf00ff6aa: Pull complete e44858b5f948: Pull complete 4000fdbdd2a3: Pull complete Digest: sha256:18d94ae734accd66bccf22daed7bdb20c6b99aa0f2c687eea3ce4275fe275062Status: Downloaded newer image for grafana/grafana:latestdocker.io/grafana/grafana:latest [root@prometheus ~]# docker imagesREPOSITORY                      TAG       IMAGE ID       CREATED        SIZEprom/prometheus                 latest    a3d385fc29f9   12 days ago    201MBgrafana/grafana                 latest    9b957e098315   2 weeks ago    275MB //使用官方grafana镜像运行容器[root@prometheus ~]# docker run -d --name grafana -p 3000:3000 --restart always grafana/grafana0b5986fc63442538a6fae845e5d1b8afc78caec4f4bdd81ca3623eb1329ad562 [root@prometheus ~]# docker psCONTAINER ID   IMAGE                             COMMAND                  CREATED          STATUS                    PORTS                                       NAMES0b5986fc6344   grafana/grafana                   "/run.sh"                4 seconds ago    Up 2 seconds              0.0.0.0:3000->3000/tcp, :::3000->3000/tcp   grafanaa0ba5535f0ea   prom/prometheus:latest            "/bin/prometheus --c…"   33 minutes ago   Up 6 minutes              0.0.0.0:9090->9090/tcp, :::9090->9090/tcp   prometheus //查看端口[root@prometheus ~]# ss -anltuNetid     State      Recv-Q      Send-Q           Local Address:Port           Peer Address:Port     Process             tcp       LISTEN     0           128                    0.0.0.0:22                  0.0.0.0:*                    tcp       LISTEN     0           128                    0.0.0.0:3000                0.0.0.0:*                    tcp       LISTEN     0           128                    0.0.0.0:9090                0.0.0.0:*                             tcp       LISTEN     0           128                       [::]:22                     [::]:*                    tcp       LISTEN     0           128                       [::]:3000                   [::]:*                    tcp       LISTEN     0           128                       [::]:9090                   [::]:*                    使用prometheus主机IP地址192.168.129.205 + 端口号3000在浏览器中访问默认账号:admin 密码:admin修改密码首页添加数据源数据源选择prometheus导入仪表盘模板地址模板ID为9276效果图到此这篇关于Prometheus容器化部署的文章就介绍到这了,转载自https://www.jb51.net/article/233429.htm
  • [知识分享] 解构华为云HE2E项目中的容器技术应用
    本文分享自华为云社区《解构华为云HE2E项目中的容器技术应用》,作者: 敏捷小智。 [华为云DevCloud HE2E DevOps实践](https://support.huaweicloud.com/bestpractice-devcloud/devcloud_practice_2000.html)当中,项目采用Docker技术进行构建部署。 容器技术应用,其实说简单也很简单,其流程无外乎:制作镜像——上传镜像——拉取镜像——启动镜像。 今天,我们就带大家**从容器技术应用的角度来解构HE2E项目**。 HE2E技术架构图: ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/15/1649992365690666986.png) # 创建项目 在华为云DevCloud中创建项目时选择DevOps样例项目,即可创建出预置了代码仓库、编译构建、部署等任务的DevOps样例项目,此项目即HE2E项目。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/15/1649992378881932915.png) # 代码仓库 HE2E项目中预置了代码仓库phoenix-sample。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/15/1649992390990581615.png) 在根目录下可以看到images、kompose、result、vote、worker五个文件夹,以及LICENSE、README.md和docker-compose-standalone、docker-compose两个yml文件。Images文件夹存了几张图片,LICENSE和README也与代码内容无关,docker-compose.yml文件是应用于本地开发时的测试文件,这些都无需理会。 # 配置Kubectl的kompose文件夹 我们先看一下kompose文件夹,此文件夹下有多个yaml文件,通过命名可以看出这些文件是针对于每个微服务应用的配置。当我们进行CCE部署时就读取这里的配置(在部署时进行配置)。本着由浅入深的精神,本文先对ECS部署时所需的配置进行讲解,大家不要心急噢。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/15/1649992407472733292.png) # 功能模块与制作镜像的Dockerfile result、vote、worker三个文件夹分别对应HE2E当中的三个功能模块:结果、投票、处理。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/15/1649992423270273381.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/15/1649992434412423310.png) 可以看到,三个文件夹下各自都有Dockerfile文件。制作镜像的时候就是靠这些Dockerfile文件来进行制作的。 我们以result下的Dockerfile进行举例说明: ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/15/1649992465473662973.png) FROM:定制的镜像都是基于 FROM 的镜像,这里的node:5.11.0-slim就是定制需要的基础镜像。后续的操作都是基于 node:5.11.0-slim。 WORKDIR /app:指定并创建工作目录/app。 RUN 命令>:执行命令>。 ADD 文件> 目录>:复制文件>至目录>。 5-9行:执行npm安装操作,并将相关文件存放入相应目录。 ENV PORT 80:定义环境变量PORT=80 EXPOSE 80:声明端口80。 CMD 命令>:在docker run时运行命令>。 在编译构建任务phoenix-sample-ci中,“制作Result镜像并推送到SWR仓库”步骤,通过“工作目录”、“Dockerfile路径”两个选项确定制作镜像时读取的Dockerfile:工作目录>/,即./result/Dockerfile。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/15/1649992476232626864.png) 其余的vote和worker两个功能模块也是按此种办法制作镜像。值得一提的是,worker文件夹下有Dockerfile、Dockerfile.j和Dockerfile.j2三个文件,但是在构建任务中,我们只需选择一个文件进行镜像制作,选择的是Dockerfile.j2这个文件。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/15/1649992491928827644.png) 在Dockerfile.j2文件中,将target下的内容复制到code/target下,但是target文件夹又并不在代码当中。这是因为worker下的项目是Java项目,target文件夹是在Maven构建的过程产生的,所以在构建任务phoenix-sample-ci中,制作Worker镜像之前需要先通过Maven进行构建。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/15/1649992499038223440.png) 通过以上的Dockerfile文件已经可以制作出三大功能模块对应的容器镜像了。在部署主机中,直接使用docker login、docker pull和docker run命令就可以登录、拉取并启动相应的镜像。但是这种方式要求对每个镜像都进行拉取和启动,不能一次性配置全部镜像。故此,我们引入了docker compose,通过docker compose实现对 Docker 容器集群的快速编排。一键(一个配置文件)配置本项目所需的各个功能模块。 # 配置docker-compose的docker-compose-standalone.yml文件 当我们部署本项目到服务器时,采取docker-compose的方式启动。 在部署任务phoenix-sample-standalone中,最终通过执行shell命令启动本项目: docker-compose -f docker-compose-standalone.yml up -d ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/15/1649992522247849007.png) 这句shell命令中的docker-compose-standalone.yml正是我们代码仓库根目录的docker-compose-standalone.yml文件。 下面对docker-compose-standalone.yml文件进行解读。 version:指定本 yml 依从的 compose 哪个版本制定的。 services:包含的服务。 本yml中含有redis、db、vote、result、worker五个服务。其中db即数据库postgres。 image:镜像地址。 以redis和worker服务为例,其镜像为docker-server/docker-org/redis:alpine、docker-server/docker-org/worker:image-version,这里采用的是参数化替换的形式定义镜像地址的。 在构建任务phoenix-sample-ci中,“替换Docker-Compose部署文件镜像版本”步骤的shell命令正是将docker-compose-standalone.yml文件中的docker-server、docker-org、image-version三处替换为我们在该构建任务中定义的三个参数dockerServer、dockerOrg、BUILDNUMBER。 进行这样的替换以后,我们的docker-compose-standalone.yml中的镜像地址才会变成我们所需的最终地址。例:swr.cn-north-4.myhuaweicloud.com/devcloud-bhd/redis:alpine、swr.cn-north-4.myhuaweicloud.com/devcloud-bhd/worker:20220303.1。 五个服务中,vote、result、worker是本项目构建生成的,redis和db是采用第三方应用,所以在镜像版本方面会有区别。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/15/1649992549737260463.png) ports:端口号。将容器和主机绑定到暴露的端口。 在vote当中ports: 5000:80就是将容器所使用的80端口号绑定到主机的5000端口号,这样我们就可以通过主机ip>:5000来访问本项目的用户端界面了。 networks:配置容器连接的网络。这里使用的是最简单的两种声明网络名称。 frontend即前端,backend即后端。 environment:添加环境变量。POSTGRES_HOST_AUTH_METHOD: "trust",此变量防止访问postgres时无法登录。 volumes:将主机的数据卷或着文件挂载到容器里。db-data:/var/lib/postgresql/data下的内容即成为postgres当中的数据内容。 deploy:指定与服务的部署和运行有关的配置。placement:constraints: [node.role == manager]即:权限设置为管理员。 depends_on:设置依赖关系。vote依赖redis、result依赖db。 至此,整个HE2E项目的代码结构已经解构完毕。 # 编译构建 其实在完成代码解构之后,整个项目已经非常清晰了。代码中包括vote、result、worker三个功能模块,项目还用到了redis和postgres两个第三方应用。所以,我们在编译构建环节的主要目的就是把这些服务的镜像制作出来并上传到SWR容器镜像仓库中。 本项目中预置了5个构建任务。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/15/1649992578449603097.png) 我们仅分析phoenix-sample-ci任务即可。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/15/1649992591941404932.png) # 三个功能模块的构建 在进行代码解构时,对构建任务的部分内容已经进行过分析了,其中就包括如何通过指定Dockerfile文件制作镜像,即docker build(制作)的操作。除此之外,制作XX镜像并推送到SWR的步骤中还包括了推送镜像所需的信息。这里设置了推送区域、组织、镜像名字、镜像标签,其实就是我们进行docker tag(打标签)和docker push(推送)的操作。 在vote、result、worker的镜像制作并推送的过程中,通过参数BUILDNUMBER定义镜像的版本号。BUILDNUMBER是系统预定义参数,随着构建日期及次数变化。 worker镜像在制作之前,需要先对worker目录下的工程进行Maven构建,这样就会生成Dockerfile.j2中(制作镜像时)所需的target文件。 # Postgres和Redis的构建 在制作了三个功能模块镜像以后,接下来要做的是生成Postgres和Redis 镜像。这里选择的办法是,通过shell命令写出这两个应用的Dockerfile。 echo from postgres:9.4 > Dockerfile-postgres echo from redis:alpine > Dockerfile-redis 通过这段shell命令就会在当前的工作目录下生成Dockerfile-postgres和Dockerfile-redis两个文件。 Dockerfile-postgres: FROM postgres:9.4 Dockerfile-redis: FROM redis:alpine 在接下来的步骤当中,指定当前目录下的Dockerfile-postgres和Dockerfile-redis两个文件制作镜像并上传。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/15/1649992617870611458.png) # 替换部署配置文件并打包 通过以上的步骤,镜像就已完全上传至SWR仓库了。后续的“替换Docker-Compose部署文件镜像版本”和“替换Kubernates部署文件镜像版本”两个步骤分别将代码仓根目录下的docker-compose-standalone.yml和kompose下的所有XX-deployment.yaml文件中的docker-server、docker-org、image-version替换为构建任务中的参数dockerServer、dockerOrg、BUILDNUMBER。这两步骤的意义就是将ECS部署(docker-compose/docker-compose-standalone.yml)和CCE部署(Kubernates/Kompose)所需的配置文件修改为可部署、可应用的版本。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/15/1649992636272683258.png) 这两个文件修改完毕后,都进行tar打包的操作。打包后的产物也通过接下来的两个“上传XX”步骤上传软件包到了软件发布库。 # Tips 在本项目的帮助文档中,提到了“配置基础依赖镜像”。整个这一段落是由于构建任务中使用的基础镜像源DockerHub拉取受限,采取了一个折中的办法拉取镜像。简言之,整段操作即通过创建prebuild任务来实现基础镜像版本的替换,以避免开发者在进行构建phoenix-sample-ci任务时出现拉取镜像失败的情形。相应地,也在“配置并执行编译构建任务”中禁用了Postgres和Redis镜像的制作步骤。 # 部署 在编译构建环节,我们已经成功将三个功能模块镜像(vote、result、worker)和两个第三方镜像构建并上传至SWR(容器镜像仓库)中了。接下来需要做的就是将SWR中的镜像拉取到我们的部署主机并启动。 在整个实践中,提供了ECS部署和CCE部署两种方式,并且在项目中预置了3个部署任务。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/15/1649992665932342943.png) 我们仅分析phoenix-sample- standalone任务即可。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/15/1649992675863946981.png) # 传输软件包至部署主机中 在构建环节,我们除了制成镜像并上传到SWR以外,还对配置文件进行了修改、压缩并上传到了软件发布库。在部署过程中,我们首先要做的,就是把配置文件从软件发布库中传到部署主机当中。 结合实际的部署任务来看,就是:向[主机组] group-bhd部署一个[软件包/构建任务(的产物)],我们选择了[构建任务] phoenix-sample-ci的最新版本([构建版本][Latest])构建产物,将其[下载到主机的部署目录]。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/15/1649992690142429572.png) 这一步骤执行完毕后,在部署主机的/root/phoenix-sample-standalone-deploy路径下,就会存在之前构建任务中压缩的docker-stack.tar.gz和phoenix-sample-k8s.tar.gz。ECS部署中,我们仅需要解压docker-stack.tar.gz,这个文件是docker-compose-standalone.yml的压缩包(回顾一下构建任务中的“替换部署配置文件并打包”)。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/15/1649992698717175913.png) # 通过执行shell命令启动docker-compose 解压完成后,我们就可以通过执行docker-compose启动命令来启动项目了。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/15/1649992904755929258.png) 在这一步骤当中,前三行分别输出了三个参数docker-username、docker-password、docker-server。这三个参数是用以进行docker login操作的。因为我们在docker-compose-standalone.yml中涉及到拉取镜像的操作,需要在拉取镜像前先登录SWR镜像仓库。 登录完毕后,就可以进入/root/phoenix-sample-standalone-deploy目录下(cd /root/phoenix-sample-standalone-deploy) 启动docker-compose(docker-compose -f docker-compose-standalone.yml up -d)。 至此,项目已经部署至主机当中,在主机中,通过docker ps -a指令可以看到5个容器进程。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/15/1649992916628234226.png) 与此同时,访问http://{ip}:5000和http://{ip}:5001即可访问项目的用户端与管理端。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/15/1649992924275226079.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/15/1649992931703616375.png) # 结语 本文从容器技术应用的角度解构了HE2E项目的代码仓库配置、镜像构建、及docker-compose的部署方式。希望通过本篇文章分享可以使更多的开发者了解容器技术和华为云。
  • [虚拟化] 基于1822网卡的原生ovs+dpdk(二) -- 使用篇
    接部署篇1.开启smmu并配置iommu:内核启动项参数添加 iommu.passthrough=1 进入BIOS -> Advanced -> MISC Config -> Support Smmu          ->      F10保存退出2.分配大页内存:临时生效:echo 40 > /sys/devices/system/node/node0/hugepages/hugepages-524288kB/nr_hugepagesecho 40 > /sys/devices/system/node/node1/hugepages/hugepages-524288kB/nr_hugepagesecho 40 > /sys/devices/system/node/node2/hugepages/hugepages-524288kB/nr_hugepagesecho 40 > /sys/devices/system/node/node3/hugepages/hugepages-524288kB/nr_hugepages永久生效:内核启动项参数添加 default_hugepagesz=512M hugepagesz=512M hugepages=160实际分配大页内存总大小根据物理内存的大小决定,物理内存至少预留10%以上查看大页内存分配生效情况相关命令:cat /sys/devices/system/node/node*/meminfo | grep Hugecat /proc/sys/vm/nr_hugepagescat /sys/devices/system/node/node*/hugepages/hugepages-524288kB/nr_hugepagescat /sys/devices/system/node/node*/hugepages/hugepages-524288kB/free_hugepages3.加载1822驱动模块:modprobe uioinsmod /xxx/dpdk-19.11/arm64-armv8a-linuxapp-gcc/build/kernel/linux/igb_uio/igb_uio.ko也可以使用vfio:modprobe vfiomodprobe vfio-pci4.连接交换机的物理网口切换到用户态:dpdk-devbind -s报错:解决方法:vim /usr/sbin/dpdk-devbind添加:defaultencoding = 'utf-8'if sys.getdefaultencoding() != defaultencoding:    reload(sys)    sys.setdefaultencoding(defaultencoding)参考:https://www.cnblogs.com/casonchan/p/4669799.htmldpdk-devbind -b igb_uio 0000:xx:00.05.配置ovs-dpdk启动项参数:ovs-vsctl --no-wait set Open_vSwitch . other_config:dpdk-init=true \other_config:dpdk-socket-mem="4096,4096,4096,4096" \other_config:dpdk-lcore-mask="0x1F" \other_config:pmd-cpu-mask="0x1E" \other_config:dpdk-pmd-driver=/lib64/librte_pmd_hinic.soservice openvswitch restart6.组网报错:解决:升级驱动和固件:https://support.huawei.com/enterprise/zh/doc/EDOC1100072480/3ec468f6https://support.huawei.com/enterprise/zh/software/253953559-ESW2000399492参考命令:hinicadm updatefw -i hinic0 -f Hi1822_nic_prd_1h_4x25G.bin重新编译dpdk、加载igb_uio、绑定网口到igb_uio、重启ovs、组网,解决7.确认Host用户态的1822网口可以收到流对端用物理打流仪器连接交换机(tesgine、思伯伦等),本端Host使用testpmd收包,testpmd参考命令:cd /xxx/dpdk-19.11/arm64-armv8a-linuxapp-gcc/app/./testpmd -d /usr/lib64/librte_pmd_hinic.so -w 0000:xx:00.0 -- -i原因:host上,ovs启动参数使用dpdk,会占用dpdk主程序,启动testpmd时候会报错关掉ovs,或ovs启动项参数不配dpdk,可以通过testpmd看到用户态的网口上通过交换机收到tesgine发来的流量service openvswitch stop./testpmd -d /usr/lib64/librte_pmd_hinic.so -w 0000:xx:00.0 -- -itestpmd> starttestpmd> set fwd rxonlytestpmd> show port info alltesgine通过查询到的本端网口mac地址开始打流testpmd> stop
  • [技术干货] 快速上手 BetterScroll 实现滑动效果
    #### BetterScroll BetterScroll 是一款重点解决移动端(已支持 PC)各种滚动场景需求的插件。 它的核心是借鉴的 iscroll (opens new window)的实现,它的 API 设计基本兼容 iscroll 在 iscroll 的基础上又扩展了一些 feature 以及做了一些性能优化。 **结构** ``` <div class="wrapper"> <ul class="content"> <li>...</li> <li>...</li> ... </ul> <!-- 这里可以放一些其它的 DOM,但不会影响滚动 --> </div> ``` BetterScroll 是作用在外层 wrapper 容器上的,滚动的部分是 content 元素。 这里要注意的是,BetterScroll 默认处理容器(wrapper)的第一个子元素的滚动,其它的元素都会被忽略。 **初始化组件** ``` import BScroll from '@better-scroll/core' let wrapper = document.querySelector('.wrapper') let scroll = new BScroll(wrapper) ``` BetterScroll 提供了一个类,实例化的第一个参数是一个原生的 DOM 对象。 当然,如果传递的是一个字符串,BetterScroll 内部会尝试调用 querySelector 去获取这个 DOM 对象。 这里的`querySelector` 就是容器的`id class` 属性,当然了在vue可以通过`ref`设置 **滚动原理** wrapper 就是我们列表显示区域,这个可能是定宽、或是定高,而content就是我们滑动的列表数据 内容的数据的高度必须超过容器的高度,对于简单滑动可以通过设置固定值, 实现滑动的效果,但是对于异步加载属性需要通过特定函数重新计算高度. **当然了多处使用滑动组件我们就需要封装一个自己better-scroll** ``` import BScroll from 'better-scroll' export default { props: { /** * 1 滚动的时候会派发scroll事件,会截流。 * 2 滚动的时候实时派发scroll事件,不会截流。 * 3 除了实时派发scroll事件,在swipe的情况下仍然能实时派发scroll事件 */ probeType: { type: Number, default: 1 }, /** * 点击列表是否派发click事件 */ click: { type: Boolean, default: true }, /** * 是否开启横向滚动 */ scrollX: { type: Boolean, default: false }, /** * 是否派发滚动事件 */ listenScroll: { type: Boolean, default: false }, /** * 列表的数据 */ data: { type: Array, default: null }, /** * 是否派发滚动到底部的事件,用于上拉加载 */ pullup: { type: Boolean, default: false }, /** * 是否派发顶部下拉的事件,用于下拉刷新 */ pulldown: { type: Boolean, default: false }, /** * 是否派发列表滚动开始的事件 */ beforeScroll: { type: Boolean, default: false }, /** * 当数据更新后,刷新scroll的延时。 */ refreshDelay: { type: Number, default: 20 } }, mounted() { // 保证在DOM渲染完毕后初始化better-scroll setTimeout(() => { this._initScroll() }, 20) }, methods: { _initScroll() { if (!this.$refs.wrapper) { return } // better-scroll的初始化 this.scroll = new BScroll(this.$refs.wrapper, { probeType: this.probeType, click: this.click, scrollX: this.scrollX }) // 是否派发滚动事件 if (this.listenScroll) { this.scroll.on('scroll', (pos) => { this.$emit('scroll', pos) }) } // 是否派发滚动到底部事件,用于上拉加载 if (this.pullup) { this.scroll.on('scrollEnd', () => { // 滚动到底部 if (this.scroll.y <= (this.scroll.maxScrollY + 50)) { this.$emit('scrollToEnd') } }) } // 是否派发顶部下拉事件,用于下拉刷新 if (this.pulldown) { this.scroll.on('touchend', (pos) => { // 下拉动作 if (pos.y > 50) { this.$emit('pulldown') } }) } // 是否派发列表滚动开始的事件 if (this.beforeScroll) { this.scroll.on('beforeScrollStart', () => { this.$emit('beforeScroll') }) } }, disable() { // 代理better-scroll的disable方法 this.scroll && this.scroll.disable() }, enable() { // 代理better-scroll的enable方法 this.scroll && this.scroll.enable() }, refresh() { // 代理better-scroll的refresh方法 this.scroll && this.scroll.refresh() }, scrollTo() { // 代理better-scroll的scrollTo方法 this.scroll && this.scroll.scrollTo.apply(this.scroll, arguments) }, scrollToElement() { // 代理better-scroll的scrollToElement方法 this.scroll && this.scroll.scrollToElement.apply(this.scroll, arguments) } }, watch: { // 监听数据的变化,延时refreshDelay时间后调用refresh方法重新计算,保证滚动效果正常 data() { setTimeout(() => { this.refresh() }, this.refreshDelay) } } } ```
  • [知识分享] 【微服务系列】详解4种微服务框架接入Istio方案
    本文分享自华为云社区《[传统微服务框架接入Istio方案详解](https://bbs.huaweicloud.com/blogs/337177?utm_source=zhihu&utm_medium=bbs-ex&utm_campaign=other&utm_content=content)》,作者:香菜聊游戏 。 # 微服务的概念和原理 ## 微服务带来的问题 **微服务带来的好处:** 解耦了业务,解耦了代码和架构,业务更紧凑,逻辑更单一简单。 **微服务带来的问题:** 在早期的时候,使用单体架构,所有的业务都在一个服务内,没有跨进程和网络上的一些复杂度。 微服务化之后引入的问题包括如何做服务发现,怎么做负载均衡,包括服务间的访问保护,例如熔断,故障定位等等问题。 在故障定位时,在原来单体服务下只需要看下日志,但是微服务化之后需要借助分布式调用链工具,这无形中带来了开发和定位问题的复杂度。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648172893747136548.png) **微服务和lstio网格架构对比** ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648172910258181295.png) 微服务框架我们了解比较多的Spring cloud 或者国内用的比较多的Dubbo,框架本身就不多介绍了,我想大家都有所了解。 原理就是提供了开发的SDK或者说叫框架,这些框架都是内置了一些解决微服务问题的方案,比如服务发现,负载均衡,服务的熔断和降级,以及调用链路的埋点,动态路由这些事情。 下图是一个典型的用法,也是应用非常广泛的用法 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648172924592109894.png) 基于网格的治理是近些年应用比较多的,从上图可以看出,虽然基于网格的治理提供的能力和上图的基于sdk的能力一样,但是两者的设计原理,使用场景,设计理念是不同的。 # 详细介绍 ## 服务发现和负载均衡 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648172946950218939.png) 上图是传统的微服务框架的原理 一般的流程是: • 服务启动的时候向服务中心进行注册 • 调用的时候先从服务中心获取后端服务的地址 • 选择一个实例发送请求,等待回复 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648172971697244448.png) 服务网格的工作原理: 服务网格一般和k8s结合使用,因为k8s 本身做了服务的endpoint 维护,所以lstio不需要做服务注册,只需要做服务发现。 看下详细的区别 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648172983057758844.png) **服务熔断** ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648173014022563261.png) 服务熔断的机制: 如果一个服务在配置的一段时间内一直不可用,可以通过熔断机制,把服务隔离开,接触不到流量,进入到半熔断状态, 如果在一定的考察时间段能够恢复正常,熔断状态就会关闭,如果还是不能正常,会继续进入到熔断状态。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648173025636281188.png) # 传统微服务框架的问题和基于服务网格的解决方案 **问题1:微服务SDK的多语言问题** ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648173045760911718.png) 上面这张图示意了微服务的之间的关系,一些大的客户拥护大的系统,系统由多个服务组成,服务可能由多种语言开发。 比如系统中可能有go服务,C++服务,python服务以及spring cloud 服务等等,这是一种比较常见的情况。 在这些服务中想做一个通用的服务发现时,但是Spring cloud或者Dubbo开发的服务,有一套自己的服务发现机制,但是不同语言开发的服务之间发现框架是不同的,比如go服务开发的服务不可能去spring cloud的服务中心注册,这个问题没办法解决。 比较粗暴的解决办法是对其他语言的项目用Java重构,在项目不复杂的情况下是可以接受的,但是在系统业务比较复杂,需要修改的项目比较多的情况下是无法接受的,不仅需要大量的人力,还要花费大量的时间,服务的稳定性没法保证。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648173056841925038.png) 服务网格的解决方案下,服务发现是业务解耦的,不管是什么语言开发的服务,因为proxy不需要参与编译,网格之间只需要开放端口,并且保持可以访问,在这种方案下,不需要修改原来代码,减少了开发量,是企业可以接受的。 **问题2:基于sdk的服务在k8s下出现延迟和数据不一致** ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648173073450569182.png) 在上图这种情况下,Consumer服务原来在pod1 上,后来由于调度问题,导致Consumer服务迁移到pod2 上,正常情况下pod1 需要注销,pod2 进行重新注册,但是如果pod 迁移比较频繁,导致Producer 在访问Consumer服务的时候仍然拿到老的注册地址,就会出现延迟和数据不一致的情况。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648173082735445456.png) **问题3:基于SDK逻辑开发的服务升级必须重新编译** ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648173142036639477.png) 基于SDK开发的逻辑代码进行升级的时候,必须重新编译所有基于SDK开发的服务,这个升级会带来大量的工作量,SDK的升级过程必须要和业务团队一起升级,非常耗时。产生的需求就是如果业务代码没有改变的情况下不需要重新编译。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648173153337627183.png) 使用网格的解决方案下,如果业务没有修改是不需要进行编译和修改的,对开发人员和运维来说是非常友好的,同时降低了运维的风险,毕竟任何改动都是风险。 **问题4:基于SDK开发,统一发现和治理能力,需要全部改造** ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648173166300440438.png) 如果对一个单体应用进行微服务化,一般是渐进微服务化,比如上图,一般先对svc1进行微服务化,然后再对svc2 进行微服务化,在开发的过程中需要仍然访问互通,但是使用SDK的微服务有时需要使用同一框架,同一版本才能进行通信交互,这就是痛点。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648173174232589949.png) 在使用网格的情况下,第一步先对svc1进行微服务化,svc2不改动,在开发的期间仍然不影响原来的访问。 # 传统微服务框架在服务网格中集成的实践详情 **总体思路** ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648173194399917971.png) 卸载SDK的服务发现和服务治理的功能,将这些功能迁移到基础设施上,让用户从这些中解脱出来,只专注于自己的业务代码。 **解决方案** ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648173206617415069.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648173231925154426.png) 传统微服务的发现是注册到注册中心 在使用网格之后,平台同一服务发现,使用kube-proxy进行服务发现和负载均衡,Kube-proxy 直接返回服务的ip和端口,这样的话就消除容器环境下服务发现数据不及时的问题。 在使用k8s做服务发现,再使用网格的能力,服务完全无需修改适配 **Spring cloud项目的改造** ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648173251864677119.png) 在原来的配置中,取消对注册中心的注册,改为直接使用服务名:端口进行访问,直连的这种方式会被k8s 进行转发,对业务代码无需修改,减少了工作量。 注意:**要和访问的服务保持协议一致。** **移除spring cloud 的项目依赖** ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648173273991517518.png) **微服务网关的改进** ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648173288079137091.png) 情况1:微服务网关有业务逻辑 写了很多自定义的逻辑,比如filter的过滤等等,这种情况下网关可以作为普通的微服务部署在网格内。 情况2:微服务只有通用逻辑能力 直接用Ingress进行替换,进行地址映射,路径映射等基础能力,移除原来的网关。 **集成微服务注册中心到网格** 由于有些项目开发架构自成体系,不太适合直接排除原来的基础能力,在这种情况下想使用网格的能力,需要把原来的注册中心导入。Istio从微服务的注册中心导入注册数据,并且转换格式存储,在这种情况下依然可以配置相同的治理规则。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648173305397667851.png) # 总结 使用k8s和lstio网格进行开发,将服务发现,服务治理留给基础设施,可以将开发人员从复杂的服务中解脱出来,专注于业务开发,是当前来说比较好的解决方案。 视频地址:https://education.huaweicloud.com/courses/course-v1:HuaweiX+CBUCNXI055+Self-paced/courseware/511f6f06d97d4aaf9b90445dca5800d1/c08eb6fa0dd14a34bd617c6beb63a923/
  • [ARM原生] robox方案搭建,容器启动失败,执行getprop | grep sys.boot.completed与预期不符,无画面显示
    背景:鲲鹏920+ubuntu18.04.1+GPU在获取robox搭建指南后,按照文档操作,发现getprop | grep sys.boot.completed执行与文档中预期不符,且容器无法进行连接,通过ardc远程无画面输出,在咨询ARM原生专家后,通过专家建议,对环境进行如下基本检查:1、检查xorg.conf中的BusID是否正确。2、Xorg是否启动正常。3、环境变量DISPALY是否存在,且与robox脚本中变量设置一致。4、环境变量XDG_RUNTIME_DIR是否存在。5、是否进行转码使能。通过对环境的排查,发现有两个问题:1、转码使能未开启,由于环境为鲲鹏920设备,一定要转码使能之后才可正常启动docker容器2、自行编译的镜像存在问题,导致容器启动失败,通过使用文档中的测试镜像,可正常启动。在处理上述两个问题后,通过robox启动脚本,容器正常启动,getprop | grep sys.boot.completed执行结果与预期一致,宿主机能出画面,但通过ARDC远程连接一直显示waiting for device关于ARDC远程连接一直显示waiting for device的问题,在咨询ARM原生专家后,发现是adb的版本过低,在替换了ARDC高版本后,可正常接出画面
  • [交流讨论] AOC的Agile, Open, Container 分别是什么含义?
    接触AOC以来,我一直很好奇AOC(Agile Open Container)该怎么理解呢?现在终于有些眉目啦,与大家分享~ Agile即敏捷。敏捷顾名思义,就是快速而精准。快速,体现在割接搬迁中,做到三个1。         1个星期原型:AOC内置了主流厂商的设备驱动。         1个月POC(Proof of Completion):AOC降低了开发的门槛,乐高式编程,快速测试验证。         1个季度交付:业务包可以在线加载,甚至不用重启和升级NCE。精准,体现在网络运维质量的提升。        某公有云现网管理中,涉及10万余台设备,存在几代的存量网络架构,和超过50个软件版本,每天都有上百次设备上线、线路扩容、BGP peer对接等操作。变更风险非常大,质量风险特别高,每天晚上都需要投入20余人参与变更以及相关质量的维护工作。过去,该公有云的变更,主要由python硬编码的方式实现,过程非常复杂,而且需求的传递容易导致错误。与AOC联合打造模型驱动的变更自动化平台后,由AOC负责最核心的模型管理和模型翻译工作,并北向与公有云的编排平台对接,支持公有云的网络工程师以拖拉拽的方式,独立完成变更场景的编排,业务开发效率非常高。同时网络变更自动化过程中自动回退能力,是变更的核心诉求。AOC能基于网络正向配置,自动生成网络回退命令行,避免了人工设计产生错误的可能,大幅提高变更工作的质量。 Open即开放。开放,就是把自主开发、自主定义的可能性,最大限度地开放给客户自己。有能力的客户:AOC支持客户拿着这个系统完全自主编程、自行定义业务需求。有标准的客户:客户定义企标并进行集采,华为来编程,提供敏捷交付。有预算的客户:华为和专业服务一起,ISPA+AOC合作提供开发和集成能力。 Container即容器。AOC由SSP, SND两部分组成。SSP就像夹娃娃机里悬在上空的夹子, SND则对应着各种厂商、各种版本的设备,就像玻璃容器中的众多娃娃。客户业务方面的意图和需求,从SSP这里传递进来,通过Yang+Python+Jinja协作的方式操纵这个夹子,在容器中选择自己想要的模板。在容器中,每个娃娃互相独立。海外多厂商设备共存,multivendor的问题则迎刃而解;设备升级时,不同版本产生的不兼容问题,则通过SND domain id,实现模型隔离,和数据存储隔离。结合业务数据影响分析工具,实现差异屏蔽、平滑升级。
  • [其他] 强化学习算法控制核聚变登上Nature:DeepMind让人造太阳向前一大步
    强化学习算法控制核聚变登上Nature:DeepMind让人造太阳向前一大步     DeepMind 和瑞士洛桑联邦理工学院 EPFL 一直在进行一个神秘的项目:用强化学习控制核聚变反应堆内过热的等离子体,如今它已宣告成功。DeepMind研究科学家David Pfau在论文发表后感叹道:「为了分享这个时刻我已经等了很久,这是第一次在核聚变研究设备上进行深度强化学习的演示!」可控核聚变、强人工智能、脑机接口是人类科技发展的几个重要方向,有关它们何时可以实现,科学家们的说法永远是「还需几十年」——面临的挑战太多,手头的方法却很有限。那么用人工智能去控制核聚变,是不是一个有前途的方向?这个问题可能需要由提出 AlphaGo 的 DeepMind 来回答了。最近,EPFL 和 DeepMind 使用深度强化学习控制托卡马克装置等离子体的研究登上了《自然》杂志。首先,我们来思考一个问题:为什么要用人工智能控制核聚变?托卡马克是一种用于容纳核聚变反应的环形容器,其内部呈现出一种特殊的混乱状态。氢原子在极高的温度下被挤压在一起,产生比太阳表面还热的、旋转的、翻滚的等离子体。找到控制和限制等离子体的方法将是释放核聚变潜力的关键,而后者被认为是未来几十年清洁能源的源泉。在这一点上,科学原理似乎是说得通的,剩下的就是工程挑战。参与该研究的瑞士等离子体中心(SPC)主任 Ambrogio Fasoli 表示:我们需要能够加热这个装置,并保持足够长的时间,以便我们从中吸取能量。在同样由聚变驱动的恒星中,仅依靠引力质量就足以将氢原子拉到一起并克服它们的相反电荷。在地球上,科学家们改为使用强大的磁线圈来限制核聚变反应,将其推到所需的位置。这些线圈必须仔细控制,以防止等离子体接触容器本身:这会损坏容器壁并减慢聚变反应。 但每次研究人员想要改变等离子体的配置并尝试不同的形状,以产生更多的能量或更纯净的等离子体时,都需要大量的工程和设计工作。传统的系统是由计算机控制的,基于模型和模拟,但 Fasoli 表示传统方法「复杂且不一定能起到优化的作用」。DeepMind 控制团队负责人 Martin Riedmiller 表示:「人工智能,特别是强化学习,特别适合解决托卡马克中控制等离子体的复杂问题。」DeepMind 在论文中详细介绍了所提的可以自主控制等离子体的 AI。论文地址:https://www.nature.com/articles/s41586-021-04301-9
  • [入门/教程] 与K8s一起航行:海量节点的多集群管理
    在KubeCon2021上,中国工商银行软件开发中心云平台架构师沈一帆和华为云云原生开源负责人王泽锋发表了《与Karmada一起航行:海量节点的多集群管理》专题演讲,分享了工商银行多k8s集群管理实践过程。*Karmada项目介绍部分由王泽锋分享,其余部分的分享来自沈一帆工行云平台的建设现状工行目前的业务上云场景是丰富多样的,既有以春节红包等支付线为代表的核心业务类应用,也有以MySQL、Redis为代表的技术支撑类应用,也包含了区块链、人工智能等新技术领域。目前工行云平台也是基于主流的开源项目进行了深度的定制化研发,保证了整体的自主可控性。从建设情况来看,也是同业最大规模的一个容器云,目前数量达到了28万+。典型业务需求及云原生基础设施现状在大规模的云原生基础设施的背景下,工行的业务对我们提出的具体的要求以及目前的现状。典型的业务需求主要包含以下几类:业务需要高可用的部署、应用需要跨集群地进行弹性伸缩以及跨集群的调度,一些业务产品需要对K8s版本有特定的一个依赖。基于以上情况,工行目前的云原生基础现状如下:单集群可靠性要求比较高。我们整体的单集群的节点数量在2000以下,就是为了缩小集群的一个故障率影响范围。资源池随业务快速增长。目前新业务应用是全面上云,存量应用是持续地迁移入云,现在核心应用已经全部入云。业务级异构集群。业务对特定的K8s版本有依赖,并且有大量的异构的CNI、CSI、包括底层一些硬件异构。多地、多中心、多云的建设现状,工行业务上包括总行云、分行云,生态云等。故障域方面是两地三中心的数据中心建设,并且在数据中心内部也有多故障域方面更细粒度的划分。基于此,工行内部的K8s集群数量其实已经达到了100个以上,目前由容器云平台统一纳管管理。但在持续发展的过程中,我们也面临着以下问题:可用性受限,因为K8s集群本身也是一个故障域,目前缺少跨故障域自动恢复。资源受限,整体的应用的调度和弹性伸缩受限于单集群。集群不透明:由于集群目前都打上了异构、故障域等属性,业务团队需要感知底层的集群去自主选择K8s集群,就导致了K8s集群本身是对上层应用是不透明的。重复配置。尽管我们的业务统一在云管平台进行了配置的录入,但具体的配置需要下发到各个集群当中,且各个集群需保证同步。面对这些挑战,我们对多集群的管理拟定了设计目标:在多集群管理平面方面:集群纳管和对集群有整体生命周期管理,并且具有统一标准的API入口。在资源管理方面,需要支持多版本全面的K8s资源,同时也需要多维度的资源Override支持。在跨集群自动调度方面,调度上需要按故障域、资源余量等进行自动调度,并且可跨集群自动伸缩。容灾方面,需要进行跨集群资源的自动恢复,并且管理平面与业务集群需要解耦。兼容性方面,对存量大量的异构集群需要平滑的纳管,同时项目本身需要高扩展性及社区的活跃度。联合创新有了清晰的设计目标,接下来就是如何实施落地了。首先对于商用产品,考虑到单一厂商的绑定和不符合自主可控的要求,首先被我们pass,而调研kubefed之后,发现它使用非原生API,对于我们存量集群来说迁移难度过大,且近期社区活跃度下降。最后我们选择以最贴合我们需求的方式,立足自身进行联合研发,同时工行金融云本身也是基于开源,所以我们也是积极地投入到开源共建,推动社区发展这个良性循环中来,最后选择联合发起karmada项目。那可能有人会问,为什么不在原有KubeFed的基础上继续演进,而是发起一个全新的项目呢?实际上我们在项目的初期考虑的确实是Kubernetes Federation的V3版本,并且很快地完成了原型的开发。然而在后来与许多的社区用户的交流过程中,我们发现其实狭义的Federation的项目范围并不能完整地覆盖大家期望提供的能力版图。除了Federation本身包含的多集群应用负载管理的能力之外,其实我们重点还希望去提供像多集群的资源调度、故障迁移、自动伸缩,以及像多集群的服务发现、数据自动化和多平台支持的集群的生命周期管理等等,为用户真正地去提供开箱即用的多云多集群的开源软件站。因此一个托管于 CNCF的中立的开源项目,会更适合于长期的技术演进和社区发展。Karmada 项目Karmada的核心架构在Karmada的核心架构方面,吸取了多家社区发起单位在多集群管理上的经验和心得,我们把重点放在了K8s原生API支持、以及框架可扩展性上。与K8s单集群架构略有相似:Karmada 的控制面拥有自己独立的APIserver,来提供K8s原生API以及Karmada的扩展API通过Karmada Scheduler,提供针对 [故障域、集群资源、K8s版本及集群开启插件等多维度、多权重的]调度策略支持,并方便用户自定义扩展与member集群的同步方面,Karmada Agent的pull工作模式,可以有效分散控制面压力,实现超大规模多集群资源池的管理。同时,Karmada还支持ExecutionController以及集成KubeEdge方式实现对位于公有云、私有云以及边缘等各种网络环境中K8s集群的直接管理。而借助ExecutionSpace的设计,Karmada实现了不同集群之间的访问权限和资源隔离,来满足多集群场景下的安全性需要。 Karmada 核心概念在Karmada核心概念的设计方面我们把用户输入的一切工作负载相关资源对象定义为Resource Template,这是严格的K8s原生API,支持包括deployment,service,configmap等,以及用户自定义的CRD资源对象。这样,用户无需任何修改,就可以直接使用原有单集群的YAML或者API来创建多集群应用,而原本在K8s之上二次开发的业务平台也不用做任何的修改。针对应用跨多集群的拆分和调度,扩展的Propagation Policy支持被多个应用复用的定义。得益于这种解耦的设计,在像工行这样独立设置平台团队和业务团队的场景中,平台团队可以针对通用的高可用部署模型设置策略,而业务团队则可以继续使用K8s原生的单集群API来管理日常的业务上线和版本升级。下面我用一个例子来说明用户是如何使用Karmada管理他们的业务零改造:使用原生API部署一个3AZ高可用的应用在这个例子中我们可以看到,其实首先是一个Propagation policy。在这个Propagation policy的定义中,平台团队设置了 Resource selector,限定所有的Deployment,如果它带有特殊的Label,HA mode为Multi zone replication,则把这些应用严格地分发到三个Zone里面去。而右边就是我们所熟悉的一个标准的 Deployment的 API的定义。通过组合这两个定义,其实我们可以看到平台团队聚焦在了通用的应用部署的模型的设置上,而业务团队聚焦在了它本身的应用内部的如Image、版本,以及像这些 Container port等等的定义上面。而Karmada负责将两个团队的需求做结合,实现应用的跨区域的高可用。在任何底下集群出现故障的情况下,可以通过动态的调度能力,自动地去补齐缺失的集群或缺失的可用区的应用实例,来实现跨集群的故障迁移。实践心得在Karmada设计研发实践再设计研发的正向循环的过程中,工行也总结了一些它的优势,也可以说是心得。主要分以下四类:资源调度、容灾、集群管理和资源管理。那么其中我认为尤其值得关注的是以下三点,那么在真实落地的过程中也显得尤为得突出。支持多种资源的绑定调度,这保证了业务节点所需的k8s资源能够同时调度,也大大提升了我们资源发放的实时性。支持k8s原生对象,这保证了我们大量的目前的k8s外部客户端几乎无需改造。Karmada目前支持Pull和Push模式分发,适配了多种场景。尤其在我们大规模集群数量的一个场景下,使用Pull模式能大大减轻Karmada控制平面性能压力。后续计划在大规模生产落地方面,我们希望容器云平台将来是作为面向用户的一个平台,底层基于Karmada统一管理多集群的资源和调度,以此去纳管存量包括异构集群在内的100+的k8s集群。在社区贡献方面,我们希望持续地进行社区贡献。主要关注的特性包括存量应用的平滑迁移,能够自动纳入到Karmada联邦化。在跨集群伸缩、应用迁移与数据联动方面,继续持续地进行优化和落地。欢迎大家访问Karmada项目的GitHub,查看Release note和社区文档,了解更多的功能和细节。如果在使用Karmada的过程中有任何建议和反馈,欢迎加入社区群和我们交流与讨论!附:Karmada社区技术交流地址项目地址:https://github.com/karmada-io/karmadaSlack地址:https://karmada-io.slack.com
  • [互动交流] 【devcloud产品】【编译构建】”容器化构建充分利用资源”能力是怎么体现的?等有3点疑问
    【功能模块】1.容器化构建——达到充分利用资源。,,这里没有理解2.还有“全局共享缓存”能力,,是指任务成功后可以“构建包下载”吗3.编译构建支持增量构建吗,,是指在源编译构建任务中可继续添加构建原子吗【截图信息】
  • [知识分享] CCE容器业务如何配置访问外部静态资源
    背景:       容器业务中需要访问到某些静态文件,如鉴权文件、图片、前端静态资源等,直接将静态文件打包至容器中会导致容器臃肿,尤其是多负载需要共享这些资源时,每个容器中都需要配置这些文件,从而降低整体业务迭代更新速度。那CCE中有没有方法可以保持容器轻量化的同时,保证容器业务也能正常运行呢?解决方式:方案一:配置存储类型为HostPath模式       这种方式是一种常见的处理方案,其原理就是将这些静态文件配置在宿主机的某个目录,然后通过k8s中HostPath模式,将宿主机的路径挂载到容器的某个具体的目录下,实现两个目录间资源文件的共享。CCE中也支持这种配置方式,具体配置方式是:1)远程登录CCE Node节点,将静态文件上传至虚拟机的某个文件目录,如/tmp/front。2)起负载,并配置文件的挂载路径,如挂载至容器的/mnt/test目录3)配置亲和性。因为静态资源上传时只上传到了容器的部分节点,需要保证负载启动时运行在静态文件上传的那个宿主机节点,因此需要配置负载和节点的亲和性策略。4)配置完成后,启动容器,即可在容器中访问到这些文件。方案二:配置云端持久化存储       持久化存储是一种共享存储的概念,不仅能实现容器和宿主机之间文件数据的共享,而且能更加完整的保存应用运行的状态数据,便于应用恢复。云端通过插件机制完成共享存储的对接,以对象存储卷为例,看看云端持久化存储如何进行配置。1)首先需要创建对象存储卷。2)将静态文件上传至OBS对象存储桶。文件较大时建议通过OBS Broswer+进行上传。3)上传完成后,在CCE负载中配置挂载持久化存储。在负载中选择更新升级》高级设置》数据存储》云存储,点击天际云存储,选择对象存储,输入挂载至容器中的路径,如/mnt/test4)挂载完成后,点击提交,即可在容器中访问到这些静态文件。两种方案对比:方案一:优点是文件读取的性能较高,配置方式简单;缺点是需要设置节点亲和性;方案二:优点是pod的创建不依赖于某一个固定节点,文件配置、修改都较方便;缺点是通过插件对接了后端的存储服务,存在网络IO的消耗,存在性能问题。
  • [技术干货] 智慧园区数字平台设备统一接入基线已集成设备-通过IoT网关接入
    基线已集成设备园区基线预集成的设备IO包含:基线设备IO、连接实验室认证扩展IO。当对应设备接入园区时无需开发任何代码,可直接接入使用。基线设备IO:随基线版本一起安装,订购园区基线后默认安装好,如表1所示。连接实验室认证扩展IO:IO扩展包随基线版本发布,但默认不安装,项目可根据需要选装,如表2所示。扩展IO详情见连接实验室认证扩展IO。基线设备IO这部分设备IO随基线版本一起安装,订购园区基线后默认安装好。表1 基线设备IO条数分类设备IO“统一设备服务”端对应的设备规格1保安系统设备门禁设备IOAccessControl2泄露电缆设备IOLeakyCable3人行闸机设备IOTurnstile4消防系统设备消防烟感设备IOSmokeDetector5消防温感设备IOTemperatureSensor6消防手报设备IOManualFireAlarmActivation7声光报警设备IOAcoustoOpticAlarm8消防栓按钮设备IOFireHydrantButton9可燃气体探测器设备IOCombustibleGasDetector10能耗系统设备水表设备IOWaterMeter11电表设备IOElectricMeter12燃气表设备IOGasMeter13资产管理设备新基点IoT射频识别标签设备IORFID14新基点IoT射频识别读卡器设备IORFIDReader15环境监测设备户外环境监测设备IOOutdoorEnvSensor16室内环境监测设备IOIndoorEnvSensor17建筑BA设备空调机组设备IOAirHandleUnit18新风机组设备IOPreCoolingAirHandlingUnit19送风机设备IOSupplyAirFan20排风机设备IOExhaustAirFan21冷机设备IOChiller22冷冻水泵设备IOChillerWaterPump23冷却水泵设备IOCoolDownWaterPump24冷却塔设备IOCoolingTower25冷源补水箱设备IOColdSourceSupplyTank26冷源补水泵设备IOColdSourceSupplyPump27冷冻水总管设备IOChilledWaterMainPipe28冷却水总管设备IOCoolDownWaterMainPipe29管道设备IOMainPipe30膨胀水箱设备IOExpansionTank31蓄冷罐设备IOColdStorageTank32电热锅炉设备IOElectricBoiler33锅炉热水泵设备IOBoilerHotWaterPump34供热水泵设备IOHeatingWaterPump35排水泵设备IODrainagePump36生活水泵设备IODomesticWaterPump37集水井设备IOSumpPit38生活水箱设备IODomesticWaterTank39减压阀设备IOPressureReliefValve40室内照明控制器设备室内照明控制器设备IOIndoorLightingController41厕位检测设备厕位检测设备IOToiletPositionDetector42工位检测设备工位检测设备IOWorkStationDetector43升降电梯设备升降电梯设备IOElevator44电梯群控器设备电梯群控器设备IOElevatorClusterController连接实验室认证扩展IO这部分设备IO扩展包随基线版本发布,但默认不安装,项目可根据需要选装。表2 连接实验室认证扩展IO条数分类设备IO“统一设备服务”端对应的设备规格1电气火灾监测系统设备故障电弧探测器设备ArcFaultDetectionDevice2电气火灾检测系统探测器设备ElectrFireMonitorSysDetector3消防电源监控系统设备FirePowerMonitorSys4照明系统路灯设备StreetLight5室外景观照明设备OutdoorLandscapeLighting6室内多回路照明控制器设备IndoorMultLoopLightingController7环境空间监测系统震动传感器设备Vibrating8GPS定位器设备GPSLocator9智能手环设备SmartBand10垃圾桶设备Trashcans11擦手纸余量检测设备TissuePaper12厕纸余量检测设备ToiletPaper13客流统计设备PassengerFlow14多媒体点评器设备Evaluator15洗手液余量检测设备SoapDispenser16井盖检测器设备ManholeCoverDetector17路灯显示屏设备StreetLightDisplayScreen18激光探测器设备LaserDetector19应急指示灯设备EmergencyLamp20水文监测系统水位水质监测设备WaterQualityMonitoring21水文监测设备HydrologicalTelemetery22能耗管理系统能耗管理系统设备EnergyConsumption23智能水表设备SmartWaterMeter24热量表设备HeatMeter25冷量表设备CoolCapacityMeter26火灾自动报警系统报警主机设备AlarmHost27入侵报警系统电子围栏设备ElectronicFence28门磁探测器设备ElecLockDetector29报警主机防区设备AlarmHostDefenceArea30环境空间告警系统管线甲烷气体探测器设备PipelineCH4Detector31管线硫化氢气体探测器设备PipelineH2SDetector32管线温湿度探测器设备PipelineTempAndHumidityDetector33管线压力探测器设备PipelinePressureDetector34管线氧气气体探测器设备PipelineO2Detector35紧急按钮设备EmergencyButton36温湿度监测设备TemperatureHumidity37管道流量监测设备PipelineTrafficMonitoring38液压检测设备HydraulicPressureDetector39水浸检测设备WaterImmersion40液位检测设备LiquidLevelDetector41CH探测器设备CH4Detector42红外探测器设备InfraredDetector43一氧化碳探测器设备CODetector44氨气探测器设备AmmoniaDetector45空气质量探测器设备AirAualityDetector46地埋侧循环泵设备BuriedSideCirculatingPump47定压水泵设备ConstantPressurePump48水处理仪设备WaterTreatmentInstrument49地源热泵机组设备GroundSourceHeatPumpUnit50锅炉补水箱设备BoilerSupplyTank51二次水循环泵设备SecondaryCirculationPump52消防监测系统消防栓监测设备HydrantDetector53消防管道监测设备FireControlPipeDetector54BA400V进线设备InLine400V5510kV进线设备InLine10kV56400V出线设备OutLine400V57电力变压器温控器设备TransformerTempController58交流电通断检测器设备ACDetector59空气断路器设备AirCircuitBreaker60电箱温度传感器设备TempDetector61母联设备BusTieSwitch62电容器设备Capacitance6335kV出线设备Capacitance64主变压器设备MainTransformer6510kV出线设备OutLine10kV66站变设备StationTransformer67110kV分段设备Subsection110kV68直流屏设备DirectCurrentPanel69110kV进线间隔设备IncomingLineInterval110kV70双电源转换开关DualPowerSwitch71TV监控设备TVMonitoringDevice72母线保护设备BusbarProtection73光伏发电设备PhotovoltaicGenerator74柴油发电设备DieselGenerator75电动天窗电动天窗设备PowerSunroof76电梯及扶梯扶梯设备Escalator
总条数:879 到第
上滑加载中