• [容器专区] 【开放性】当主站ip地址与容器网桥地址同网段时处理配置方法
    问题背景:当前使用AR-CORE融合终端(版本:R20C00SPC100)在陕西送检时反馈,业务主站ip地址为192.168.100.11/24,设备ip地址配置为192.168.100.222/16,容器IP地址192.168.100.2,因同网段导致pc无法登陆设备及容器;解决方案:1、将GE0帮到br0网桥下:命令行如下ip link set dev GE0 master br0,缺点:不能将LTE0绑到br0网桥下,导致现网不能使用;2、配置对应接口的明细路由,命令行:ip route add 192.168.100.11/32 dev GE0,将主站ip地址作为明细地址,此时在pc端可以ssh登录设备,但还无法登录容器,此时需要再添加一条指令:ip link set dev br0 proxy,此时可以通过nft配置的端口号登录容器,LTE同理(ip route add 192.168.100.11/32 dev LTE0;ip link set dev br0 proxy)。以上方案二选一即可,不可同时使用。ps:存在以太口和LTE同时配置后设备需要切换的场景,具体逻辑如下:以太网、4G同时在线,是可以配两条指向同样主站ip的路由的,配路由的时候在命令后面加metric参数可以指定优先级,metric越低优先级越高,配FE口的路由metric比LTE口低就行;配置如下:ip route add 192.168.100.11/32 dev GE0 metric 100ip route add 192.168.100.11/32 dev LTE0 metric 120
  • [技术干货] 一个合格的CloudNative应用:程序当开源软件编写,应用配置外置(1)
    作者名:关耳山石作者博客链接:https://bbs.huaweicloud.com/community/usersnew/id_1593343710234702 摘要:对于一个合格的CloudNative应用,应该把自己的程序当做开源软件来编写的,不该将数据库连接信息和密码放在代码里,一定要将配置外置。对于一个合格的CloudNative应用,应该把自己的程序当做开源软件来编写的,不该将数据库连接信息和密码放在代码里,一定要将配置外置。因此我试着在华为云上落地这套标准,期间尝试了从ServiceStage、CCE、CSE这三个入口进行配置注入,最终实现能够在应用启动时,主动拉取配置,覆盖本地配置文件里的调试配置,并能够在线配置并生效。打法是:CCE配置启动参数,制定SpringProfiles;配合CSE做应用配置,将资源外置后的配置记录于此,并可以动态更新,最终实现了配置外置的诉求。另外,通过这次增加的多版本管理,尝试梳理了一下ServiceStage的组件、CCE的workload、CSE的应用和微服务之间,错综复杂的概念之间的关系,个人浅见,欢迎指正:1. 初始化配置在系统初始化的时候,不可能一点配置都没有,所以保留一些基础配置在配置文件里是有必要的。配置外置并不意味着100%的配置都要外置,而是把外部依赖资源的配置,特别是容易变化配置外置。1.1 启用Bootstrap和Spring profile在代码层面,首先要进行基础配置。先看代码结构,这里除了最基本的application.yaml,增加了bootstrap.yaml和*-dev.yml等带后缀的文件。介绍一下原理:首先介绍Bootstrap Application Context:它是Spring Cloud Context的父Context,所以从外部配置源里加载配置一般从这里来,且优先级高于其他一切配置文件。于是,我们也利用这个能力,借助CSE的微服务配置中心能力,进行Spring的外部参数写入。然后介绍Spring profiles:为了把通用配置和环境相关的配置区分开,比如DEV环境没有AK/SK认证,而线上环境都有认证,这种配置项上的区别,引入了Spring profiles的概念,当Springboot启动的时候,会根据profiles.active参数判断应该启用那个环境配置PS:参考SpringCloud官方解释另外,就是哪些配置应该放在配置文件里,理论上除了最基础的配置,在启动时使用的,其余的配置都可以放在CSE的微服务配置中心里,而不必在本地配置文件里存在,另外就是本地配置里存在的,也可以通过二次设置在微服务的配置中心里,进行覆盖,比如数据库连接池的大小,而不需要修改代码,至于改完以后,要不要重启,那就得看生效的逻辑了。1.2 引入CSE配置中心CSE配置中心引入,需要先引入依赖包,然后在bootstrap.yaml中配置CSE配置中心的地址、认证信息等。这里可以参考官方文档,主要关注bootstrap.yaml的配置参数:使用分布式配置中心补充:获取spring-cloud-starter-huawei-config的版本参考地址:huaweicloud/spring-cloud-huawei可以参考现有的SpringCloud基线版本,选择SpringCloud-Huawei的版本补充:关于配置中心的优先级微服务引擎提供了分层次的配置机制。按照优先级从高到低,分为:配置中心(动态配置)Java System Property(-D参数)环境变量配置文件参考官方文档:配置微服务2. 本地CSE配置中心能力验证前提条件,本地得安装一个Local-CSE并启动,这部分参考云上DevOps:2.1-本地环境准备2.1 配置application.yaml和bootstrap.yml原始文件可以参考Github的Demo,配置文件入口,我这里进行了修改,因为bootstrap.yaml优先级高于application.yaml,参数只要在bootstrap.yaml中出现过,就不会使用application.yaml中的配置了。上代码,application.yaml,可以看到配置很少,因为大部分bootstrap.yml中已经包含,就都去掉了这是bootstrap.yml,注意这里的spring.application.name、spring.cloud.servicecomb.discovery.appName和spring.cloud.servicecomb.discovery.version会组成一个微服务私有的参数作用域,这里的优先级高于全局作用域application。特别注意,云上的CSE环境,除了上面提到的,还需要增加server.env参数。另外,server.env有四个参数可以选development、testing、acceptance、production关于如上参数的定义,参考官方文档:使用分布式注册中心和官方文档:使用分布式配置中心。2.2 准备验证代码直接上代码2.3 静态配置能力为了验证CSE配置中心的参数,是否能覆盖application.yaml中的参数配置,我选了一个很特别的参数:spring.datasource.password,如果能够覆盖成功,那么启动后,创建数据库连接池一定会报错。首先,打开本地CSE配置中心,地址为:http://localhost:30106/#/cse/services/config,创建一个配置项,作用域选VodMgrService@CabgOne#1.0.0,关于application的作用域后面再解释。重启本地微服务,启动后创建数据库连接池就报错了,符合预期。结论:CSE配置中心的参数,能够覆盖application.yaml中的参数配置2.4 动态配置能力为了验证CSE配置中心的参数动态生效,需要使用注解@RefreshScope,同时也引入ConfigRefreshEvent来监听事件变化,这样就会得到一个效果,对于动态生效的参数,可能需要一些重建或刷新,比如连接池、缓存、Client等。首先,增加一个配置项config.value然后很快可以看到后台日志打印出来,包括自己的监听器,也响应了日志查看一下数据,已经响应为TryMe具体的配置,在后台是轮询的,响应周期配置参数为cloud.servicecomb.config.watch.delay,目前是10秒一次修改一下配置,为TryMeAgain
  • [维护宝典] Kafka生产发送数据失败
                    我们使用kafka时,有时候会遇到发送数据失败的情况,其原因及解决方案如下:1.     Kafka topic leader为-1Kafka客户端执行如下命令查看topic的leader信息:kafka-topics.sh --describe --zookeeper zk业务IP:24002/kafka如果leader为-1,需查看Replicas中的副本节点是否正常,查看命令如下:kafka-broker-info.sh --zookeeper zk业务IP:24002/kafka命令中可以查询到brokerid,说明节点kafka服务正常如果leader为-1的分区对应的Replicas中节点都不正常,需要先恢复异常节点kafka服务。如果都正常但ISR列表中无节点信息,或者ISR列表中的节点不正常,需要查看Kafka服务端的unclean.leader.election.enable参数是否为true或者topic端是否配置此参数为true。如果都不为true,需要对此topic修改配置为true。Kafka服务端的unclean.leader.election.enable参数配置查看方式如下:                                             Kafka topic端unclean.leader.election.enable参数配置查看方式如下:kafka-topics.sh --describe --zookeeper zk业务IP:24002/kafka --topic topicName如果Config中无unclean.leader.election.enable信息,则与服务端配置一致。如果有,则此配置优先级高于服务端配置。修改topic端此配置的方式如下:kafka-topics.sh --alter --topic topicName --zookeeper zk业务IP:24002/kafka --config unclean.leader.election.enable=true2.     DNS配置导致执行 vi /etc/resolv.conf,如果有“nameserver X.X.X.X”,把此内容注释掉3.     网络异常生产端节点ping服务端IP,ping -s 15000 IP,如果延迟高于5ms,说明网络延迟过高,也可通过长ping来判断是否有网络丢包。4.     CPU或者IO过高也可能导致连接失败iostat -d -x 1查看CPU参数idle和IO参数util,idle值越高,CPU越空闲,util值越高,IO使用率越高。如果idle值小于20%,top -Hp kafkaPid查看CPU使用率高的线程,打jstack日志分析具体的原因;如果util值大于80%,查看磁盘对应的读写速率、await和svctm的大小判断对IO影响大的原因,如果读写速率比较大,排查kafka读写请求和延时,如果awati远大于svctm,IO队列太长,应用响应时间很慢。5.     磁盘坏道或者其他原因也可能导致连接失败如果server.log日志中有大量“java.io.IOException: Connection to IP:21007 (id: 2 rack: null) failed”日志,查看IP节点操作系统日志中是否有“Sense Key : Medium Error”信息,如果有,说明出现磁盘坏道,需修复或更换磁盘。另外,还需要打此节点的jstack信息,排查是否有阻塞或者死锁。如果是C80版本,且jstack信息中有如下信息,需打死锁补丁:6.     如果报“TimeoutException”或偶尔发送失败,可先调大request.timeout.ms,并查看服务端num.io.threads和num.network.threads是否可以优化(这两个参数一般调整为节点磁盘个数的倍数)。根据发送的数据量的大小也可适当调整batch.size、buffer.memory、linger.ms的大小。如果发送的数据量很大且可容忍一定时延,也可以考虑开启压缩,compression.type指定压缩方式,可配置为“gzip”、“snappy”或“lz4”。7.     ssh卡住ssh -v -p 端口号 异常节点ip如果如上图所示卡住,解决方式是将GSSAPIAuthentication修改为no8.     如果是集群外客户端生产发送失败,还可以通过集群内客户端测试下生产是否成功,进一步减小排查方向。
  • [热门活动] 如何选到一款标准、安全、高可用并具丰富功能的企业级应用服务器?
    TongWeb应用服务器是一款标准、安全、高可用并具丰富功能的企业级应用服务器,为企业级应用提供了便捷的开发、随需应变的灵活部署、丰富的运行时监视、高效的易管理等关键支撑。产品两大主要功能:1,提供应用中文容错性、多框架兼容性、动态加载、多样性配置管理、系统运行状态多方面分析、集群管控、应用性能监控等能力,操作简约容易。2,提供应用运行的基础框架,包括但不限于容器、线程、日志、接口、安全、监控、界面、配置参数、优化等功能实现。TongWeb应用服务器提供了各种容器和功能组件,包括Web容器、EJB容器、RMI服务容器、Web服务平台、JCA服务、数据库连接池、事务控制组件等,并支持各种成熟开发框架,以帮助企业快速构建各种业务应用处理系统,为企业级信息化建设构建基础应用平台。 TongWeb可以通过使用集群功能实现负载均衡和备份,以增强应用的健壮性和稳定性。同时通过动态扩展的功能实现集群部署的动态管理。TongWeb应用服务器的集群功能提供跨多种平台服务器的集群部署配置以及故障切换,从而快速适应企业现有软硬件环境并可确保关键应用和服务高效可用。 产品还提供多种方式以提高企业级应用的安全性,从而限制对应用的访问,保障企业数据的安全,防止恶意攻击。通过TongWeb应用服务器提供的监控管理工具对服务的运行情况进行实时跟踪监控,并提供大量方便的日志管理功能以便用户进行审计。文中提到的的商品链接:东方通应用服务器软件(TongWeb)【华为云云市场,助您无忧上云】
  • [技术干货] 【DevOps职业认证训练营FAQ】DevOps&敏捷8大领域60个精彩问答
    “DevOps的价值是又快又好地交付软件”——《凤凰项目》的作者Gene Kim和《持续交付》的作者JezHumble当前数字化转型的形势下,软件行业面临着巨大的市场机遇,而软件系统复杂度不断增加,跨地域高效协作、多环境部署等问题也逐渐突出,DevOps能帮助企业提升软件研发效率,通过自动化“软件交付”和“架构变更”的流程,来使得构建、测试、发布软件能够更加快捷、频繁和可靠。基于此,我们策划组织了2期【DevOps职业认证训练营】,并邀请到姚冬、卜汉东两位专家老师全程陪伴学习与答疑。在整理问答的过程中我们发现,学员提出的问题覆盖了规划设计、开发集成、测试、部署发布、运维监控等DevOps落地实践中的关键疑点与难点。本文从中挑选整理了60个精华问答,希望通过这些问题与解析,帮助更多DevOps实践者解决DevOps落地过程中的疑惑与痛点。(文末可下载大纲模式的pdf文档方便浏览)【一、华为端到端DevOps概览】Q1:华为端到端的DevOps工具链是如何承载敏捷和DevOps相关理念和方法的?A:敏捷和DevOps的理念其实是相通的,DevOps可以视作敏捷的延伸,敏捷思想打破了需求与开发之间的壁垒,DevOps则通过将开发与运维间的壁垒打破,打通软件交付全流程。华为云DevOps工具链DevCloud包含了从需求管理到代码托管、构建部署、测试等一系列步骤,覆盖软件开发全生命周期。理念往往需要结合实践,我们可以通过DevCloud进行需求管理、每日站会等等许多敏捷实践,通过提交代码可以触发执行流水线,让开发人员专注开发。Q2:华为云DevCloud与传统基于开源组件拼接的工具链,有什么差异优势?A:传统的由开源组件拼接而成的工具链,大部分都是使用Jira来进行需求管理、用Git来做代码托管、用Jenkins做DevOps开发,因为其组件大部分都是开源的,所以一般费用较低或者免费,其缺点是使用者需要掌握很多工具,而且这些工具并不是在同一个平台上。华为云DevCloud是一站式的软件开发平台,可以做到所有工具都在一个平台上,端到端打通覆盖整个软件开发全生命周期。用Jenkins的人都知道,在使用之前首先需要搭建一套Jenkins的环境,还需要定制化地做一些脚本、配置等,华为云DevCloud相当于是一个已经封装好了的DevOps开发工具,可以极大减少这些操作。在华为云DevCloud里,将编译构建、部署任务等做成了原子化的操作,如果我们想要做Tomcat部署,可以直接使用这些模板,只需要对里面的步骤进行细微的调整即可。而且它还使用了可视化视图,操作起来一目了然,学习成本也比较低。华为云DevCloud还支持代码检查、自定义shell、Python、脚本、自定义report展示。Q3:DevOps /敏捷和SDLC 有何不同?A:DevOps/敏捷和SDLC的角度不一样。SDLC是指系统生命周期,它提出的几种典型生命周期模型包括瀑布模型、快速原型模型、迭代模型。敏捷打破了需求和开发之间的沟通壁垒,DevOps则打通了整个软件交付的全流程。Q4:DevOps人员在与项目的结合中是否会承担更多开发、测试、运维的工作?A:DevOps不会让人去承担更多开发、测试、运维的工作。DevOps里有一个理念:让开发的人专注于开发、测试的人专注于测试、运维的人专注于运维,所有的工具层面的东西全部交给工具,只要把一切可自动化的东西自动化,所有的人忙自己手头的工作就好了。Q5:DevOps的反模式有哪些?A:参考《9种DevOps团队结构适用类型与7种反型》 Q6:DevOps适合哪些行业的业务模式?对于非软件行业是否需要调整模式?A:DevOps也好,敏捷也好,其初衷和理念适用于所有行业,但是每个行业在执行和实际落地效果上会有一些折扣,比如持续交付的生产环境、自动化部署、质量管控、自动化流转等过程的实现等。简单而言,互联网的一些应用,或者说SaaS应用,相对来说更适合DevOps的研发模式。原因是:其业务对软件更新、发布的要求较高;没有太大的历史包袱;相对更容易对标目标受众群体,包括生产环境等。传统类的业务比较重,比如银行的核心系统,实践起来相对较难,也不是说不能用敏捷或DevOps。比如持续集成、每天多次构建、多次提交代码、自动化测试、可视化等,都可以实行。对于非软件行业,如硬件、嵌入式、机械类,实践起来也比较难,比如测试自动化等,需要做一些工具或平台的适配,引进插件或工具后,流程也能够跑起来,只是会慢一些。综上,我认为敏捷和DevOps本身是一条没有终点的路,所有行业都可以到这条路上来,只是走得难易与远近的问题。Q7:在企业落地DevOps有没有什么套路?A:企业实际情况各不相同,落地DevOps没有统一的套路,但会有一些建议的方式。DevOps偏工程侧,通常建议先把版本管理建立起来,比如Git代码仓、代码分支管理等;接下来需要把流水线构建起来,在上面逐渐进行自动化测试、分层测试等。Q8:最能有效促进Scrum团队本身的持续改进的是什么实践?A:每个团队遇到的问题都是不一样的,如果一定要找一个通用的答案,首先要保证团队每日站会、评审会议等如质如期进行,以此来保持持续改进。 【二、持续规划与设计】Q9:基于DevOps实现持续有效规划应该先从哪个层面去入手呢?A:首先需要理解DevOps和敏捷的含义,我们一般说的规划与设计更偏向于敏捷项目管理中涵盖的需求和计划。狭义的DevOps主要是CI/CD,即持续集成和持续部署,是偏工程侧的。广义的DevOps,即本训练营中讲的DevOps是“端到端的DevOps”,从持续集成/持续部署,向前延伸到业务侧,向后延伸到运维/运营侧,因此也涵盖了前段的需求和设计层面。回到问题,基于DevOps实现持续有效规划,应该从需求和计划切入,包括整个的市场分析、目标客户群体的用户画像,用户的痛点是什么,针对这些痛点提供什么样的功能,然后到产品应该怎么设计,接下来才真正落到研发这个主体上。从方法论角度来看,需求和设计层面的方法论包括设计思维、精益创业等。做好需求分析后,就要进行需求拆分,排列优先级,这样就进到敏捷项目计划里,方法论包括看板、Scrum等,大规模团队敏捷框架有SAFe等。Q10:Scrum,看板和 XP 是敏捷开发的具体方式,老师能否具体讲解一下区别?A:参考文章《DevOps VS 敏捷:傻傻分不清楚》。Scrum和看板更侧重在团队级敏捷项目管理层面,XP更偏向于工程实践层面。Scrum和看板两者比较:“标准的”Scrum包括3355的框架;看板源自丰田的精益生产,其背后是精益的思想,通过可视化、限制在制品的数量,快速暴露问题和瓶颈点,集中对最严重的瓶颈点进行修复,然后去寻找下一个瓶颈点。DevOps的很多理念同样借鉴了精益的思想,个人认为,看板可以应用到很多领域。另外,Scrum和看板在实施或应用时并没有冲突,可以结合起来使用。 Q11:企业组织架构中什么角色或者部分适合推行DevOps落地?A:企业组织架构中一般都没有专门的组织来推行和落地DevOps。DevOps包括两个部分“Dev”和“Ops”,就是指开发部门和运维部门。几种常见的情况:如果是由开发部门来发起DevOps落地,就是由开发往运维去推进。我们平时看到比较多的是测试团队或传统的质量管理部门来发起,从开发到测试再往前一步到运维生产环境上去,因为这些部门本身就承担着代码托管、编译构建、自动化测试等职能。而有的公司会把内部的基础设施、IT支撑、测试等放在数据中心,往前去推把自己变成类似我们讲的DevOps工程师,然后通过自动化工具帮助开发团队进行自动化部署等,这就是从运维侧往前推进DevOps落地。还有一种情况,就是近年来比较火的云原生,架构师更多考虑采用微服务架构,通过基础设施即代码等方式自动化部署到Docker环境中去,因此引入自动化流水线、Infrastructure as Code(基础设施即代码)、接口测试等实践,这些都属于DevOps的范畴。还有一些其他的角色,比如敏捷教练、内部的技术教练等,他们本身就是在做研发管理的落地实践,很自然地转化去做DevOps推进。综上,DevOps的推进和落地不一定非要有一个DevOps工程师或独立的DevOps团队,初期引入DevOps的时候需要有一个团队或角色去承担起这个职责,进行概念和实践的导入和探索,这时更容易把DevOps工程师、DevOps团队建立起来。而后期应该把这些工程师或能力分散到各个团队中去,让DevOps在企业内有更广泛的传播和实践。Q12:请问在Scrum中,如果没有项目经理,是由TeamLeader还是ScrumMaster协调资源?A:应该由TeamLeader来协调资源,ScrumMaster不是管理角色,而更多的是一个辅助的牧羊犬的角色,在Scrum实施过程中守护团队Scrum流程不受干扰。Q13:对于非产品形态的项目,Product Owner来自哪个部门更合适?(业务部门/研发部门)A:Product Owner代表客户,一般是哪个部门更接近业务,更了解业务和系统,就由这个部门的人来担任。非产品形态项目的Product Owner,要求既了解业务又懂技术,一般可以由业务分析师、PMO等角色担任。Q14:实际开发中,客户往往无人承担PO的角色,而是领导来承担,如何破解这个问题?A:这种情况可称为“BDD”,Boss-Driven Development,老板驱动开发。好处是至少有一个人能拍板;坏处是拍板的人,你可能很难去辩驳或谈判,所以最好还是能够把客户侧的人拉进来。当然,如果老板确实对业务非常了解,也非常专业,并且是一个可沟通的人,也是可以的。PO的核心要求是需要有一个人代表客户或业务侧,针对需求或范围做决定,且当团队有问题的时候,可以随时找到这个人。Q15:影响地图主要应用于哪个环节?A:从HE2E DevOps实施框架图可以看到,在端到端的DevOps实践中,影响地图通常用于需求规划或业务规划阶段,与传统的Scrum流程相比,更偏业务侧。影响地图通过四层结构:why、who、how、what来拆解业务和需求,也可以用于运营或项目冷启动环节。Q16:请问如果一个大的Story拆分成多个小的Story,甚至再次拆分成孙子辈的Story,如何更好地表示这些关联关系?A:Story拆分有两种方式:一种是从epic(史诗故事)到feature到story的拆分,epic以月为单位,feature以周为单位,story以天为单位;另一种是平级拆分,所有拆分的故事全部叫story,只不过它们之间存在父子关系。不管是三层还是四层,我们只关注父子关系,从一个父story拆分出子story,如果粒度不够小,则以子story为父story继续拆分出它的子story。如果系统需要有层级追溯,可以用树状或脑图等结构来展现。Q17:学完课程感觉用户故事和项目管理里的工作包很像,二者有个共同的问题,拆解到什么粒度是好的用户故事?A:故事也好,需求也好,只是一个名字,用户故事之所以叫用户故事,有两点表征:1)它是站在用户的角度去看;2)它讲了一个故事、一个场景。好的用户故事遵循INVEST原则,即一个合适的用户故事应该是独立的(Independent)、有价值的(Valuable)、可讨论的(Negotiable)、小的(Small)、可估算的(Estimable)和可测试验证的(Testable)。Q18:如果采用敏捷开发,最终的用户需求如何呈现给用户?如果是需要存档的用户需求说明书、设计说明书或操作手册之类的文档,适合从DevCloud导出后再修改么?另外如果出现变更,如何确保文档与代码一致?A:如果是需求文档,可以以用户故事的形式存放,华为云DevCloud或者其他工具都提供多元的存储格式,如文本、图片、附件等,华为云DevCloud有一个帮助网站,每一个新上线的功能都会在这里进行同步和更新。也可以把词条或需求存放到wiki里,并跟前端的需求条目之间建立链接。wiki本身是可以有层级关系的,可以把需求从wiki里导出来形成文档形式,如果做得好,还会有版本计划,比如版本里包括10条需求,可以统一导出一篇需求规格说明文档。需求和代码之间的同步,可以通过流程等方式去控制,比如发版的检查点,这可能需要以人工方式去做,但也可以通过一些工具来辅助。比如提交代码的时候需要提交注释,可以把这个注释关联到一个工作项上,一个需求可能会修改多个文件里的多段代码,这其实就是一个完整的变更集的概念,这个变更是为了同一个目的,是有相关性的,如果要从代码里去剥离的话,应该会把这一次变更集统一进行剥离。在未来查看代码时,可以进行代码版本比较,看两个版本之间进行了哪些增加/修改、这些变更是为什么目的、其意图是什么。Q19:对于变化的需求或者新增的需求,是应该放到当前迭代里,还是规划到后面的迭代里,持续规划是指规划过程贯穿整个生命周期么?A:变化或新增的需求都会统一放到一个大的池子里,我们称之为product backlog(产品待办事项列表),这是一个一维的表格,所有需求按照优先级排列。我们要通过判断新进需求的优先级,看它应该放在什么位置。敏捷强调需求是动态变化的,我们会定期对需求列表进行梳理,看是否需要进行优先级排序的调整,因此变化或新增的需求不会放到当前的迭代里,因为当前迭代是一个固定的时间窗口,且范围相对固定,团队对此进行了承诺。我们会将其放入大的需求池,是在下个迭代还是之后的迭代实现,取决于该需求的优先级。Q20:对于初学者刚刚接触一个项目,但是项目的需求不明确、结构不成熟,怎么从敏捷入手?A:这里包括两种情况:初学者、项目在初级阶段。如果是初学者,应该通过获取现有资产快速熟悉和上手;如果项目处于初级阶段,需求也不太明确,可以通过敏捷的快速交付、精益的MVP等实践,快速获取反馈,对后续工作进行指导和建议。Q21:作为整个项目的入口,需求的质量如何把控和评测?A:明确定义需求可以转开发的标准,即DoR。那什么是DoR呢?敏捷开发发展了几个年头之后,人们发现进入迭代开发应当满足一定条件,否则过于模糊的需求会导致迭代的失败,在迭代内花费过多的时间去做需求澄清,因此给进入迭代设立门槛,就是Definition of Ready,简略称之为“DoR”, 最初的Ready是指准备好可以进入迭代开发。Q22:持续规划与设计有什么度量数据或指标用于衡量团队绩效或用于持续改进?如何衡量持续规划与设计的成熟度?A:度量工具推荐Scum的燃尽图、看板的累积流图。研发效能的核心度量数据指标包括团队速率、Lead time,即需求的平均交付时长。Q23:敏捷下的组织过程资产(配置、文档等)这些有好的存储方案么?A:理论上文档、资产等都存储在资产库里,常用的知识库或资产平台有Conflunce、IBM的Rational Asset Manager等。资产和知识是不同的概念,现在做资产管理的相对少一些,知识库可以用wiki等平台,便于统一维护更新和协同。Q24:DevOps 持续规划与设计在DevOps生命周期中是处于开始的时刻,为什么还说代码集成是整个DevOps生命周期的核心呢?A:“代码集成”包括两部分:代码和集成。整个软件生命周期包括三个版本:需求版本,即发版计划;代码版本;上线发布的二进制包的版本。其中代码版本处于承前启后的中间位置,且是唯一真正有价值的。需求和文档是没有价值的,只有由代码编译成二进制包并部署上线才是有价值的。在代码层面多花一些精力是非常有必要的,所有的研发其实都是在一个代码仓库里进行协同开发,包括代码版本管理、分支管理等模式,因此将代码视为DevOps生命周期的核心也是必然的。软件研发最痛苦的地方往往是在集成层面,一开始大家各写各的代码,一旦要将这些不同的代码进行集成的时候,问题就出现了。持续集成的概念来源于XP,“如果代码集成是一件非常痛苦的事情,那我们就每天多次地进行。”一切杀不死你的都会让你更强大,持续地进行集成,你会想办法去减少集成的痛苦。就像跑步一样,假如以前的集成是一块大石头,每天多次集成就相当于将这块石头变成一颗颗的小石子,大石头打在身上会非常疼,小石子就好多了。这也是我们为什么要把集成往前提,并且持续去进行的原因,所以在DevOps生命周期中持续集成也非常重要。【三、持续开发与集成】Q25:如何加强开发人员对于版本质量的信心?A:加强对版本质量的信心,不只是针对开发人员,对所有人都应该如此。整个DevOps的过程其实就是在保障整体的版本质量,包括静态代码检测、接口API测试等。另一方面,版本对需求的映射关系或完成程度,应该从业务场景往下去切,看整个需求的匹配程度。第三点应该是我们通常说的非功能性需求(Non-functional requirements),比如负载、性能、安全、并发支持等,这些要根据我们服务承诺的质量来做相关措施。 Q26:敏捷开发相比传统开发有什么优点?A:我认为最大的优点或特点是敏捷开发更真实,或者说它更愿意承认研发的本质或现状。传统的研发认为质量受三个因素制约:范围、资源、时间,且默认范围和资源投入是相对确定的,时间是变化的。然而,在真实场景或变化的市场下,时间和资源是固定的,没办法讨价还价,因为市场、业务、客户都不会等你,在这样的前提下,软件的需求或范围实际上是可以商量或讨论的,我们要以可变的范围去赢得市场、时间窗口。敏捷开发要求我们不断交付高优先级的需求,并获取反馈,不断调整。这是敏捷开发的最大的核心,承认市场是变化莫测的,需求范围是可变的。Q27:一个产品,既有主线版本,又有很多的行业定制分支(50+),适合什么样的分支策略?A:这种场景在传统的产品里比较常见,个人认为应该考虑的是产品策略而不是分支策略。如果分支非常多,会导致产品碎片化严重。我们在持续集成、持续交付的时候,推崇主干开发或短的分支,不希望这些分支长期存在,否则在产品进行合并时会非常痛苦,工作量也会随着分支的多少和分支存在的时间呈几何倍数增长,所以不建议用长期存在的分支。那可以用什么样的方式来解决呢?首先要看整个版本上是否一定要出现这么多定制化的分支,这些分支有没有可能通过配置文件、功能开放等方式处理或实现。举个例子,我们做项目管理的软件,每个客户要求的字段、功能流转的流程都不太一样,如果都通过代码实现,有多少客户就会出现多少个分支,可能都不止50个。我们是怎么做的呢?针对字段,我可以配置一个界面,里面包括常见属性的字段,这个字段可以是文本类型或下拉框等形式;功能流转的话,新进来一个需求,它的下一个状态是什么、应该触发什么动作、应该是什么样的角色来触发这个动作等这些都是可以进行配置的,这些配置信息存在数据库里,变成用户的配置数据,这样我的主代码主程序是保持不变的,只需要提供一套模型根据数据去驱动适配或实现。这是我们更推崇的方式,可以用来消灭那些分支。Q28:日常项目开发,在代码分支管理上经常疑惑用什么分支管理策略,比如是选择基于生产分支工作流,还是基于环境等等,在实际实践中,我们应该重点考虑哪些因素?既可以兼顾管理效率,又可以确保代码质量。A:个人建议采用分支开发主干发布或分支开发分支发布的分支管理策略。基于环境进行分支构建的话,以前我们会有开发库测试库等仓库管理的概念,但现在全部是持续集成、自动化部署,就没必要再基于环境去拉取分支了。如何保证代码质量,我们在CI/CD流水线、自动化部署和构建的同时需要考虑每一个环境上跑哪些测试,这些测试大部分通过自动化的方式实现,也有少量的是手工进行。Q29:像华为云这样团队成员能力超强、应用场景以线上服务为主,一般会采用什么样的分支管理模式?A:华为云团队也是采用特性分支的管理模式,同时会做多级流水线触发不同环境的流水线来做相关构建,除了开发环境的流水线以外,还有测试、类生产环境等流水线。Q30: 要做到主干上的提交始终处于可发布状态,不受隐含的代码冲突、提交的feature只部分完成等因素影响,对开发团队和基础设施有哪些要求?A:首先主干上提交的流程或质量要严格控制,真正达到DoD(Definition of Done)的标准,这里可能需要一些机制人为地进行管控,比如Committer机制等。提交的时候,除了非功能性的要求,比如跑相关的回归测试、代码检视以外,还有很重要的功能性要求,比如对需求的实现程度的检查。另外“基础设施即代码”,还要看持续集成、持续部署、自动化测试能不能快速有效地跑起来,并保持高度一致。Q31:持续集成的成功因素是什么? A:持续集成主要包括代码仓库、自动构建、自动部署、自动测试四个方面。要求每人每天都要向主干提交代码,触发自动构建和自动部署,在类生产环境进行自动化测试,同时需要团队每个成员确保清楚正在发生的状况,以此来保证持续集成的成功。Q32:华为云上的CI/CD与K8s上搭的CI/CD有什么区别?A:华为云DevCloud打通了端到端的软件交付全流程,集成了常用的DevOps开发工具,不仅可以完成CI/CD,还可以直接在上面进行项目管理和开发;而K8s只是软件开发中一个单独的工具,没有项目需求管理等功能,需要配合其他工具一起使用才能实现完整的软件开发与交付。Q33:开发和修复bug的工时如何进行安排呢?之前迭代出来的bug是按照单独工时安排,还是统一安排在开发中?A:主要看发版的标准和要求是什么,通常来说可以带病发版,但如果是非常严重的缺陷,就不能上线,必须先修复这些bug。一般bug会跟需求放在同一个池子里,根据它的优先级和影响程度来进行排序,决定是先修复bug还是先做需求。如果修改bug是为了扫清技术债务,建议在一个迭代里固定一定比例的时间来进行。Q34:感觉SaltStack和Ansible中哪个是最好的配置管理(CM)工具?为什么?A:两者定位不一样。个人认为Ansible并不是一个标准的配置管理工具,它更多是通过自动化部署的手段去touch环境这一侧,SaltStack相对来说功能性更强一些。Q35:在代码互评审和评审流程中如何高效的提升代码质量?A:人机结合,将重复性的,比如检查代码风格、命名规则等工作交给工具;人工集中看代码实践的逻辑、对需求的匹配等。将人从重复性的工作中解放出来,节约时间和人力。华为实行代码审查Committer机制,开发人员提交代码后,会自动拉起自动化代码检查。提交一个Pull Request,工具匹配相关的review进行评审和打分,如果是重要实现还可能会有一个评审会议,然后进入最终Committer决定是否将提交的代码合并到主干上去。【四、持续测试与反馈】Q36:“通过持续测试实现快速与高质量“是敏捷测试原则之一,而测试金字塔顶端的一些测试往往依赖许多外部因素,较为脆弱,容易因被测软件之外的因素而失败;且由于这类测试同时测试了软件中的多个模块,定位问题就会更难一些。对于 Flaky tests 怎样处理比较好?删除还是进行标记使其不中断后续的测试且不影响质量门禁?A:Flaky Tests,就是指在被测对象和测试条件都不变的情况下,有时候失败、有时候成功的测试。因此,Flaky Tests实际上就是不稳定的测试,或者随机失败(随机成功)的测试。测试金字塔之所以是正的三角形,核心理念是越往上,即金字塔顶端的测试,其跨度越大,影响面越大,一旦出现问题,爆炸的半径也会更大,在这个层面做测试投入产出较小,工作量大且很难执行,比如测试故障定位等,而且自动化用例的复用程度或稳定性也较差,维护成本也比较高。当然该做的工作一定要做,但相对而言,建议这个层面的测试数量要适当减少。相反,越往底层,比如单元测试,爆炸半径相对就小一些,复用度和投入产出比也更高,而且在这个层面发现的bug应该是最多的。建议金字塔底层的测试措施应该相对多做。中间比如接口测试或跨组件的集成等,如果微服务拆分相对颗粒度小一些,各方面相对就比较好,且接口测试相应的工具也比较多,投入产出比也会越来越大。接口测试也可以多做一些,这样中间层变大,金字塔也会变成橄榄球形。Q37:构建本地持续测试和云上持续测试的对比难易程度和成本,如何选取?A:本地持续测试和云上持续测试的差异在于:本地需要自行对工具和版本进行维护,云上的环境相对快捷。从成本方面考虑,云上是按需的,性能测试、压力测试等适合在云上进行,因为自己去搭建一套10万/100万并发的环境成本非常高;越往前端的测试频度非常高,适合在本地进行构建。另外还需要综合考虑开发人员的使用习惯、公司对于数据的安全要求等进行选取。Q38:从传统的瀑布型测试到敏捷测试再到DevOps,三者之间具体有什么区别?A:瀑布型测试是在开发完成交付以后才进行完整的测试,测试主体是测试人员;敏捷测试往前走一步,做大量的持续集成等实践(如果敏捷实践不只是在管理层面的话);DevOps是全流程测试,除了测试左移外,还有测试右移,频繁地持续部署到准生产或生产环境上去跑相关测试,甚至还有现网测试,包括混沌工程、Chaos monkey等,其概念更广。DevOps信奉Resilience(韧性),测试这件事很痛苦,我们要频繁地去做。和反脆弱的概念比较一致,“一切杀不死你的让你更坚强”。Q39 在测试自动化环节中应该如何简化测试流程又能快速发现业务风险?A:测试流程未必会简化,所谓的简化应该是指人员参与的流程减少,把大量能够让机器完成的工作交给机器、回归测试等实现自动化,将人从枯燥的重复性的测试活动中解放出来,去做一些新型测试的探索。Q40:SRE和DevOps有什么区别和联系?A:DevOps通常由两种角色去发起,Dev和Ops,即开发和运维。SRE是Google首先提出的一个概念,Site Reliability Engineer(网站可靠性工程师),从Google运维体系出来的一个角色。SRE工程师会通过自动化工具帮助开发人员,以运维的角度去参与研发并提供一些支持,包括开发一些自动化部署及运维相关的工具,通过这些工具和流程使能开发人员。两者比较而言,DevOps概念和范围相对更大一些,SRE则聚焦在开发与运维层面。Q41:在Scrum中只有 Dev team,没有专门的测试团队。“做测试者胜于做检查者”也要求测试人员不仅能发现问题更要准确定位问题。持续测试向价值流持续交付的两端延伸,要求测试人员不仅要懂业务、懂开发还要懂运维,对测试人员的要求很高。在这种背景下,测试人员该如何进行职业发展规划?A:确实测试人员的焦虑相对更多,因为不管流程也好、角色分工也好,他都处于开发和运维之间的位置,像三明治一样,比较难受。换个角度来看,测试是承上启下的活动,DevOps或敏捷在开始的时候都会相对顺利一些,短期成效很快,但等真正进入到测试层面,就像进入深水区,推进变得困难,原因可能就是自动化测试没做好。这样看来测试人员或测试活动其实大有可为,我们强调测试应该是一类活动,分配在整个研发生命周期过程中,而不是中间的某个阶段,因此对测试人员的要求当然也会更高。以往测试人员给人的印象是在研发提交后才参与进来,或者大量通过手工界面的点击去做回归等工作。现在和未来,这类测试人员存在的价值会很低,未来可能会要求测试人员懂业务,从业务的角度设计测试用例;还要懂开发,需要写测试脚本;还要懂运维。其实这些要求对所有的工程师都同样存在,包括开发工程师,要会做架构、做设计、做开发、还可能要自己做测试、部署运维等;运维工程师也是如此,如果转型SRE工程师的话,也要往前段去走。从这点来看,大家都在同一水平线上,所有人都要求往T型人才发展。综上,测试工程师应该是一个全程的质量保障人员,要从专业测试的视角对研发流程、需求、交付等进行质量控制,还需要引入相关实践、开发工具或做工具集成,去赋能开发和运维。真正好的测试对整个团队的帮助和提升应该是最大的。Q42:与传统项目比较,在敏捷项目中,测试工作在整个流程中所占的比重是否更少了,频次更高了,这是否意味着人效更高了?在DevOps流程下,产品人员、开发人员、主导测试人员的比例是否有一个新的经验参考?A:与传统项目相比,敏捷项目中,测试工作比重更大、频次更高、人效也会更高,但这个更高不是通过人去堆,而是通过自动化工具或时间来完成。在DevOps流程下,专职的测试人员数量会下降,现在大量的开发测试是由开发人员来做,在华为内部称为开发者测试,强调开发人员自己去做测试,以前开发测试比例差不多是3:1, 甚至1:1,现在可能是5:1或10:1的比例。产品人员跟以往应该没有太大差异,现在强调产品思维、运营思维,业务运营人员的人数会增加。Q43:小团队(5人,分工:2前端,3后端,没有专业测试人员)需要单独配备测试人员吗,一边开发一边测试,还是每个人对自己代码负责最后一块集中测试。这两种哪种好一些?A:个人认为5人团队没有必要配置专职测试,可以先由开发承担测试,当团队认为需要有一个专业的测试去知道或支持时,再去引入专业测试人员。那端到端的测试谁来做?建议是采用轮岗机制,类似on call,让团队成员轮流去做,这样可以让所有人对完整的测试都有了解和重视。Q44:未来是否会研测一体化?A:我认为研侧一体化会是一个趋势,开发者测试或开发测试的比例会越来越大,且不断往前端延伸,社会分工本就是合久必分分久必合,大分工衍生了一些新的概念,专业的人做专业的事,驱使我们更聚焦于自己的业务本质,比如IaaS(基础设施即服务),运维/环境管理、系统管理等会有专业的人去做,可以看看你是否就是这样一个专职的人才;测试也是如此,比如TaaS(Test as a service),也是一个非常专业的领域,要求懂开发、懂业务、懂运维。再有就是看公司的核心业务是什么,很多公司都不是专门做测试、运维或工具的,我们应该专注聚焦于公司主营业务。【五、持续安全与审计】Q45:如果组织中缺少专业的安全与审计人员,应该如何去补足这方面的能力?A:有些团队会把这个能力转移给相关的SaaS服务平台或第三方厂商。但平台只能提供问题的展现,实际的安全审计处理还需要专人进行。团队规模小时,可以通过业务上的分割和一些工具手段,尽量减轻相应人员的压力。Q46:小团队安全管控得太严格了,对开发测试都会造成很多不便,也会影响问题排除追踪,如何合理度量安全管控?A:项目进入正规化流程后会有很多环境:开发环境、测试环境、类生产环境、生产环境等,可以采用多环境不同程度安全管控的策略,比如在进行开发环境测试时安全管控力度可以松一些,类生产环境测试时安全管控严格一些。【六、持续部署与发布】Q47:持续部署是不是可以做到热部署,不暂停业务直接通过流水线进行部署、提供用户体验?A:持续部署,每一次变化都是直接部署到生产环境里,但持续交付是有一定选择性的,我们可以选择性地把一些需要的东西部署到生产环境中。如果希望可以做到热更新、热部署,不暂停业务,可以通过持续部署的方式,直接使用流水线来实现。Q48:K8s和Docker在应用上有什么区别?A:Docker是一种容器技术,在实践中可以直接使用Docker进行镜像构建等操作;K8s是进行集群管理的技术手段,华为云DevCloud的帮助中心有一个凤凰商城的实践案例,和HCIP考试中的实验一样,只是多了CI/CD的环节,在这个环节中就使用了K8s。Q49:K8S 和 云原生是什么关系?A:云原生是包括微服务、DevOps、容器化、持续交付等理念和方法,K8s只是一个集群管理的工具。 Q50:如果生产环境有等保要求,还有什么办法实现持续部署吗?A:如果生产环境有等保要求的话,不太适合直接做持续部署,这时使用持续交付的方式更好一些,我们可以先决定应该把哪些特性搬到生产环境上去。Q51:新版程序修改了数据结构,如何进行应用设计或部署方案,以应对可能出现重大问题所需要的版本回退?A:当我们做一些比较大的修改时,一般会先部署到类生产环境上,检视没问题后才会通过灰度的方式同步到生产环境中。Q52:我们已经在做持续集成了,但持续交付和持续部署应该怎么落地?A:如果已经在做持续集成,且做得比较成熟了的话,再往前落地持续交付和持续部署会相对容易。我们经常说:持续交付只是持续集成往前的一小步,最后一公里或最后一米会比较痛苦。其实更多的痛点不在于技术层面,而是在于流程、制度层面,可能很难打穿部门墙、穿透企业管控类的要求,这些都未必是技术能解决的问题。【七、持续运维与监控】Q53:通过自动化的方式实现持续集成和持续交付,中间会不会出现干扰而发生错误?A:一般来说,通过自动化的方式实现持续集成和持续交付后,不是很容易发生错误。错误的出现可能是由于配置问题导致的,在配置相应流水线时没有配置好,比如参数出现问题,版本变得不一致等。除此之外还可能会有一个意外导致的问题,比如网络故障等。Q54:如果生产环境要求网络隔离,还有什么办法实现持续部署吗?A:如果生产环境要求网络隔离的话,我们的流水线一般会搭建在公司内部,也就是从提交代码到构建部署都会在公司内部实现。这个过程中使用云上自动化产品会少一些,因为目前大部分云上构建的工具都必须访问公网才可以做到流水线的效果。因此这种环境下,建议在本地搭建自动化构建流水线,或者购买可供私有化部署的工具。也可以在公网进行代码托管和构建,只在部署的时候通过手工部署的方式将软件包放到网络隔离的机器上去。Q55:Docker与虚拟机有何不同?A:从上图可以用比较清楚的看到Docker和虚拟机的异同。左边的VM是虚拟机使用,container是容器使用,也就是我们说的Docker。两边都有server端和Host OS(虚拟机上的系统)。我们知道每个APP上都有Bin/libs,在Docker容器技术环境下,相同的APP可以共用同一个Bin/libs。大大节省了所占的资源空间。【八、DevOps实践与转型路径】Q56:到目前为止,已经学习了很多DevOps的功能,但是有一个困惑,对于使用DevOps是零代码,那么对于专业的开发人员来说,会不会慢慢降低他们的代码开发积极性?A:DevOps提供的零代码是指在整个DevOps工具链中希望是零代码的,通过将一切可自动化的工具自动化,将开发人员从各种维护工作中解放出来,使他们专注于开发。Q57:在DevOps实践中,环境差异的问题需要在哪个环节就开始着手来注意减少或者避免?A:配置即代码,在开发环节配置差异化的时候把环境差异等都配置进去。Q58:在DevOps转型过程中,对组织和团队最有挑战的有哪些?A:我认为DevOps转型最难的有两方面:一是如何争取公司高层同意推动DevOps转型;二是如果请了教练/顾问协助DevOps转型,顾问/教练走后,如何继续保持和落地DevOps实践。Q59:小团队如果想要使用DevOps需要全员学习吗,感觉每个人都学习时间成本挺高的,是否可以专人负责特定阶段?A:团队如果想要进行DevOps转型,需要专门有一个人把这些流程和工具研究明白,或者聘请一位外部DevOps顾问,再由整个专职人员或DevOps顾问在整个团队进行培训和推动。Q60:四个闭环过程中遇到困难或者难点是否可以列举?有什么避免的方案?A:先回忆一下四个闭环过程:l   第一阶段闭环:需求开发测试融合,将产品、研发、测试等角色融合,组建跨职能团队,提升产品交付价值与质量; l   第二阶段闭环:开发测试融合,组建研发部门内部的跨职能团队,提升自动化水平,降低修复成本; l   第三阶段闭环:研发运营一体化,实施产品自运营、自运维,打破了市场、研发、运维部门之间的壁垒,更多角色融入交付链路,提升业务响应力,建立价值反馈流; l   第四阶段闭环:目标是逐步实现所有业务线都以跨职能团队为最小组织单元,实现业务敏捷性,持续提升企业的市场竞争力。难点包括:l   打通需求难。产品侧和研发侧沟通难。在传统瀑布模式下产品和研发的沟通存在很多问题,比如需求沟通不明确等,引入敏捷的计划会议,在计划会议上做需求澄清,可以解决这一难题。l   开发测试融合难。在很多公司这是两个团队,还有些公司没有测试的角色,要进行人员和过程的融合比较困难。l   研发运营结合难。研发运营一体化,运营部分的内容怎么跟开发结合也是一个难点。l   组织结构管理难。整个流程打通了,人员的管理和组织结构的变动方面也可能会存在问题。以上难点需要根据公司具体情况来实践和探索最佳解决方案。+小姐姐微信加入训练营交流群
  • [云计算周刊] 中国云计算市场规模将达1000亿美元!
    云计算作为当前企业IT基础架构技术的不二之选,已走过探索实践阶段,迎来了多样化全面化的发展时期。  根据调研机构IDC发布的数据统计,2019年,包括云服务(Cloud as a service:公有云服务和专属云服务)、云相关服务(Cloud-related services:云专业服务和云管理服务)、云基础设施建设(Cloud infrastructure build:企业用户和服务商云基础设施建设)在内的中国整体云计算市场规模达到了329亿美元,预计2024年该市场规模将达到1,000亿美元以上。产品服务方面  云产品从虚拟机、存储、数据库、中间件等主要类型向大数据、人工智能、IoT等产品门类发展,再到当前以DevOps、容器和Serverless等为代表的云原生产品不断推广落地;云服务模式上,公有云、企业自建私有云阵营不断融合渗透,混合云、行业云的热潮尚未过去,专属云(包括本地云、托管私有云)、边缘云等热潮已经到来。  生态形成方面  围绕着主要的公有云服务商、私有云产品和技术提供商,一大批帮助企业客户上云、用云、管云的咨询服务商、系统集成商、软件开发商、销售代理商生态已经形成。云计算的发展为初创企业进入和老牌IT服务商业转型带来了发展机遇,也正在逐渐打破原来IT市场上由国际化硬件、软件和服务厂商占主导的生态格局。  市场竞争方面  公有云服务市场的聚集效应仍然明显,《中国公有云服务市场(2020第三季度)跟踪》报告显示,阿里云、腾讯云、华为云、天翼云和AWS 在IaaS+PaaS市场总体占据76.3%的市场份额,此外,金山云、浪潮云、UCloud、移动云等在同期表现出了强劲的增长。公有云服务商加速向本地云、边缘云、企业自建私有云等市场渗透,紫光云、中国电科云、中国电子云等生力军纷纷加入政企云计算市场,再加上原有私有云建设市场上的新华三、浪潮、曙光、VMware以及大批开源软件服务商等,云计算市场竞争日益白热化。  行业应用方面  在疫情刺激下,视频、游戏、电商等带动的互联网行业推动了公有云服务市场的快速增长。政府、医疗、教育、制造、服务等非互联网行业也纷纷看到了云计算对于业务数字化转型的重要作用,将加速推动云计算的全面应用。在云服务商和企业需求的双重推动下,云的部署将无处不在,为行业用户带来更多样化的产品选择和模式选择。  未来,云计算仍将迎来下一个黄金十年,进入普惠发展期。一是随着新基建的推进,云计算将加快应用落地进程,在互联网、政务、金融、交通、物流、教育等不同领域实现快速发展。二是全球数字经济背景下,云计算成为企业数字化转型的必然选择,企业上云进程将进一步加速。三是新冠肺炎疫情的出现,加速了远程办公、在线教育等SaaS服务落地,推动云计算产业快速发展。中国信通院发布的云计算发展白皮书(2020年),对未来云计算发展作出展望,归纳出以下六个关键词。  关键词1:云原生  随着市场持续增长,云技术也不断推陈出新,其中一个值得高度关注的趋势是——云原生采纳率持续攀升。目前超四成的企业已经在使用容器技术,超过七成的私有云企业已经使用或计划使用微服务架构。  关键词2:SaaS  疫情下,越来越多的企业接受SaaS的模式,从业务上看,我国IaaS发展成熟,PaaS增长高速,SaaS潜力巨大。2019年,我国SaaS市场规模达到194亿元,与全球整体市场(1095亿美元)的成熟度差距明显,但是发展空间却十分巨大。尤其是受疫情的推动,预计未来市场将加速发展。  关键词3:分布式云  随着云边协同的发展,在工业等多个领域,分布式云将成为主要模式。中国信通院的调研显示,超过50%的用户已经计划或者已经使用边缘云的模式,“中心云+边缘云”的分布式云的架构已经崭露头角。  关键词4:原生云安全  近年来,一个新的理念诞生,即原生云安全。中国信通院发布的《中国公有云发展调查报告(2020年)》显示,42.4%的企业在选择公有云服务商时会考虑服务安全性,安全是影响企业选择的重要因素。而随着云原生快速兴起,原生云安全也成为关注焦点。  关键词5:数字化转型  数字化转型已经成为经济社会发展的重要趋势。随着云计算技术、架构、安全等方面的推陈出新,云计算在数字化转型中扮演重要角色。调查显示,超过五成的企业使用云计算是为了降本增效,超四成的企业表示使用云计算提升了IT运行效率,IT运维工作量减少和安全性提升的占比分别为25.8%和24.2%。  关键词6:新基建  随着利好政策不断加码,云计算已经成为新基建的重要组成部分。无论是工业和信息化部发布的《中小企业数字化赋能专项行动方案》,国家发展改革委、中央网信办发布的《关于推进“上云用数赋智”行动培育新经济发展实施方案》,还是国家发展改革委对新基建概念的解读,都表明——云计算已经成为新基建的重要组成部分。  无论是如火如荼的“新基建”、稳步推进的企业数字化转型,还是突如其来的疫情,都将云计算推向了一个新高度。未来十年,云计算将进入全新发展阶段,具体表现为以下六大趋势:  趋势1:云技术从粗放向精细转型  趋势2:云需求从IaaS向SaaS上移  趋势3:云架构从中心向边缘延伸  趋势4:云安全从外部向原生转变  趋势5:云应用从互联网向行业生产渗透  趋势6:云定位既是基础资源也是基建操作系统来源: 小巫女聊星座
  • [技术干货] Multi-Architecture镜像制作指南已到,请查收!
    摘要:使用Multi-Architecture镜像,可以让docker根据系统架构去拉取对应的镜像,服务的部署脚本等可以在不同架构的系统间使用相同的配置,减化服务配置,提高了服务在不同系统架构间的一致性。背景由于Kubernetes集群支持amd64和arm64架构的系统,容器部署时两种类型的节点都可能被集群调度到;所以容器在打包推送到镜像仓库时需要考虑支持多架构,防止调度到不支持的架构节点导致运行失败。简介Docker register: v2.3.0开始支持Multi-Architecture镜像Docker CLIv1.11开始支持Multi-Architecture镜像拉取v18.03开始支持Multi-Architecture镜像制作参考资料:Manifest标准:https://docs.docker.com/registry/spec/manifest-v2-1/Manifest命令:https://docs.docker.com/engine/reference/commandline/manifest/Registry:https://github.com/docker/distribution/releases/tag/v2.3.0制作说明虽然Multi-Architecture标准很早就有,但是官方的Docker CLI直到v18.03版本才开始支持Multi-Architecture镜像的制作;或者可以考虑使用第三方工具,参考:构建多CPU架构支持的Docker镜像后续Multi-Architecture镜像的制作使用Docker v18.09版本进行说明。设置DockerDocker使用manifest命令来设置MANIFEST_LIST从而支持Multi-Architecture。到Docker v18.09版本为止,manifest命令还是实验性的,所以要配置Docker使能实验性功能。Docker daemon修改配置文件/etc/docker/daemon.json,添加配置"experimental": true:$ sudo cat /etc/docker/daemon.json[sudo] password for zhangsan:{    "data-root": "/home/common/docker",    "experimental": true,               <- 使能docker daemon实验性功能    "storage-driver": "overlay2",    "log-driver": "json-file",    "log-opts": {        "max-file": "10",        "max-size": "100m"    },    "insecure-registries": [        "docker-hub.***.com"    ]}Docker Cli修改当前用户home目录的配置文件~/.docker/config.json,添加配置"experimental": "enabled":$ cat ~/.docker/config.json{    "experimental": "enabled",          <- 使能docker cli实验性功能        "proxies":        {            "default":            {                "httpProxy": "http://127.0.0.1:3128",                "httpsProxy": "http://127.0.0.1:3128",                "ftpProxy": "http://127.0.0.1:3128"            }        }}验证配置重启docker服务,手工运行docker manifest,出现如下信息说明配置成功:$ docker manifest Usage:  docker manifest COMMAND  Manage Docker image manifests and manifest lists  Commands:  annotate    Add additional information to a local image manifest  create      Create a local manifest list for annotating and pushing to a registry  inspect     Display an image manifest, or manifest list  push        Push a manifest list to a repository Run 'docker manifest COMMAND --help' for more information on a command.镜像打包示例程序stop是一个go程序,启动后暂停不做任何操作,编译到amd64和arm64平台,在amd64平台分别运行如下:$ ll -hR.:total 8.0Kdrwxrwxr-x 2 zhangsan zhangsan 4.0K Jun  3 17:21 amd64drwxrwxr-x 2 zhangsan zhangsan 4.0K Jun  3 17:21 arm64 ./amd64:total 240K-rw-rw-r-- 1 zhangsan zhangsan   51 Jun  3 17:21 Dockerfile-rwxrwxr-x 1 zhangsan zhangsan 235K Jul 19  2014 stop ./arm64:total 656K-rw-rw-r-- 1 zhangsan zhangsan   51 Jun  3 17:21 Dockerfile-rwxr-xr-x 1 zhangsan zhangsan 651K May 22 14:38 stop $ amd64/stop^C% $ arm64/stopzsh: exec format error: arm64/stop使用相同的Dockerfile:$ cat DockerfileFROM scratch COPY stop /stopENTRYPOINT ["/stop"]amd64版本$ cd amd64 $ lsDockerfile  stop # 使用tag标注平台信息。$ docker build -t docker-hub.***.com/zhangsan/stop:1.0-amd64 .Sending build context to Docker daemon  242.7kBStep 1/3 : FROM scratch --->Step 2/3 : COPY stop /stop ---> ffb0d366bb8cStep 3/3 : ENTRYPOINT ["/stop"] ---> Running in 715d1fbcf450Removing intermediate container 715d1fbcf450 ---> 0584fe60ca3dSuccessfully built 0584fe60ca3dSuccessfully tagged docker-hub.***.com/zhangsan/stop:1.0-amd64 $ docker images | grep stopREPOSITORY                                        TAG                 IMAGE ID            CREATED             SIZEdocker-hub.***.com/zhangsan/stop        1.0-amd64           0584fe60ca3d        3 seconds ago       240kB $ docker push docker-hub.***.com/zhangsan/stop:1.0-amd64The push refers to repository [docker-hub.***.com/zhangsan/stop]9e352dcc98ab: Pushed1.0-amd64: digest: sha256:e5b6263b7e45840f139f1bf40b774294712c95df1b43d41598b736f07110341f size: 526 # 可以用manifest的子命令inspect查看镜像的manifest信息,由于是私有仓库,需要使用--insecure参数。$ docker manifest inspect -v --insecure docker-hub.***.com/zhangsan/stop:1.0-amd64{        "Ref": "docker-hub.***.com/zhangsan/stop:1.0-amd64",        "Descriptor": {                "mediaType": "application/vnd.docker.distribution.manifest.v2+json",                "digest": "sha256:e5b6263b7e45840f139f1bf40b774294712c95df1b43d41598b736f07110341f",                "size": 526,                "platform": {                        "architecture": "amd64",                        "os": "linux"                }        },        "SchemaV2Manifest": {                "schemaVersion": 2,                "mediaType": "application/vnd.docker.distribution.manifest.v2+json",                "config": {                        "mediaType": "application/vnd.docker.container.image.v1+json",                        "size": 1489,                        "digest": "sha256:0584fe60ca3dbff4c746d376855e89b72b022a4198373b3c8d4c41b97b8b4faf"                },                "layers": [                        {                                "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",                                "size": 71322,                                "digest": "sha256:7797d3b3ba41f7abc6a914250f793cf2d69a3e7c0bcc787a596eab4836554552"                        }                ]        }}arm64版本$ cd arm64 $ lsDockerfile  stop $ docker build -t docker-hub.***.com/zhangsan/stop:1.0-arm64 .Sending build context to Docker daemon  669.2kBStep 1/3 : FROM scratch --->Step 2/3 : COPY stop /stop ---> e02dd9cc9ffaStep 3/3 : ENTRYPOINT ["/stop"] ---> Running in 9b574680691aRemoving intermediate container 9b574680691a ---> 1fc97e49b088Successfully built 1fc97e49b088Successfully tagged docker-hub.***.com/zhangsan/stop:1.0-arm64 $ docker images | grep stopdocker-hub.***.com/zhangsan/stop        1.0-arm64           1fc97e49b088        8 seconds ago       666kBdocker-hub.***.com/zhangsan/stop        1.0-amd64           0584fe60ca3d        3 minutes ago       240kB $ docker push docker-hub.***.com/zhangsan/stop:1.0-arm64The push refers to repository [docker-hub.***.com/zhangsan/stop]a0c07ccfc4ae: Pushed1.0-arm64: digest: sha256:089798dc96fcc3d2bf4da3ec4243adcc2507d2ae0c5ba77c5582af626702b3d6 size: 527 # 由于打包镜像的机器是amd64架构,所以arm64的应用镜像中architecture为amd64,后面可以修改,或者直接在arm64机器上打包。$ docker manifest inspect -v --insecure docker-hub.***.com/zhangsan/stop:1.0-arm64{        "Ref": "docker-hub.***.com/zhangsan/stop:1.0-arm64",        "Descriptor": {                "mediaType": "application/vnd.docker.distribution.manifest.v2+json",                "digest": "sha256:089798dc96fcc3d2bf4da3ec4243adcc2507d2ae0c5ba77c5582af626702b3d6",                "size": 527,                "platform": {                        "architecture": "amd64",                        "os": "linux"                }        },        "SchemaV2Manifest": {                "schemaVersion": 2,                "mediaType": "application/vnd.docker.distribution.manifest.v2+json",                "config": {                        "mediaType": "application/vnd.docker.container.image.v1+json",                        "size": 1488,                        "digest": "sha256:1fc97e49b0883f59e1e894404785ea1867b9e557d55bdac92f2da09c92b659e7"                },                "layers": [                        {                                "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",                                "size": 318698,                                "digest": "sha256:4397808817371da0348eb097ca181996165a9836d629aa1fb97b0d3824ffe2e2"                        }                ]        }}验证镜像$ docker images | grep stopdocker-hub.***.com/zhangsan/stop        1.0-arm64           1fc97e49b088        21 hours ago        666kBdocker-hub.***.com/zhangsan/stop        1.0-amd64           0584fe60ca3d        21 hours ago        240kB $ docker run docker-hub.***.com/zhangsan/stop:1.0-amd64^C% $ docker run docker-hub.***.com/zhangsan/stop:1.0-arm64standard_init_linux.go:207: exec user process caused "exec format error"创建MANIFEST_LIST创建一个MANIFEST_LIST引用之前两个不同平台的镜像。$ docker manifest inspect -v --insecure docker-hub.***.com/zhangsan/stop:1.0no such manifest: docker-hub.***.com/zhangsan/stop:1.0 $ docker manifest create --insecure docker-hub.***.com/zhangsan/stop:1.0 docker-hub.***.com/zhangsan/stop:1.0-amd64 docker-hub.***.com/zhangsan/stop:1.0-arm64Created manifest list docker-hub.***.com/zhangsan/stop:1.0 $ docker manifest inspect -v --insecure docker-hub.***.com/zhangsan/stop:1.0[        {                "Ref": "docker-hub.***.com/zhangsan/stop:1.0-amd64",                "Descriptor": {                        "mediaType": "application/vnd.docker.distribution.manifest.v2+json",                        "digest": "sha256:e5b6263b7e45840f139f1bf40b774294712c95df1b43d41598b736f07110341f",                        "size": 526,                        "platform": {                                "architecture": "amd64",                                "os": "linux"                        }                },                "SchemaV2Manifest": {                        "schemaVersion": 2,                        "mediaType": "application/vnd.docker.distribution.manifest.v2+json",                        "config": {                                "mediaType": "application/vnd.docker.container.image.v1+json",                                "size": 1489,                                "digest": "sha256:0584fe60ca3dbff4c746d376855e89b72b022a4198373b3c8d4c41b97b8b4faf"                        },                        "layers": [                                {                                        "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",                                        "size": 71322,                                        "digest": "sha256:7797d3b3ba41f7abc6a914250f793cf2d69a3e7c0bcc787a596eab4836554552"                                }                        ]                }        },        {                "Ref": "docker-hub.***.com/zhangsan/stop:1.0-arm64",                "Descriptor": {                        "mediaType": "application/vnd.docker.distribution.manifest.v2+json",                        "digest": "sha256:089798dc96fcc3d2bf4da3ec4243adcc2507d2ae0c5ba77c5582af626702b3d6",                        "size": 527,                        "platform": {                                "architecture": "amd64",                                "os": "linux"                        }                },                "SchemaV2Manifest": {                        "schemaVersion": 2,                        "mediaType": "application/vnd.docker.distribution.manifest.v2+json",                        "config": {                                "mediaType": "application/vnd.docker.container.image.v1+json",                                "size": 1488,                                "digest": "sha256:1fc97e49b0883f59e1e894404785ea1867b9e557d55bdac92f2da09c92b659e7"                        },                        "layers": [                                {                                        "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",                                        "size": 318698,                                        "digest": "sha256:4397808817371da0348eb097ca181996165a9836d629aa1fb97b0d3824ffe2e2"                                }                        ]                }        }]修改MANIFEST_LIST修改刚创建的MANIFEST_LIST,使镜像和架构对应。$ docker manifest annotate docker-hub.***.com/zhangsan/stop:1.0 docker-hub.***.com/zhangsan/stop:1.0-arm64 --arch arm64[        {                "Ref": "docker-hub.***.com/zhangsan/stop:1.0-amd64",                "Descriptor": {                        "mediaType": "application/vnd.docker.distribution.manifest.v2+json",                        "digest": "sha256:e5b6263b7e45840f139f1bf40b774294712c95df1b43d41598b736f07110341f",                        "size": 526,                        "platform": {                                "architecture": "amd64",                                "os": "linux"                        }                },                "SchemaV2Manifest": {                        "schemaVersion": 2,                        "mediaType": "application/vnd.docker.distribution.manifest.v2+json",                        "config": {                                "mediaType": "application/vnd.docker.container.image.v1+json",                                "size": 1489,                                "digest": "sha256:0584fe60ca3dbff4c746d376855e89b72b022a4198373b3c8d4c41b97b8b4faf"                        },                        "layers": [                                {                                        "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",                                        "size": 71322,                                        "digest": "sha256:7797d3b3ba41f7abc6a914250f793cf2d69a3e7c0bcc787a596eab4836554552"                                }                        ]                }        },        {                "Ref": "docker-hub.***.com/zhangsan/stop:1.0-arm64",                "Descriptor": {                        "mediaType": "application/vnd.docker.distribution.manifest.v2+json",                        "digest": "sha256:089798dc96fcc3d2bf4da3ec4243adcc2507d2ae0c5ba77c5582af626702b3d6",                        "size": 527,                        "platform": {                                "architecture": "arm64",                                "os": "linux"                        }                },                "SchemaV2Manifest": {                        "schemaVersion": 2,                        "mediaType": "application/vnd.docker.distribution.manifest.v2+json",                        "config": {                                "mediaType": "application/vnd.docker.container.image.v1+json",                                "size": 1488,                                "digest": "sha256:1fc97e49b0883f59e1e894404785ea1867b9e557d55bdac92f2da09c92b659e7"                        },                        "layers": [                                {                                        "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",                                        "size": 318698,                                        "digest": "sha256:4397808817371da0348eb097ca181996165a9836d629aa1fb97b0d3824ffe2e2"                                }                        ]                }        }]推送MANIFEST_LIST到镜像仓库创建的MANIFEST_LIST会保存在本地目录~/.docker/manifests,在push时可以使用-p(--purge)参数删除本地数据:$ ll -R ~/.docker/manifests/home/zhangsan/.docker/manifests:total 4drwxr-xr-x 2 zhangsan zhangsan 4096 Jun  3 17:57 docker-hub.***.com_zhangsan_stop-1.0 /home/zhangsan/.docker/manifests/docker-hub.***.com_zhangsan_stop-1.0:total 8-rw-r--r-- 1 zhangsan zhangsan 733 Jun  3 17:57 docker-hub.***.com_zhangsan_stop-1.0-amd64-rw-r--r-- 1 zhangsan zhangsan 734 Jun  3 18:01 docker-hub.***.com_zhangsan_stop-1.0-arm64 $ sudo docker manifest push -p --insecure docker-hub.***.com/zhangsan/stop:1.0[sudo] password for zhangsan:sha256:401767ef0864a65578bef86e3baed2e1e0be905d08d88b57cdeb299850400ece验证$ docker images | grep stopdocker-hub.***.com/zhangsan/stop        1.0-arm64           1fc97e49b088        16 hours ago        666kBdocker-hub.***.com/zhangsan/stop        1.0-amd64           0584fe60ca3d        16 hours ago        240kB # 在amd64架构的系统下拉取不带架构信息的镜像$ uname -aLinux SZX1000514415 4.4.0-87-generic #110-Ubuntu SMP Tue Jul 18 12:55:35 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux $ docker pull docker-hub.***.com/zhangsan/stop:1.01.0: Pulling from zhangsan/stopDigest: sha256:401767ef0864a65578bef86e3baed2e1e0be905d08d88b57cdeb299850400eceStatus: Downloaded newer image for docker-hub.***.com/zhangsan/stop:1.0 $ docker images | grep stopdocker-hub.***.com/zhangsan/stop        1.0-arm64           1fc97e49b088        16 hours ago        666kBdocker-hub.***.com/zhangsan/stop        1.0                 0584fe60ca3d        16 hours ago        240kBdocker-hub.***.com/zhangsan/stop        1.0-amd64           0584fe60ca3d        16 hours ago        240kB # 可正常运行$ docker run docker-hub.***.com/zhangsan/stop:1.0^C% # 在arm64架构的系统下拉取不带架构信息的镜像[root@kwephicprc09532 ~]# uname -aLinux kwephicprc09532 4.1.44-06.160.vhulk1711.1.1.aarch64 #1 SMP Tue Oct 16 18:45:06 UTC 2018 aarch64 aarch64 aarch64 GNU/Linux [root@kwephicprc09532 ~]# docker images | grep stop [root@kwephicprc09532 ~]# docker pull docker-hub.***.com/zhangsan/stop:1.01.0: Pulling from zhangsan/stop439780881737: Pull completeDigest: sha256:401767ef0864a65578bef86e3baed2e1e0be905d08d88b57cdeb299850400eceStatus: Downloaded newer image for docker-hub.***.com/zhangsan/stop:1.0 [root@kwephicprc09532 ~]# docker images | grep stopdocker-hub.***.com/zhangsan/stop                          1.0                 1fc97e49b088        16 hours ago        666.5 kB # 可正常运行[root@kwephicprc09532 ~]# docker run docker-hub.***.com/zhangsan/stop:1.0^CShutting down, got signal: Interrupt升级MANIFEST_LIST后期升级MANIFEST_LIST方法与创建类似,如:docker-hub.***.com/zhangsan/stop:1.0-amd64镜像升级或docker-hub.***.com/zhangsan/stop:1.0这个MANIFEST_LIST要关联其它镜像时,都需要升级MANIFEST_LIST。需要注意几点:manifest create时使用参数-a(--amend)升级后没有关联到期望的镜像可以先手工删除本地保存的manifest再尝试使用Multi-Architecture镜像的好处使用Multi-Architecture镜像,可以让docker根据系统架构去拉取对应的镜像,服务的部署脚本等可以在不同架构的系统间使用相同的配置,减化服务配置,提高了服务在不同系统架构间的一致性。 本文分享自《叮!快收好这份Multi-Architecture镜像制作指南》,原文作者:Thir**mans 。
  • [应用专区] 【AR502H产品】【串口功能】串口没有输出
    【功能模块】      AR502H串口输出模块【操作步骤&问题现象】1、我创建了一个容器,命名为lxc01,该容器是特权模式的容器(登陆后是root用户)。2、映射串口设备:在AR502H使用 container add-dev lxc01命令将所有的设备映射到容器里,如下图所示:3、然后配置串口的模式:使用serialportctl命令来配置/dev/ttyRS1,和/dev/ttyRS2,如下图所示:4、配置串口:在容器内容使用stty命令执行如下操作:stty -F /dev/ttyRS1 speed 9600 cs8 -parenb -cstopb将串口1设置成了9600波特率 8数据位 1停止位 无校验位,如下图所示:5、连接串口:    然后使用串口1连接到我的主机电脑的一个串口,并将该串口设置为与/dev/ttyRS1相同的配置。6、测试:    在lxc01容器内,使用echo “111111” > /dev/ttyRS1命令,在我的电脑那一端的串口终端没有收到任何信息。并且485接口的灯也没有闪烁(我们做回环测试是可以闪烁的,说明串口连接没有问题)。请问这是什么原因,我对串口的操作还有哪些需要操作的。
  • [容器专区] 【融合终端产品】容器内执行“rmmod ftdi_sio”命令失败
    【功能模块】在容器运行的demo程序会调用函数并执行system("rmmod ftdi_so"),窗口显示执行命令异常,如下图所示:【操作步骤&问题现象】1、容器包的生成方法是参考《边缘计算网关二次开发智能(AR-CORE系列)》指导手册,制作脚本是从容器编译环境制作脚本下载。2、容器制作步骤:a.制作基础镜像 -> b.在基础镜像里编译第三方开源组件(命令:./build_opensrc.sh arm64) -> c.制作最终编译环境的镜像 -> d.在最终容器环境下编译生成容器包,执行命令:./build_ova.sh arm64 1.0.0 huawei unprivileged3、将生成的容器安装包ARLXC-EC-1.0.1-arm64-unprivileged.ova导入到融合终端的/mnt/internal_storage目录下,然后安装容器并加载所有驱动,容器状态如下:4、进入容器后,手动执行命令“rmmod ftdi_sio”是正常,但执行demo程序后,就会出现异常现象,如下界面5、相同的demo程序,放在贵单位核心板默认安装的lxc01环境下是可以正常运行的,能成功操作ft4232芯片并实现SPI的收发通信。
  • [技术干货] 跳转机分配问题终于“有救”了!容器化时代到来
    跳转机容器化方案介绍想必大家在利用跳转机进行解决方案开发和测试过程中都会遇到这些问题:1. hi,兄弟,帮我分配个跳转机;2. 谁呀,XX跳转机我在使用,不要抢占;3.跳转机全分配完了,没有可用的了,而实际上有很多跳转机分而不用;4. 我想用跳转机来模拟用户,可没有足够的跳转机资源进行容量测试;5.我们跳转机是WINDOWS系统,而实际交付版本配套工具是需要安装在LINUX上的,无资源进行镜像测试;……遇到以上问题怎么办?通过学习和实践利用容器化跳转机方案将如上问题彻底解决,现就该方案跟大家做个分享,欢迎大拿们一起交流。什么是容器容器是应用层的抽象,多个容器可以在同一台宿主机上运行,并共享操作系统资源,每个容器在用户界面是独立运行的,互相不干扰。更多知识,点击:https://mp.weixin.qq.com/s?__biz=MzA5MjM5OTYzNA==&mid=2247489316&idx=1&sn=31404eacde815bee1d9d23d99fea1fb0&chksm=906ce659a71b6f4f96df95d1c8055ca5c76f7cc56057270b6872dd7b28f6235ca08dcf9b9e10&token=1376150626&lang=zh_CN#rd
  • [技术干货] 没有它你的DevOps是玩不转的,你信不?
    善用兵者,役不再籍,粮不三载。取用于国,因粮于敌,故军食可足也。                                                                                                                 ——《孙子兵法》在古代,带兵作战的将领,不仅要能善于用兵,而且要能保障粮食的充足。正所谓兵马未动,粮草先行。粮草永远摆在第一位,因为在冷**时代,战争中的将士都是在拼力气,吃饱才有力气打仗。在今天互联网的“战争”环境中,我们为了能更快的应对市场变化,一直以来不断调整着作战的方针和打法,也从传统的开发方式转变为了敏捷开发,由敏捷开发又过渡了到DevOps。在2019年的中国DevOps行业报告中指出:“尽管受访企业期望 DevOps 能够带来更高效的交付效率,提升客户满意度,创造更多的商业价值,但成功实践 DevOps 依然是一个难题 。”其中28.22% 被调查者认为自己组织的 DevOps 实践是不成功的, 41.13%的被调查者不清楚如何衡量自己组织的 DevOps 实践是否成功。如果以一个更加直观的数据来展示,就是在接受调查的企业中有69.35%是没有能很好的了解和实践DevOps的。也许,在实践DevOps的这几年来,并没有多少公司是真正知道什么是DevOps的。DevOps只是从字面上理解的打破部门墙的一键发布的工具链吗,是否有了这个工具链就是DevOps?答案是否定的。那么,DevOps是什么?DevOps 是集文化理念、实践和工具于一身,可以提高组织高速交付应用程序和服务的能力,与使用传统软件开发和基础设施管理流程相比,能够帮助组织更快地发展和改进产品。这种速度使组织能够更好地服务其客户,并在市场上更高效地参与竞争。——AWS从AWS给出的定义来看,好像也还是比较的抽象。那如果简单的来说,DevOps就是让软件过程既“快”又“稳”。何为快和稳,这个快和稳体现在,部署频率、交付周期、平均修复时长、变更失败比例这4个维度上。在2018年的DevOps调查报告中基于上述4个维度,由于仅有6%达到了所规定的高性能指标,为了避免特殊原因造成数据过低,所以放宽的条件,并给出了准高性能DevOps指标。从达成这一准高性能DevOps指标的团队分析来看,其具体体现在三个方面:一方面是自动化、标准化、质量保证、敏捷方法的实践活动上;一方面是DevOps各个阶段的对应工具上。除此以外就是,团队正在开发应用的架构上。架构的选择对于DevOps的实践是至关重要的,从某种程度上来说,架构就是DevOps这场战役的粮草,它是支撑着DevOps成功落地的重要前提。受访的准高性能DevOps指标的团队将“使用微服务框架”作为团队正在开发应用的架构上的Top1。什么是微服务是一种软件架构风格,它是以专注于单一责任与功能的小型功能区块 (Small Building Blocks) 为基础,利用模块化的方式组合出复杂的大型应用程序,各功能区块使用与语言无关 (Language-Independent/Language agnostic) 的 API 集相互通信。微服务的起源是由 Peter Rodgers 博士于 2005 年度云计算博览会提出的微 Web 服务 (Micro-Web-Service) 开始,Juval Löwy 则是与他有类似的前导想法,将类别变成细粒服务 (granular services),以作为Microsoft下一阶段的软件架构,其核心想法是让服务是由类似 Unix 管道的访问方式使用,而且复杂的服务背后是使用简单URI来开放接口,任何服务,任何细粒都能被开放 (exposed)。这个设计在 HP 的实验室被实现,具有改变复杂软件系统的强大力量。2014年,Martin Fowler与James Lewis共同提出了微服务的概念,定义了微服务是由以单一应用程序构成的小服务,自己拥有自己的行程与轻量化处理,服务依业务功能设计,以全自动的方式部署,与其他服务使用 HTTP API 通信。同时服务会使用最小的规模的集中管理 (例如Docker) 能力,服务可以用不同的编程语言与数据库等组件实现。 微服务的特点根据Martin Fowler的分析,微服务架构有以下的一些通用特性,但并非所有微服务架构应用都必须具备所有这些特性:1.  通过服务实现应用的组件化(Componentizationvia Services):微服务架构中将组件定义为可被独立替换和升级的软件单元,在应用架构设计中通过将整体应用切分成可独立部署及升级的微服务方式进行组件化设计。2.  围绕业务能力组织服务(Organizedaround Business Capabilities):微服务架构采取以业务能力为出发点组织服务的策略,因此微服务团队的组织结构必须是跨功能的(如:既管应用,也管数据库)、强搭配的DevOps开发运维一体化团队,通常这些团队不会太大(如:亚马逊的“Two pizza team”- 不超过12人)。3.  产品而非项目模式(Productsnot Projects):传统的应用模式是一个团队以项目模式开发完整的应用,开发完成后就交付给运维团队负责维护;微服务架构则倡导一个团队应该如开发产品般负责一个“微服务”完整的生命周期,倡导“谁开发,谁运营”的开发运维一体化方法。4.  智能端点与管道扁平化(Smartendpoints and dumb pipes):微服务架构主张将组件间通讯的相关业务逻辑/智能放在组件端点侧而非放在通讯组件中,通讯机制或组件应该尽量简单及松耦合。RESTful HTTP协议和仅提供消息路由功能的轻量级异步机制是微服务架构中最常用的通讯机制。5.  “去中心化”治理(DecentralizedGovernance):整体式应用往往倾向于采用单一技术平台,微服务架构则鼓励使用合适的工具完成各自的任务,每个微服务可以考虑选用最佳工具完成(如不同的编程语言)。微服务的技术标准倾向于寻找其他开发者已成功验证解决类似问题的技术。6.  “去中心化”数据管理(DecentralizedData Management):微服务架构倡导采用多样性持久化(PolyglotPersistence)的方法,让每个微服务管理其自有数据库,并允许不同微服务采用不同的数据持久化技术。7.  基础设施自动化(InfrastructureAutomation):云化及自动化部署等技术极大地降低了微服务构建、部署和运维的难度,通过应用持续集成和持续交付等方法有助于达到加速推出市场的目的。8.  故障处理设计(Designfor failure):微服务架构所带来的一个后果是必须考虑每个服务的失败容错机制。因此,微服务非常重视建立架构及业务相关指标的实时监控和日志机制。9.  演进式的设计(EvolutionaryDesign):微服务应用更注重快速更新,因此系统的计会随时间不断变化及演进。微服务的设计受业务功能的生命周期等因素影响。如某应用是整体式应用,但逐渐朝微应用架构方向演进,整体式应用仍是核心,但新功能将使用应用所提供的API构建。再如在某微服务应用中,可替代性模块化设计的基本原则,在实施后发现某两个微服务经常必须同时更新,则这很可能意味着应将其合并为一个微服务。微服务适用的场景基于微服务的优势,我们可以看到,微服务比较实用于以下场景:1.    对于业务流程较为复杂,且业务会变得逐渐复杂的项目,可以考虑使用微服务架构2.    项目存在多个团队(公司)多种开发语言时 3.    核心业务和非核心业务变得泾渭分明 4.    需要平滑升级时(服务无中断、客户无感知)5.    想对系统进行细粒度监控时 (bug调查困难或性能等问题)既然微服务有其使用的场景,那么也一定有其优缺点。微服务的优势微服务的诞生正是在互联网高速发展,技术日新月异变化以及传统架构无法适应快速变化等多种因素共同推动下的必然产物。从一个网站的演变可以看到使用微服务后带来了很多优点,总结如下:逻辑清晰:这个特点是由微服务的单一职责的要求所带来的。逻辑清晰带来的是微服务的可维护性,在我们对一个微服务进行修改时,能够更容易分析到这个修改到底会产生什么影响,从而通过完备的测试保证修改质量。简化部署:微服务则可以只对一个微服务单独进行部署,不影响其他功能的同时,在效率上也得到了提升,从而快速的发布新的功能。可扩展性强:在分布式系统中,采用微服务的系统相对单块系统具备更好的可扩展性。灵活组合减少浪费:在微服务架构中,可以通过组合已有的微服务以达到功能重用的目的,减少了重复浪费。技术异构:微服务间松耦合,不同的微服务可以选择不同的技术栈进行开发。微服务的缺点以往单体应用,排查问题通常是看一下日志,研究错误信息和调用堆栈。而微服务架构整个应用分散成多个服务,定位故障点非常困难。在微服务架构中,一个服务故障可能会产生雪崩效用,导致整个系统故障。微服务架构虽然逻辑设计上看是完美的,但就像积木搭建的华丽宫殿一样,经不起风吹草动。微服务架构虽然解决了旧问题,也引入了新的问题:提高了系统的复杂度,此外还有:1.    服务的注册与发现问题;2.    服务之间的分布式事务问题;3.    数据隔离再来的报表处理问题;4.    服务之间的分布式一致性问题;5.    服务管理的复杂性,服务的编排;6.    不同服务实例的管理。 微服务在使用上是一把“双刃剑”,这就像粮草如果在搬运的过程中被敌方夺取,那可能会是毁灭性的。所以DevOps团队在微服务的架构上需要非常的重视,一个成熟度高的微服务框架才是实现其DevOps的重要前提,反之亦然。那么如何算得上是一个成熟度高的微服务呢?在华为云DevCloud专业服务中提供了微服务的能力评估,想知道成熟度高不高,快来看看你的微服务的成熟度评估结果吧~~~~~~~~~~~
  • 容器技术:从通用向多元化发展
    (1) 安全容器        容器技术的采纳率连年提升,已经开始进入企业的生产环境。以Docker 为代表的普通容器通过Namespaces 和cGroups 实现的隔离,共享内核的机制使得隔离性具有天然的缺陷无法根除,在多租户场景下安全问题更加凸显:        内核Bug 引发容器逃逸,操作系统内核漏洞、Docker 组件设计缺陷、不当的配置等都会导致Docker 容器发生逃逸。由于频发的安全及逃逸漏洞,一般在云环境中的容器应用不得不运行在虚拟机中,以满足多租户安全隔离要求。而分配、管理、运维这些传统虚拟机与容器轻量、灵活、弹性的初衷相悖,同时在资源利用率、运行效率上也存在不足。内核资源竞争影响业务性能,同一个宿主机上的不同Pod,实际上是不同的用户态进程的集合,这些用户态进程虽然在namespace 上是相互隔离的,但他们还是会共享很多内核资源,比如调度器、某些内核线程或者对象。这种级别的资源共享会引入很多可以观测到的性能抖动,对在线业务的影响也很明显。与Docker 普通容器不同,安全容器通过添加隔离层,给进程分配了一个独立的操作系统内核,从而避免了让容器共享宿主机的内核。因此容器进程能够看到的攻击面,就从整个宿主机内核变成了一个极小的、独立的、以容器为单位的内核,从而有效解决了容器进程发生“逃逸”或者夺取整个宿主机的控制权的问题。(2) Serverless 容器        FaaS 平台提供的是函数级别的Serverless 化部署,且应用场景多依赖于其绑定的触发器,对函数的执行有一些配置限制,并且不支持进程常驻。传统的应用大都是单体应用或者微服务应用,在迁移到FaaS 平台时,需要拆分函数,迁移成本较高。        Serverless 容器,可以很好地弥补FaaS 的不足,Serverless 容器可以支持进程常驻的服务形态,不限运行时长,并扩大Serverless的应用场景。Serverless 容器支持服务的形态,传统的单体应用或者微服务应用,几乎可以无缝迁移到Serverless 容器平台上。        Serverless 容器和传统的容器相比,为了实现Serverless 的理念,在如下几个方面做了加强:免运维的纯托管模式,传统的容器往往是直接将容器集群托管给业务方,业务方需要分担容器集群的一些运维工作。Serverless 容器则把容器集群完全托管给云厂商,由云厂商进行集群的运维工作,用户不用关注这些运维工作,只需部署自己的业务逻辑即可;以实际资源用量计费,传统的容器是按照容器的实例配置进行计费的,Serverless 容器是按照实际资源使用量进行计费;秒级弹性伸缩响应,传统的容器往往借助于容器编排工具来实现弹性伸缩,比如通过Kubernetes 可以实现Docker 的容器的弹性伸缩,但是Kubernetes 伸缩时间是分钟级的,而Serverless 容器能够提供更加极致的伸缩能力,做到秒级伸缩并且资源实例和伸缩至零。    (3) 裸金属容器        容器服务最早部署形态是基于IAAS 虚拟机,以虚拟机节点作为容器集群的计算节点,并基于此构建容器的网络、存储和编排能力,这样的堆叠架构虽然可以让整个软件栈分工明确、边界清晰,但是带来了较大的性能损耗和功能冗余。此外如果用户对实例安全隔离性要求较高,就需要借助虚拟化技术,而虚拟化平台不能很好支持该能力。基于以上痛点,在裸金属服务器上搭建容器服务成为一些对性能和实例隔离性较高用户的选择。        随着裸金属容器的发展,为了进一步提高容器负载性能和稳定性,原来部署在裸金属之上的非业务负载组件也逐步的由专门的卸载硬来承载,比如容器存储、容器网络、容器引擎以及服务网格组件。将容器组件下沉到卸载卡后,有几方面好处:l 裸金属节点就可以被当做纯粹的计算资源,可以“完全”被业务负载使用。同时避免了对业务负载的性能干扰。l 容器网络、容器存储组件下沉到卸载卡后可以与传统IAAS 层的网络、存储组件垂直打通,减少冗余功能;直接以硬件设备直通方式将存储、网络资源分配给容器实例,缩短I/O 路径,提高性能。l 容器层组件下沉到卸载卡后,裸金属成为纯粹的计算资源,可以被容器实例或者虚机实例共享,为虚拟机和容器实例共节点奠定了基础,提高资源整体利用率。虽然裸金属容器可以通过卸载技术获得诸多益处,但同时也面临着较大的挑战:l 资源占用问题。由于卸载卡上的资源非常有限,容器组件需要进行轻量化瘦身后才能较好的适配卸载卡,当前业界也在推动容器引擎层面的轻量化改造,比如kata-shim-v2 和isulad。l 实例密度问题。由于容器存储和网络资源都是走VF 直通方式,而当前卸载卡上支持的VF 数量比较有限,在小规格实例场景,VF 会成为实例密度提升的限制。        此外,裸金属容器不仅在资源利用率和性能上有优势,对系统运维管理的自动化和敏捷性上有较高诉求。为了获得较高的自动化运维能力,很多的依赖组件都进行了微服务改造,借助容器编排自身能力来自动化管理所依赖的服务,甚至是节点操作系统本身。比如AWS 为了提高容器计算节点操作系统更新管理的灵活性,推出了bottlerocket 产品,放弃原来基于包更新的升级机制,采用镜像粒度一步更新方法,降低了OS 更新的失败率,提高运维自动化程度和容器应用的稳定性。来源:云原生产业联盟
  • [技术干货] 因为这7个C++的坑,整个团队加班一星期
     摘要:近期踩到了一些比较隐晦的C++的坑,可把我们团队给坑惨了~~近期我们团队进行版本质量加固时,踩到了一些比较隐晦的C++的坑,特总结分享在此,供大家参考。1. string的字符串拼接,导致coredump该问题的核心点在于第9行,竟然是可以编译通过,其原因是x+"-",会被转成char*,然后与to_string叠加导致BUG。2. map的迭代器删除map要删除一个元素,通常通过erase()函数来完成,但是要注意,如果我们传入了一个iterator作为erase的参数来删除当前迭代器所指向的元素,删除完成后iterator会失效,产生未定义行为。正确的使用方法应该是接收erase()的返回值,让iterator指向被删除元素的下一个元素或者end()。for  ( auto  iter = m.begin(); iter != m.end(); iter++) {  if  (...)  iter = m.erase(iter);  } 但是上述代码仍然有错误,因为如果触发了删除,那么iter再下一轮循环时会指向下下个元素,所以正确的写法应该是:  for  ( auto  iter = m.begin(); iter != m.end();) {  if  (...) {  iter = m.erase(iter);  continue ;  }  else  {  iter++;  }  } 3. stringstream的性能问题stringstream的清空是clear之后,置空。stringstream在任何情况下都比snprintf慢。memset是个很慢的函数,宁愿新创建对象。上述测试结果是单线程,改成多线程,同样成立。str += “a”, 比 str =str+ “a” 效率高很多,后者会创建新对象。4. 智能指针(shared_ptr)使用注意4.1尽量使用make_shared初始化提高性能std::shared_ptr<Widget> spw(newWidget);需要分配两次内存。每个std::shared_ptr都指向一个控制块,控制块包含被指向对象的引用计数以及其他东西。这个控制块的内存是在std::shared_ptr的构造函数中分配的。因此直接使用new,需要一块内存分配给Widget,还要一块内存分配给控制块autospw = std::make_shared<Widget>();一次分配就足够了。这是因为std::make_shared申请一个单独的内存块来同时存放Widget对象和控制块。这个优化减少了程序的静态大小,因为代码只包含一次内存分配的调用,并且这会加快代码的执行速度,因为内存只分配了一次。另外,使用std::make_shared消除了一些控制块需要记录的信息,这样潜在地减少了程序的总内存占用。异常安全processWidget(std::shared_ptr<Widget>( new  Widget),   //潜在的资源泄露   computePriority()); 上述代码存在内存泄漏的风险,上述代码执行分为3个步骤:1.  new  Widget2. shared_ptr构造3. computePriority 编译器不需要必须产生这样顺序的代码,但“new Widget”必须在std::shared_ptr的构造函数被调用前执行。如果编译器产生的顺序代码如下:1.  new  Widget2. 执行computePriority。3. 执行std::shared_ptr的构造函数。 如果执行步骤2:computePriority的时候程序出现异常,则在第一步动态分配的Widget就会泄露了,因为它永远不会被存放到在第三步才开始管理它的shared_ptr中4.2 父类之类智能指针转换C++中是允许裸指针,因此裸指针之间转换方法同C语言指针强转,智能指针转换不能通过上述方法进行强转,必须通过库提供转换函数进行转换。 C++11的方法是:std::dynamic_pointer_cast;boost中的方法是:boost::dynamic_pointer_cast#include <memory>#include <boost/shared_ptr.hpp>#include <boost/make_shared.hpp>#include <iostream>class  Base {  public :  Base(){}  virtual  ~Base() {}};class  D :  public  Base {  public :  D(){}  virtual  ~D() {}};int  main(){  //方式一:先初始化子类智能指针,然后调用dynamic_pointer_cast转换成基类智能指针对象  std::shared_ptr<D> d1 = std::make_shared<D>();  std::shared_ptr<Base> b1 = std::dynamic_pointer_cast<Base>(d1);    //方式二:先new子类D的指针,然后调用shared_ptr的构造函数初始化基类智能指针  std::shared_ptr<Base> b2 = shared_ptr<Base>( new  D());  return  0;} 结论方式一和方式二均能够实现基类智能指针指向子类,但建议采用方式1,通过std::make_shared的方式构造智能指针,然后进行转换;5. map的安全查找办法即map[key]这种写法,就是会创建元素(且不一定初始化),因此在业务逻辑是希望查找的时候,就老老实实用find,不然会有脏数据写入。6. string 的指针构造std::string 的构造方式,除了与其它顺序容器相近的方式之外,提供了三种额外的构造方式:string s(cp, n): s 是cp指向的数组中前n个字符的拷贝,该数组至少应该包含n个字符string s(s2, pos2):s 是string s2从下标pos2开始的字符的拷贝,若pos2>s2.size(),构造函数的行为未定义string s(s2, pos2, len2):s 是string s2从下标pos2开始len2个字符的拷贝,若pos2>s2.size(),构造函数的行为未定义。不管len2的值是多少,构造函数至多拷贝s2.size()-pos2个字符 std::string 未提供 string(cp, pos2, len2) 这种构造方式,如果代码中使用了该方式,最终会将 cp 指向的数组构造成一个string,然后调用string(s2, pos2, len2)这种构造方式。不提供string(cp, pos2, len2)这种构造方式原因在于:使用这种方式构造容易出现问题,cp是一个指针,通常使用时,能获得其数组长度并检查传入参数;若传入两个参数,容易出现越界。7. 变量初始化变量初始化总是没错的,不管后面是否会修改该值。尤其是int等内建的类型,在类或struct中及容易忽略初始化,使变量成为随机值,产生不可预知的错误。变量请初始化!变量请初始化!!变量请初始化!!!
  • [技术干货] 【转载】容器、Docker、虚拟机,别再傻傻分不清
     摘要:容器技术起源于Linux,是一种内核虚拟化技术,提供轻量级的虚拟化,以便隔离进程和资源。尽管容器技术已经出现很久,却是随着Docker的出现而变得广为人知。容器技术起源于Linux,是一种内核虚拟化技术,提供轻量级的虚拟化,以便隔离进程和资源。尽管容器技术已经出现很久,却是随着Docker的出现而变得广为人知。Docker是第一个使容器能在不同机器之间移植的系统。它不仅简化了打包应用的流程,也简化了打包应用的库和依赖,甚至整个操作系统的文件系统能被打包成一个简单的可移植的包,这个包可以被用来在任何其他运行Docker的机器上使用。容器和虚拟机具有相似的资源隔离和分配方式,容器虚拟化了操作系统而不是硬件,更加便携和高效。图1 容器 vs 虚拟机相比于使用虚拟机,容器有如下优点:更高效的利用系统资源由于容器不需要进行硬件虚拟以及运行完整操作系统等额外开销,容器对系统资源的利用率更高。无论是应用执行速度、内存损耗或者文件存储速度,都要比传统虚拟机技术更高效。因此,相比虚拟机技术,一个相同配置的主机,往往可以运行更多数量的应用。更快速的启动时间传统的虚拟机技术启动应用服务往往需要数分钟,而Docker容器应用,由于直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间,大大节约了开发、测试、部署的时间。一致的运行环境开发过程中一个常见的问题是环境一致性问题。由于开发环境、测试环境、生产环境不一致,导致有些问题并未在开发过程中被发现。而Docker的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性。更轻松的迁移由于Docker确保了执行环境的一致性,使得应用的迁移更加容易。Docker可以在很多平台上运行,无论是物理机、虚拟机,其运行结果是一致的。因此可以很轻易的将在一个平台上运行的应用,迁移到另一个平台上,而不用担心运行环境的变化导致应用无法正常运行的情况。更轻松的维护和扩展Docker使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。此外,Docker团队同各个开源项目团队一起维护了大批高质量的官方镜像,既可以直接在生产环境使用,又可以作为基础进一步定制,大大的降低了应用服务的镜像制作成本。Docker容器典型使用流程Docker容器有如下三个主要概念:镜像:Docker镜像里包含了已打包的应用程序及其所依赖的环境。它包含应用程序可用的文件系统和其他元数据,如镜像运行时的可执行文件路径。镜像仓库:Docker镜像仓库用于存放Docker镜像,以及促进不同人和不同电脑之间共享这些镜像。当编译镜像时,要么可以在编译它的电脑上运行,要么可以先上传镜像到一个镜像仓库,然后下载到另外一台电脑上并运行它。某些仓库是公开的,允许所有人从中拉取镜像,同时也有一些是私有的,仅部分人和机器可接入。容器:Docker容器通常是一个Linux容器,它基于Docker镜像被创建。一个运行中的容器是一个运行在Docker主机上的进程,但它和主机,以及所有运行在主机上的其他进程都是隔离的。这个进程也是资源受限的,意味着它只能访问和使用分配给它的资源(CPU、内存等)。典型的使用流程如图2所示:图2 Docker容器典型使用流程(1)首先开发者在开发环境机器上开发应用并制作镜像。Docker执行命令,构建镜像并存储在机器上。(2)开发者发送上传镜像命令。Docker收到命令后,将本地镜像上传到镜像仓库。(3)开发者向生产环境机器发送运行镜像命令。生产环境机器收到命令后,Docker会从镜像仓库拉取镜像到机器上,然后基于镜像运行容器。使用示例下面使用Docker将基于Nginx镜像打包一个容器镜像,并基于容器镜像运行应用,然后推送到容器镜像仓库。安装DockerDocker几乎支持在所有操作系统上安装,用户可以根据需要选择要安装的Docker版本。在Linux操作系统下,可以使用如下命令快速安装Docker。curl -fsSL get.docker.com -o get-docker.shsh get-docker.sh说明: CentOS 8.0操作系统使用上述脚本安装Docker会出现问题,建议使用如下命令安装较低版本Docker。 wget -O /etc/yum.repos.d/docker-ce.repo https://repo.huaweicloud.com/docker-ce/linux/centos/docker-ce.repo sudo sed -i 's+download.docker.com+repo.huaweicloud.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo yum install docker-ce-18.06.3.ce -y systemctl restart docker Docker打包镜像 Docker提供了一种便捷的描述应用打包的方式,叫做Dockerfile,如下所示: # 使用官方提供的Nginx镜像作为基础镜像 FROM nginx:alpine   # 执行一条命令修改Nginx镜像index.html的内容 RUN echo "hello world" > /usr/share/nginx/html/index.html   # 允许外界访问容器的80端口 EXPOSE 80 执行docker build命令打包镜像。 docker build -t hello . 其中-t表示给镜像加一个标签,也就是给镜像取名,这里镜像名为hello。. 表示在当前目录下执行该打包命令。 执行docker images命令查看镜像,可以看到hello镜像已经创建成功。您还可以看到一个Nginx镜像,这个镜像是从镜像仓库下载下来的,作为hello镜像的基础镜像使用。 # docker images REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE hello               latest              d120ec16dcea        17 minutes ago      158MB nginx               alpine              eeb27ee6b893        2 months ago        148MB 本地运行容器镜像 有了镜像后,您可以在本地执行docker run命令运行容器镜像。 # docker run -p 8080:80 hello docker run命令会启动一个容器,命令中-p是将本地机器的8080端口映射到容器的80端口,即本地机器的8080端口的流量会映射到容器的80端口,当您在本地机器访问 http://127.0.0.1:8080时,就会访问到容器中,此时浏览器中返回的内容应该就是“hello world”。 把镜像推送到镜像仓库 华为云提供了容器镜像服务SWR,您也可以将镜像上传到SWR,下面演示如何将镜像推送到SWR。详细的方法请参见客户端上传镜像,本文档后续的示例中将主要使用SWR作为示例。 首先登录SWR控制台,在左侧选择“我的镜像”,然后单击右侧“客户端上传镜像”,在弹出的窗口中单击“生成临时登录指令”,然后复制该指令在本地机器上执行,登录到SWR镜像仓库。 上传镜像前需要给镜像取一个完整的名称,如下所示: # docker tag hello swr.cn-east-3.myhuaweicloud.com/container/hello:v1 这里swr.cn-east-3.myhuaweicloud.com是仓库地址,每个华为云区域的地址不同,v1则是hello镜像分配的版本号。 swr.cn-east-3.myhuaweicloud.com是仓库地址,每个华为云区域的地址不同。 container是组织名,组织一般在SWR中创建,如果没有创建则首次上传的时候会自动创建,组织名在单个区域内全局唯一,需要选择合适的组织名称。 v1则是hello镜像分配的版本号。 然后执行docker push命令就可以将镜像上传到SWR。 # docker push swr.cn-east-3.myhuaweicloud.com/container/hello:v1 当需要使用该镜像时,使用docker pull命令拉取(下载)该命令即可。 # docker pull swr.cn-east-3.myhuaweicloud.com/container/hello:v1
  • [技术干货] JFrog:这是一个流动的世界,开发者是雨点的制造者
    2020年10月26日上午6:00,作者:Richard MacManus             JFrog上个月进行了首次公开募股(IPO),从那时起,其股价几乎翻了一番。对于一个很难向开发者社区以外的人解释的软件公司来说,这并不坏。甚至连公司的名字都不能说明它到底在做什么。正如JFrog的联合创始人兼首席执行官Shlomi Ben Haim在最近的一次采访中告诉我的那样,如果他的母亲给他打电话祝贺公司的成功,“当我们开始谈论二进制时,她就会失去注意力。”             JFrog是一个DevOps平台,其主要货币是,正如本哈伊姆(Ben Haim)所暗示的那样,它的主要货币是二进制。他还指出,“软件包”和“图像”是同一事物的替代术语。不管用什么术语,它都是已经编译好并准备好供计算机系统执行的代码。有些人将JFrog与GitHub进行了比较,不同之处在于GitHub是源代码的存储库,而JFrog是二进制文件的存储库。“这是你从你的源代码中构建出来的,以及你打包在一起的东西,”本·哈伊姆在谈到二进制文件时说,“从这一点开始,这就是你测试、安全和在运行时部署的东西。”在当前的DevOps应用程序开发时代,有很多活动部件。当您浏览组成JFrog平台的各种软件产品时,您将了解到DevOps变得多么复杂,以及为什么企业越来越需要像JFrog这样的平台来管理它。JFrog成立于2008年,在2008年和在后来的几年里,它的唯一产品是 Artifactory,从2011年起,被称为管理被称为“Repository Management Solution.”之后,JFrog拓展了其他安全、CI?CD、分布式计算产品以及一些其他产品。            关于JFrog的另一个有趣的地方是,正如你猜的,它的销售是由开发者驱动的。决定使用JFrog软件的并不是像微软(Microsoft)和甲骨文(Oracle)等知名软件供应商的那样由企业首席信息官驱动。在JFrog的例子中,这是一个自下而上的采购过程,开发者最初选择使用JFrog,后来随着JFrog的广泛部署,首席信息官可能会承担相应的费用。本•哈伊姆自豪地告诉我,JFrog没有对外销售人员,正因为如此。“即使是今天作为一家上市公司,我们在这个领域连一个直销员都没有。一个也没有。从来没有人敲过别人的门,主动提供JFrog Artifactory——它都安装在里面,都是进货(销售)。”显然,这一策略奏效了。据本•哈伊姆(Ben Haim)称,财富100强企业中有75%现在都在使用JFrog。            你的特斯拉神器库戴尔科技资本公司是JFrog的早期投资者,其董事总经理泰勒•杰威尔(Tyler Jewell)在其开发者主导的景观论文中写道,“artifact存储库”类别同比增长了45%。他说,这是“软件构建方式的转变所驱动的”,特别是第三方可重用模块(通过低代码、JavaScript框架等)的日益增多的使用。             我问Ben Haim,他是否认为未来几年工件库的这种增长水平仍在继续?他回答说,这种增长的一部分原因是由于微服务、容器和其他云计算原生技术的兴起,软件二进制文件“成倍增长”,“因为软件发布变得如此容易”,他不认为工件存储库的市场会很快放缓,因为“可寻址市场将显著增长”。原因:非企业用例。“下一步——想想看——将在你的组织之外,因为你希望你的特斯拉得到更新,你的iPhone也得到更新。DevOps for IoT(物联网)仍处于非常早期的阶段。”这就引出了JFrog一直在其网站上推广的软件理论:液体软件。这在其主页上被定义为“软件更新过程自动地、连续地运行,就像软件是流动的一样。”这让我想起了互联网就像电网一样的比喻——换句话说,就是一种实用工具。JFrog也提出了同样的建议,只是它用电换水。本哈伊姆回到特斯拉,他称之为“一台有轮子的电脑”,进一步解释。他说,目前,如果你需要在你的特斯拉汽车上运行软件更新,“它需要关闭你的发动机两个小时”;有时甚至需要技术人员“到你家里来运行软件更新”,我自己不是特斯拉的车主,我无法验证等待时间(这个Quora线程表明这更像是30分钟),但不管怎样,本·哈伊姆的观点是:在软件更新的过程中,汽车变得无法运行。这是目前的状况,但JFrog的目标是使所有软件更新都能在后台持续进行。“在液体软件的世界里,特斯拉也会随着这个缩放应用程序的更新而更新,”Ben Haim说,他提到了我们目前正在进行的Zoom视频通话。他推测,特斯拉最终将使用点对点网络技术,让汽车相互更新,从而“不让网络超载,也不让我们的基础设施超载” 这一切都要回到开发人员身上,他们当然要负责维护这种“流动”的软件更新过程。              开发者如雨滴制造者            “JFrog(2008年)是由一群本身就是开发者的人创立的,”本•哈伊姆说。“我们的主要想法是解决问题——当公司要求我们提供更多、更快和更安全的产品时,我们如何才能更快?”             他继续说,在JFrog成立之时,软件开发正处于转型期——“从瀑布到敏捷再到DevOps。”尽管DevOps这个词直到2009年才被发明出来,并在那之后又过了几年才获得关注,但JFrog还是围绕着同一个概念建立了自己的公司——或者正如本·哈伊姆所说,“自动化[和]机器的力量,以及开发人员的力量”的结合。在我们的谈话中,本哈伊姆把开发者称为商业的“雨点”。他指的是开发人员正在创造被称为“数字化转型”(我无法告诉你,这句话在新一代“后流感”的电子邮件宣传中被使用了多少次)。 本哈伊姆以一家现代银行为例,说明了开发者将传统业务转变为数字化业务的能力。“我不认为我已经三年多没有亲自拜访过我的银行,但如果我不喜欢应用,我会从一家银行搬到另一家银行。”              他的观点是,现在银行提供了更好的用户体验,因为你可以在网上做更多的事情。我完全同意这一点,我不怀念那些不得不亲自开车去银行分行做任何事情的日子。“开发者之所以成为造雨者,是因为他们创造了企业的竞争优势,”本哈伊姆这样总结道。一旦你理解了这个概念,就很容易理解为什么JFrog在股票市场上表现如此出色——尽管很少有投资者了解它的实际作用。原文链接:https://thenewstack.io/jfrog-its-a-liquid-world-and-developers-are-the-rainmakers/
总条数:879 到第
上滑加载中