• [技术干货] 容器化上云参考
    1:负载均衡应用改造点:选择合适的负载均衡器中小型的Web应用可以使用ngnix或HAProxy,大型网站或重要的服务可以使用LVS,目前该企业业务较小,选取nginx作为负载均衡器!2:web应用改造点:应用存在长时间执行请求   增加消息队列,通过消息队列将长任务与用户请求解耦3:应用服务器应用改造点:应用实例依赖于本地的存储来持久化数据如果是日志,建议变成流汇聚到分布式日志系统中。如果必须要使用存储,要使用共享文件系统如NFS。4:资源及集群规划规划:目前采用单集群规划,云资源中有其他应用项目请画出简要的资源规划图: 5:高可用规划   结合华为云,给出高可用规划的简单说明:    分别在2个AZ中部署两套CCE集群,K8S Master采用本地3节点高可用部署;应用AZ内高可用部署,通过ClusterIP服务调用不跨AZ。应用发布LoadBalancer类型的Service对接到集群所在AZ的融合ELB服务实例;应用通过VIP访问数据库,数据库自动切换应用不感知。支持多AZ动态容器存储,根据pod所在AZ创建数据卷。6:网络规划:集群内部应用默认可通过ClusterIP类型服务相互通信。k8s集群内置DNS服务,服务间访问可以通过IP或域名访问,请画出K8S集群内部应用网络互通示意图: Step1:kube-proxy、core-dns从Master中kube-apiserver订阅service,POD2的Service创建时,kube-proxy刷新本节点iptables,core-DNS更新路由数据。Step2:Pod2通过域名访问Pod4的service4,发起到core-dns查询请求,并获取对应的ClusterIP(如果使用ClusterIP直接访问则忽略这一步骤)Step3:Pod2发送业务报文,目的地址为获取到的ClusterIP。容器网络根据目的地址匹配策略后进行VxLAN封装,封装源地址为容器所在的VM IP地址,目的地址为目的容器所在VM IP,并将报文发给I层vSwitch,然后转发至目的容器所在VM,容器网络解VxLAN封装后,根据ClusterIP将业务报文发送目的service及POD。  
  • [大咖交流] 视频存储容器化
    一.存储容器化存储作为基础组件,直接和本地盘打交道,所以我们一个要解决的事情就是如果Kubernetes 管理本地盘。kubernetes管理本地盘通过官方提供的local-static-provisioner自动生成LocalPersistentVolume管理磁盘。LocalPersistentVolume是Kubernetes提供的一种管理本地盘的资源。5.1 使用Statefulset管理存储容器通过statefulset 管理有状态的存储服务, 为每个pod分配一个单独的磁盘可以使用volumeClaimTemplates给每个pod生成唯一的pvc,具体规则{podName},事先准备好PVC 和 PV,通过Statefulset 我们就可以把我们的存储托管到云上了。另外借助daemonset,可以把我们gateway模块部署到每一个node上面。处理云存储的请求。5.2 存储容器化的收益1)降低运维成本基于Kubernetes和statfulset获得了滚动更新,灰度更新,健康检查,快速扩容等功能,只需要一组yaml文件就可以快速搭建一个集群,相比于传统写ansible脚本部署的方式复杂度大大降低。2)降低开发运维成本由于Kubernetes把存储抽象成StorageClass PersistentVolume PersistentVolumeClaim。我们可以通过他们管理我们的存储资源,基于Kubernetes lable的过滤功能,可以实现简单的关系查询,通过PVC与PV管理存储资源,减少管理端的开发。定位问题也能通过POD信息快速定位到问题机器和问题云盘。而且接入Kubernetes生态上的prometheus后,监控告警也能快速开发。3)隔离性增强docker限制cpu memory使用,减少进程之间资源互相干扰,进一步提升资源利用率。在做流媒体容器化过程中,各个系统 Portal 平台、中间件、ops 基础设施、监控等都做了相应的适配改造,改造后的架构矩阵如下图所示。1. Portal:流媒体 的 PaaS 平台入口,提供 CI/CD 能力、资源管理、自助运维、应用画像、应用授权(db 授权、支付授权、应用间授权)等功能。2.运维工具:提供应用的可观测性工具, 包括 watcher(监控和报警)、bistoury (Java 应用在线 Debug)、qtrace(tracing 系统)、loki/elk(提供实时日志/离线日志查看)。中间件:应用用到的所有中间件,mq、配置中心、分布式调度系统 qschedule、dubbo 、mysql sdk 等。3.虚拟化集群:底层的 K8s 和 OpenStack 集群。4.Noah:测试环境管理平台,支持应用 KVM/容器混合部署。一.CI/CD 流程改造主要改造点:应用画像: 把应用相关的运行时配置、白名单配置、发布参数等收敛到一起,为容器发布提供统一的声明式配置。授权系统: 应用所有的授权操作都通过一个入口进行,并实现自动化的授权。K8s 多集群方案: 通过调研对比,KubeSphere 对运维优化、压测评估后也满足我们对性能的要求,最终我们选取了 KubeSphere 作为多集群方案。二.中间件适配改造改造关注点:由于容器化后,IP 经常变化是常态,所以各个公共组件和中间件要适配和接受这种变化。Qmq组件改造点:Broker端加快过期数据的处理速度。原因:由于IP变化频繁,对于一个主题有几百个甚至上千个的IP订阅,会产生很多文件Qconfig/Qschedule组件改造点:按实例级别的推送、任务执行在容器场景下不建议使用 。原因:因为IP经常变化,在容器化场景下发布、pod驱逐等都会导致IP变化,按实例维度推送没有意义Dubbo组件改造点:更改上线下线逻辑,下线记录由永久节点改为临时节点。 原因:上下线机制加上频繁的IP变更会导致zookeeper上产生大量的过期数据Openresty改造点:监听多K8s集群的endpoint变更,并更新到upstream; KVM、容器server地址共存,支持KVM和容器混合部署;三应用平滑迁移方案设计为了帮助业务快速平滑地迁移到容器,制定了一些规范和自动化测试验证等操作来实现这个目标。1.容器化的前置条件: 应用无状态、不存在 post_offline hook(服务下线后执行的脚本)、check_url 中不存在预热操作。2.测试环境验证: 自动升级 SDK、自动迁移。我们会在编译阶段帮助业务自动升级和更改 pom 文件来完成 SDK 的升级,并在测试环境部署和验证,如果升级失败会通知用户并提示。3.线上验证: 第一步线上发布,但不接线上流量,然后通过自动化测试验证,验证通过后接入线上流量。4.线上 KVM 与容器混部署:保险起见,线上的容器和 KVM 会同时在线一段时间,等验证期过后再逐步下线 KVM。5.线上全量发布: 确认服务没问题后,下线 KVM。6.观察: 观察一段时间,如果没有问题则回收 KVM。
  • [大咖交流] 什么业务适合做容器化
    1.轻量级的应用系统、丢失数据不敏感业务适合上容器化平台。几类应用比较适合容器化部署:一是功能单一的应用,即微服务(这也是为什么现在大家一谈到微服务就会谈到容器,一谈到容器就会谈到微服务的原因 );二是无状态的应用,容器的一个最大的优点就是可以快速创建(秒级),对于无状态的应用,可以通过快速横向扩容来提升并发处理能力;三是变更频繁的应用,容器是基于镜像创建的,对于变更频繁的应用,只要能保证镜像在测试环境测试没有问题,那么在生产环境上线由于环境差异导致出问题的概率就会少的多;四是对于需要在一个站点快速部署的应用组,对于需要在一个新站点快速部署的应用组,使用容器技术能够结合容器平台自身的特性,快速创建一个新的站点。2.重量级的中间件、oracle数据库、对数据持久化有强需求的应用、传统行业核心应用不适合容器化。使用容器部署应用,建议的上容器顺序如图所示:
  • [大咖交流] 企业容器化改造方案
    X企业容器化改造方案 【背景】A企业是一家位于杭州的软件开发公司,具备自主设计软件,交付软件及销售的能力,目前公司业务已经上华为云,考虑到开发及交付的便利性,准备进行容器化改,目标是能够实现软件开发即交付。业务现网状况如下:目前2台web服务器作为前端,mysql数据库,软件负载均衡器,无数据库中间件,后端EVS云硬盘,针对于本企业的现状,给出各部分的容器化改造及后续方案. 1:负载均衡应用改造点:选择合适的负载均衡器中小型的Web应用可以使用ngnix或HAProxy,大型网站或重要的服务可以使用LVS,目前该企业业务较小,选取nginx作为负载均衡器!2:web应用改造点:应用存在长时间执行请求   增加消息队列,通过消息队列将长任务与用户请求解耦3:应用服务器应用改造点:应用实例依赖于本地的存储来持久化数据如果是日志,建议变成流汇聚到分布式日志系统中。如果必须要使用存储,要使用共享文件系统如NFS4:资源及集群规划规划:目前采用单集群规划,云资源中有其他应用项目请画出简要的资源规划图: 5:高可用规划   结合华为云,给出高可用规划的简单说明:    分别在2个AZ中部署两套CCE集群,K8S Master采用本地3节点高可用部署;应用AZ内高可用部署,通过ClusterIP服务调用不跨AZ。应用发布LoadBalancer类型的Service对接到集群所在AZ的融合ELB服务实例;应用通过VIP访问数据库,数据库自动切换应用不感知。支持多AZ动态容器存储,根据pod所在AZ创建数据卷。6:网络规划:集群内部应用默认可通过ClusterIP类型服务相互通信。k8s集群内置DNS服务,服务间访问可以通过IP或域名访问,请画出K8S集群内部应用网络互通示意图: Step1:kube-proxy、core-dns从Master中kube-apiserver订阅service,POD2的Service创建时,kube-proxy刷新本节点iptables,core-DNS更新路由数据。Step2:Pod2通过域名访问Pod4的service4,发起到core-dns查询请求,并获取对应的ClusterIP(如果使用ClusterIP直接访问则忽略这一步骤)Step3:Pod2发送业务报文,目的地址为获取到的ClusterIP。容器网络根据目的地址匹配策略后进行VxLAN封装,封装源地址为容器所在的VM IP地址,目的地址为目的容器所在VM IP,并将报文发给I层vSwitch,然后转发至目的容器所在VM,容器网络解VxLAN封装后,根据ClusterIP将业务报文发送目的service及POD。
  • [大咖交流] 中小企业容器化改造建议
    中小企业容器化改造建议企业应用容器化改造,一般有以下三种方式:• 方式一:单体应用整体容器化,应用代码和架构不做任何改动。• 方式二:将应用中升级频繁,或对弹性伸缩要求高的组件拆分出来,将这部分组件容器化。• 方式三:将应用做全面的微服务架构改造,再单独容器化。对于中小企业而言,首次做容器化改造,建议选择方式一,主要优点有:• 业务0修改:应用架构和代码不需要做任何改动。• 提升部署和升级效率:应用可构建为容器镜像,确保应用环境一致性,提升部署效率。• 降低资源成本:Docker对系统资源利用率高。相比虚拟机技术,一个相同配置的主机,往往可以运行更多数量的应用。确定容器化改造方式后,企业就可以着手改造。以近期遇到的某中小企业改造为例。企业现状:该企业目前2台web服务器作为前端,mysql数据库,软件负载均衡器,无数据库中间件,后端EVS云硬盘。企业改造点:1、负载均衡应用改造点:选择合适的负载均衡器。一般中小型的Web应用可以使用ngnix或HAProxy,大型网站或重要的服务可以使用LVS,目前该企业业务规模较小,选取nginx作为负载均衡器;2、web应用改造点:应用存在长时间执行请求。增加消息队列,通过消息队列将长任务与用户请求解耦。3、应用服务器应用改造点:应用实例依赖于本地的存储来持久化数据。日志建议变成流汇聚到分布式日志系统中。如果必须要使用存储,要使用共享文件系统如NFS。4、资源及集群规划:目前采用单集群规划(假设云资源中有其他应用项目),给出示意图如下:5、 高可用规划• 分别在2个AZ中部署两套CCE集群,K8S Master采用本地3节点高可用部署。• 应用AZ内高可用部署,通过ClusterIP服务调用不跨AZ。• 应用发布LoadBalancer类型的Service对接到集群所在AZ的融合ELB服务实例。• 应用通过VIP访问数据库,数据库自动切换应用不感知。• 支持多AZ动态容器存储,根据pod所在AZ创建数据卷。6、 网络规划集群内部应用默认可通过ClusterIP类型服务相互通信。k8s集群内置DNS服务,服务间访问可以通过IP或域名访问。K8S内部应用网络互通示意图如下:Step1:kube-proxy、core-dns从Master中kube-apiserver订阅service,POD2的Service创建时,kube-proxy刷新本节点iptables,core-DNS更新路由数据。Step2:Pod2通过域名访问Pod4的service4,发起到core-dns查询请求,并获取对应的ClusterIP(如果使用ClusterIP直接访问则忽略这一步骤)Step3:Pod2发送业务报文,目的地址为获取到的ClusterIP。容器网络根据目的地址匹配策略后进行VxLAN封装,封装源地址为容器所在的VM IP地址,目的地址为目的容器所在VM IP,并将报文发给I层vSwitch,然后转发至目的容器所在VM,容器网络解VxLAN封装后,根据ClusterIP将业务报文发送目的service及POD。
  • [大咖交流] 企业容器化改造方案
                         X企业容器化改造方案 【背景】A企业是一家位于杭州的软件开发公司,具备自主设计软件,交付软件及销售的能力,目前公司业务已经上华为云,考虑到开发及交付的便利性,准备进行容器化改,目标是能够实现软件开发即交付。业务现网状况如下:目前2台web服务器作为前端,mysql数据库,软件负载均衡器,无数据库中间件,后端EVS云硬盘,针对于本企业的现状,给出各部分的容器化改造及后续方案.1:负载均衡应用改造点:选择合适的负载均衡器中小型的Web应用可以使用ngnix或HAProxy,大型网站或重要的服务可以使用LVS,目前该企业业务较小,选取nginx作为负载均衡器!2:web应用改造点:应用存在长时间执行请求   增加消息队列,通过消息队列将长任务与用户请求解耦3:应用服务器应用改造点:应用实例依赖于本地的存储来持久化数据如果是日志,建议变成流汇聚到分布式日志系统中。如果必须要使用存储,要使用共享文件系统如NFS。4:资源及集群规划规划:目前采用单集群规划,云资源中有其他应用项目请画出简要的资源规划图:5:高可用规划   结合华为云,给出高可用规划的简单说明:    分别在2个AZ中部署两套CCE集群,K8S Master采用本地3节点高可用部署;应用AZ内高可用部署,通过ClusterIP服务调用不跨AZ。应用发布LoadBalancer类型的Service对接到集群所在AZ的融合ELB服务实例;应用通过VIP访问数据库,数据库自动切换应用不感知。支持多AZ动态容器存储,根据pod所在AZ创建数据卷。6:网络规划:集群内部应用默认可通过ClusterIP类型服务相互通信。k8s集群内置DNS服务,服务间访问可以通过IP或域名访问,请画出K8S集群内部应用网络互通示意图:Step1:kube-proxy、core-dns从Master中kube-apiserver订阅service,POD2的Service创建时,kube-proxy刷新本节点iptables,core-DNS更新路由数据。Step2:Pod2通过域名访问Pod4的service4,发起到core-dns查询请求,并获取对应的ClusterIP(如果使用ClusterIP直接访问则忽略这一步骤)Step3:Pod2发送业务报文,目的地址为获取到的ClusterIP。容器网络根据目的地址匹配策略后进行VxLAN封装,封装源地址为容器所在的VM IP地址,目的地址为目的容器所在VM IP,并将报文发给I层vSwitch,然后转发至目的容器所在VM,容器网络解VxLAN封装后,根据ClusterIP将业务报文发送目的service及POD。   
  • [干货汇总] Docker容器:将带UI的程序直接转为Web应用,so easy
    >摘要:使用Docker容器,将带UI的程序,直接转换为Web应用。很方便,跟大家分享一下。 本文分享自华为云社区《[使用Docker容器,将带UI的程序,直接转为Web应用](https://bbs.huaweicloud.com/blogs/355359?utm_source=csdn&utm_medium=bbs-ex&utm_campaign=other&utm_content=content)》,作者:tsjsdbd。 我们可以通过Docker容器,将App的UI界面,投射到任意的网络目的端。 即: ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/2/1654132780202343224.png) 其原理是利用X11协议,把界面投射转化为网络协议,到达目的端显示出来。 但是这种方案,有一个硬性要求:就是目的端必须要安装一个“投屏软件(X11 Server)”,比如:VcXsrv 或者 MobaXterm。 那么用户想要看到App的界面,他就得额外安装一个软件,用户体验并不是最佳的。 # 一、VNC方案 Windows的远程桌面,相信大家都用过吧。 VNC就是Linux版的远程桌面。它可以将屏幕,通过网络共享给客户端。 在服务端,安装vncserver。 在客户端,安装vncviewer。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/2/1654132793968614741.png) 不过,windows是自带了一个 远程桌面客户端。对VNC的话,用户就得安装一个 vnc-viewer客户端。和X11方案差不多,还是不够方便。 # 二、noVNC方案 好消息是,VNC-Viewer有一个WEB版的客户端,叫做 noVNC。它直接打开网页,就获得VNC-Viewer能力。详见:https://novnc.com/info.html 于是,我们可以将方案拓展为: ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/2/1654132807363446276.png) 毕竟,浏览器基本上每个客户都会有。这就好比,微信大家都有,所以“单独安装一个App”vs“微信小程序” ,肯定是后者在使用更便捷一样的道理。 所以你可以看到各大云厂商,比如华为云的ECS虚机,也都自带了使用noVNC的方式来展示虚机的界面。可见noVNC的产品化可靠性还是OK的。 # 三、具体操作 这里我为了方便,准备将各种Server都安装到一个Docker容器里面,如下: ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/2/1654132825636861204.png) ## 1. 使用 Ubuntu:20.04 的基础镜像 因为最终我们要通过HTML访问这个容器,所以启动的时候,我们得记得开放端口: ``` docker run -it -p 80:8080 ubuntu:20.04 /bin/bash ``` 在这个容器里面,启动上图中的各种Server。 ## 2. Xvfb虚拟屏幕 首先,安装一个叫做 xvfb 的软件。这是一个“虚拟屏幕”,都在内存中模拟的屏幕。见:https://en.wikipedia.org/wiki/Xvfb 安装: ``` apt-get install -y xvfb ``` 然后启动“虚拟屏幕”: ``` Xvfb :0 -screen 0 1920x1080x24 -listen tcp -ac +extension GLX +extension RENDER ``` 其中,1920x1080x24 表示:屏幕大小(分辨率)。 24则是像素深度。 这个屏幕大小,到时候可以根据App的界面效果自己调整。 ## 3. X11vnc服务器 然后,我们安装 x11服务器(因为安装这个有交互,所以之类设置了 无交互模式) ``` export DEBIAN_FRONTEND=noninteractive apt-get install -y x11vnc ``` 然后启动 x11服务器: ``` x11vnc -forever -shared -noipv6 -passwd tsjsdbd ``` 其中标红的password换成你自己喜欢的密码。 ## 4. noVNC服务器 最后,我们通过noVNC服务器,将 VNC翻译为HTML服务, 安装: ``` apt-get install -y novnc ``` 然后启动: ``` websockify --web /usr/share/novnc 8080 localhost:5900 ``` ## 5. 启动带UI的App ``` apt-get install x11-apps DISPLAY=:0.0 xclock ``` 这里的DISPLAY变量的作用,是表示把App的界面,投射到咱们的这个“虚拟屏幕”上。 详细请看我之前的那篇文章。 ## 6. 从浏览器访问 从浏览器,访问我们的容器。地址(因为我们启动容器用来http默认端口80,所以这里URL不用设置端口了。): http://容器ip/vnc.html ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/2/1654133028850496244.png) 这里填,第3步咱设置的密码。然后可以看到App的界面啦: ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/2/1654133039587406619.png) # 四、Dockerfile 这里为了大家方便,直接提供一个Dockerfile ``` FROM ubuntu:20.04 ENV DEBIAN_FRONTEND=noninteractive RUN apt-get install -y novnc x11vnc xvfb EXPOSE 8080 ENTRYPOINT ["/bin/bash"] ``` 然后写个 start-novnc.sh 脚本: ``` #!/bin/bash set -e #虚拟屏幕 Xvfb :0 -screen 0 1920x1080x24 -listen tcp -ac +extension GLX +extension RENDER > /dev/null 2>&1 & #vnc服务器 x11vnc -forever -shared -noipv6 -passwd tsjsdbd > /dev/null 2>&1 & #novnc websockify --web /usr/share/novnc 8080 localhost:5900 > /dev/null 2>&1 & ``` 最后你启动app的时候,记得带上: ``` DISPLAY==========================================BN =:0.0 your-ui-app ``` 就可以了。
  • [认证交流] 华为云云原生入门级开发者认证学习笔记——第四章
    第四章:华为云容器服务介绍 学习笔记• 华为云容器全栈服务介绍华为云容器全栈服务一览特点:易使用、易运维、高性能• 云容器引擎CCE1. 基于开源Kubernetes、Docker技术的企业级容器服务。2. 借助云容器引擎,用户可以在华为云上轻松部署、管理和扩展容器化应用程序。3. CCE与Kubernetes关系CCE集群:丰富异构、高性能、安全、统一调度的容器基础设施产品。4. CCE产品架构图A、 丰富的异构算力支持:全面支持华为云各类计算实例、支持存量实例纳管;B、 高性能云原生网络:Overlay模式下网络性能较开源Flannel方案提升30%、Underlay模式下网络性能较直连损耗在55之内;C、 全面安全的云原生能力:安全加固的容器运行时,有效屏蔽各类开源漏洞、容器镜像多种策略扫描、有效识别镜像中风险D、 统一的大规模云原生调度:单集群最大支持1万节点,自研Volcano调度效率较开源调度方案提升30%• CCE使用方式可通过CCE控制台(推荐)、Kubelctl命令行、Kubernetes API使用云容器引擎服务• CCE使用流程CCE集群:标准集群,提供商用级集群服务Turbo集群:面向云原生2.0、大规模、高性能的场景做了计算、网络和调度的全面加速的集群鲲鹏集群:计算架构基于鲲鹏架构• CCE关键特性总览• 集群管理:可一键创建集群,支持多种异构基础设置• 节点\节点池管理节点:节点是容器集群组成的基本元素,取决于业务、既可以是虚拟机、也可以是物理机。节点池管理:节点池中有多个节点,节点参数配置相同,可通过设置节点模板创建节点,通过节点池功能方便实现节点动态扩缩容。• 工作负载:Deployment、Statefulset、Daemonset、Job、CronJob等类型。云容器引擎CCE提供基于Kubernetes原生类型的容器部署和管理能力,支持容器工作负载部署、配置、监控、扩容、升级、卸载、服务发现以及负载均衡等生命周期管理。根据不同工作负载的特点,CCE可提供不同的能力以保证其正常运转。• 亲和/反亲和调度A、 工作负载和可用区的亲和性:基于可用区可设置多条调度策略,只需满足其中一条就会进行调度B、 工作负载和节点的亲和性:基于节点可以设置多条调度策略,只需满足其中一条就会进行调度C、 工作负载间的亲和性:基于工作负载可以设置多条调度策略,但多条策略中设置的标签必须同时出现在一个工作负载中• 容器网络• 持久化卷存储CCE除支持本地磁盘存储外,还支持将工作负载数据存储在华为云的云存储上,当前支持云存储包括四点:本地磁盘存储云硬盘存储文件存储卷对象存储卷• 弹性伸缩根据业务需求和策略自动调整资源使用策略工作负载伸缩:HPA策略,实现Pod水平自动伸缩功能CustomedHPA:华为云自研的弹性伸缩增强能力,能基于CPU利用率、内存利用率等指标对无状态负载进行弹性扩缩容。节点伸缩:通过节点自动伸缩组件autoscaler实现,根据pod调度状态及资源使用情况对集群的节点进行自动扩缩容。• CCE使用场景• 云容器实例CCI1. 云容器实例:只需要管理运行在Kubernetes上的容器化业务,无需管理集群和服务器即可在CCI上快速创建和运行容器负载。2. CCI和CCE的差别计费模式不同、使用场景不同、资源创建不同3. CCI的使用流程4. CCI关键特性:智能调度:CCI天然支持Volcano异构容器:充分利用华为云底层异构资源,满足业务场景安全容器:每个容器/pod都运行在单独的ECS中,安全性高秒级计费:根据实际使用资源量,按需秒级计费。5. CCI应用场景:AI计算、高性能容器批量处理(Job类任务)、长稳及扩容流量处理• SWR:容器镜像服务1. SWR基本概念—仓库:集中存放镜像的空间。仓库分为公共仓库和私有仓库2. SWR基本概念—容器镜像:镜像,是多个二进制只读层的集合。3. SWR基本概念—组织:组织用于隔离镜像仓库,便于仓库和镜像的管理4. SWR的使用流程:创建组织→镜像获取→应用部署→更新镜像5. SWR镜像管理—上传镜像:客户端上传镜像(客户端版本必须为1.1/1.2以上,镜像每个layer不能超过10G)/页面上传镜像(每次最多上传10个文件,单文件大小不超过2G)6. SWR镜像管理—编辑镜像属性:包括镜像的类型、分类和描述信息7. SWR镜像管理—共享私有镜像:只有账号所有者或具备该私有镜像管理权限的IAM用户才能进行分享8. SWR镜像管理—添加触发器:实现镜像版本更新时,自动更新使用该镜像的应用。可全部触发、指定版本号触发或正则触发9. SWR镜像管理—镜像老化规则:可从存活时间和版本数目两个规则进行设置10. SWR镜像管理—自动同步镜像11. SWR镜像管理—镜像安全扫描:一键对镜像进行安全扫描,确保所用镜像安全12. SWR镜像管理—设置镜像加速器:解决公有镜像因为网络原因导致下载速度慢或下载失败的问题
  • [知识分享] 解构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) } } } ```
总条数:888 到第
上滑加载中