济南做网站找泉诺,哈尔滨seo优化专注,visual studio怎么做网页,做网站网站名字自己设置吗本文由1月31日晚iHealth运维技术负责人郭拓在Rancher官方技术交流群内所做分享的内容整理而成#xff0c;分享了iHealth从最初的服务器端直接部署#xff0c;到现在实现全自动CI/CD的实践经验。作者简介郭拓#xff0c;北京爱和健康科技有限公司#xff08;iHealth)。负责公… 本文由1月31日晚iHealth运维技术负责人郭拓在Rancher官方技术交流群内所做分享的内容整理而成分享了iHealth从最初的服务器端直接部署到现在实现全自动CI/CD的实践经验。作者简介郭拓北京爱和健康科技有限公司iHealth)。负责公司基础服务构建与研发流程定制曾供职于乐视、21vianet高龄攻城狮活跃在一线研发工作中乐此不疲。前言相信我一切事情的发生都是赶鸭子上架没有例外。人类所有伟大的变革都是迫不得已可又是那么顺其自然。比如容器docker技术的诞生比如箭在弦上的创业比如野心勃勃的kubernetes比如如今已作为左膀右臂的rancher比如这篇文章。iHealth致力于用全新的移动互联体验整合传统的个人健康管理方式公司业务范围包含移动医疗、慢病护理以及健康与医疗硬件研发。不同于郑兄的CI/CD实践《如何利用Docker构建基于DevOps的全自动CI》我们结合自身状况构建了一套我们自己的DevOps CI/CD流程更轻更小更适合Startup。合适的才是最好的Node.js Docker如果世界只有FLAG、BAT那就太无趣了。iHealth是一家初创型公司我所在的部门有大概10名研发人员担负着三端研发工作的同时所有围绕服务的交付和运维工作也都是我们来做。技术的选型上服务端、Web端和移动端Android、iOS都要上但人少。所以招人的时候并没有以貌取人部门对外的Title都是全栈。能一门语言通吃三端群众基础广泛恐怕没有比Javascript/Typescript(Node.js)更合适的了。服务端有Express、Koa、Feather、Nest、Meteor等各有其长的框架前端大而火的Reactjs、Vuejs和Angular不管是Server Render还是前后端分离都可以得心应手。因为公司的健康设备血糖仪、血压计、体温计、血氧、体脂秤等等会有专门的部门研发设计以及提供SDK所以移动端的研发工作更多是在设计实现和性能优化上React Native是一枚大杀器。虽然现在公司并没有桌面端的需求但不能否认的是Electron是一个很有趣的项目也为“全栈”这个词增加了更多背书。另外选择使用Node/Js/Ts作为全栈的基础会附带有RPC的好处。无需集成传统意义上的RPC框架如gRPC只需在编写远程(微)服务方法时编写相应的npm package也可以达到相同的目的且成本更小更易理解。 运维环境的选型上所有的业务都运行在云端省去了机房维护和服务器运维的成本。其实在盘古开荒时我们也是编写了Node程序后使用PM2部署在服务器上并没有使用Docker。当然也存在没有使用Docker所带来的一切问题三端不同步、环境无法隔离……而Docker带给我最大的惊喜除了超强的可移植性更在于研发人员可以非常容易对程序的顶级架构进行推理。事实上我们直接使用docker-compose做容器编排着实有一段时间在一次大规模的服务器迁移中发现需要重新思考越来越多的container管理和更完善的编排方案。RancherCattle就是在这时被应用到技术栈中。一切从Github开始在运维环境一波三折的同时DevOps的征程也是亦步亦趋步步惊心。幸运的是我们知道自己缺乏什么想要什么所以能比较容易的做到“哪里不会点哪里”。如同上一章节所述合适的才是最好的。持续集成CI与持续交付CD的迭代过程从最初的代码拷贝到结合docker-compose与rsync命令到使用CI/CD工具做到相对意义上的自动化……迄今为止我们摸索出一套相对好用并且好玩的流程故事大致是这样的当一只代码猴提交代码之后他需要去接一杯咖啡。在猫屎氤氲的雾气里45°角仰望天花板手机微信提醒这次构建成功或失败并附带污言秽语。这时他可以开始往工位走坐下时微信又会提醒本次部署到Rancher成功或失败。这一切开始的地方是github。当开发者写完 BUG 功能之后需要有地方保存这些宝贵的资料。之所以没有使用Gitlab或Bitbucket搭建私有的Git服务器是因为我们认为代码是最直接的价值体现。服务如骨架终端如皮肤UE如衣服三者组成让人赏心悦目的风景代码是这背后的基础。我们认为在团队精力无法更分散、人口规模尚小时购买Github的商业版是稳妥且必要的毕竟那帮人修复一次故障就像把网线拔下来再插上那样简单。Drone CIDrone这个单词在翻译中译作雄蜂、无人机。我特意咨询了一位精通一千零二十四国语言的英国朋友说这个词的意思是autonomousworks by itself。白话就是有活它自己干而且是自主的。不过这个解释对于Drone来说名副其实。这个在Github上拥有13,000 Stars的开源项目使用Golang编写相比Jenkins的大而全Drone是为Docker而生的CI软件。如果有使用过Gitlab CI的小伙伴相信对Drone的使用方式不会感到陌生他们都是使用Yaml风格文件来定义pipelinepipeline:build:image: node:latestcommands:- npm install- npm run lint- npm run testpublish:image: plugins/npmwhen:branch: masterDrone的安装方式如同Rancher一样简单一行docker命令即可。当然大家也可以看Drone的官方文档在这里只讲一下使用Rancher catalog安装Drone的方式查看大图大家可以看到Drone使用Rancher catalog安装的方法with github在Github 的Settings中创建Drone的OAuth App时Home Page Url务必要写你能访问Drone的IP地址或域名例如http://drone.company.com而OAuth App的Authorization callback URL应该对应上面的写法http://drone.company.com/authorize小功告成登录进Drone之后在Repositories中找到你想要开启CI的Git Repo用switch按钮打开它这表示已经打开了Drone对于这个Repo的webhook当有代码提交时Drone会检测这个Repo的根目录中是否包含.drone.yml文件如存在则根据yaml文件定义的pipeline执行CI流程。Drone与Rancher、Harbor、企业微信的集成在决定使用Drone之前需要知道的是Drone是一个高度依赖社区的项目。其文档诸多不完善完善过版本迭代文档跟不上了plugins质量良莠。但对于擅长Github issue、Google、Stackoverflow的朋友来说这并不是特别困难的事情。Drone也有付费版本无需自己提供服务器而是像Github那样作为服务使用。如果你决定开始使用Drone截止到上面的步骤我们打开了Drone对于Github Repo的监听再次提醒需要在代码repo的根目录包含.drone.yml文件才会真正触发Drone的pipeline。那么如果想重现上面故事中的场景应该如何进行集成呢我司在构建CI/CD的过程中现使用Harbor作为私有镜像仓库从提交代码到自动部署到Rancher其实应当经历如下步骤提交代码触发Github WebhookDrone使用docker插件根据Dockerfile构建镜像并推送到Harbor中Drone使用rancher插件根据stack/service部署上面构建好的imageDrone使用企业微信插件报告部署结果在这里节选公司项目中的一段yaml代码描述了上述步骤# .drone.yaml
pipeline:# 使用plugins/docker插件构建镜像推送到harborbuild_step:image: plugins/dockerusername: harbor_usernamepassword: harbor_passwordregistry: harbor.company.comrepo: harbor.company.com/registry/testmirror: https://registry.docker-cn.comtag:- devdockerfile: Dockerfilewhen:branch: developevent: push# 使用rancher插件自动更新实例rancher:image: peloton/drone-rancherurl: http://rancher.company.com/v2-beta/projects/1a870access_key: rancher access keysecret_key: rancher secret keyservice: rancher_stack/rancher_servicedocker_image:harbor.company.com/registry/test:devbatch_size: 1timeout: 600confirm: truewhen:branch: developevent: push# 使用clem109/drone-wechat插件报告到企业微信report-deploy:image: clem109/drone-wechatsecrets:- plugin_corp_secret- plugin_corpid- plugin_agent_idtitle: ${DRONE_REPO_NAME}description: | 构建序列: ${DRONE_BUILD_NUMBER} 部署成功干得好${DRONE_COMMIT_AUTHOR} 更新内容: ${DRONE_COMMIT_MESSAGE} msg_url: http://project.company.combtn_txt: 点击前往when:branch: developstatus:- success对接企业微信之前需要在企业微信中新建自定义应用比如我们的应用名字叫Drone CI/CD。当然您也可以给每一个项目创建一个企业微信App这样虽然麻烦但是可以让需要关注该项目的人关注到构建信息。下面是企业微信测试的截图企业微信与微信客户端是连通的可玩性还不错在这里我认为有必要提醒一下使用Drone的企业微信插件时不要使用Drone Plugins列表里的企业微信。翻阅其源码可以发现其中一个函数会将企业的敏感信息发送至私人服务器。不管作者本身是出于BaaS的好意还是其它想法我认为都是不妥的代码地址https://github.com/lizheming/drone-wechat/blob/master/index.js在此Drone Plugins里的企业微信插件出现很久之前我的好友Clément 克雷蒙同学写了一个企业微信插件至今仍在使用。欢迎检查源代码提issue提bug为了不让克雷蒙同学骄傲我并不打算号召大家给他starclem109/drone-wechat而在构建完成后可以看到Drone控制面板里小伙伴们战斗过的痕迹ELK与Rancher的集成ELK是ElasticSearch、Logstash与Kibana的集合是一套非常强大的分布式日志方案。ELK的使用更多在于其本身的优化以及Kibana面向业务时的使用这本身是一个很大的话题只ElasticSearch就有许多奇技淫巧。因为人力资源的原因我们使用了兄弟部门搭建的ELK等同于使用已有的ELK服务。所以在此也不再赘述ELK的搭建网上有许多资源可供参考。在这里要做的事情就是把rancher中的日志归集到已有的ELK中。在Rancher的catalog中找到logspout这是一个logstash的adapter为docker而生在配置中设置LOGSPOUTignore然后把ROUTE_URIS设置为已经搭建好的logstash地址就可以将当前环境的日志集成到ELK中Traefik与Rancher的集成目前看来一切都很好对吗的确是这样。我们提交了代码drone自动构建镜像到harbor自动部署到Rancher自动发送构建结果Rancher又可以帮助自动重启死掉的container使用Rancher webhook也可以实现自动弹性计算并且可以使用yaml文件定制构建流程定制一些report信息当构建或部署失败时让企业微信自动侮辱我们的小伙伴……可是据说微服务还讲究服务注册和服务发现如果并不想动用Zookeeper这样的核武器就像我们不想用Kong一样一是有一定学习和维护成本二是Logo越改越丑那就需要找到一个轻量级能满足需求的替代品。况且目前并没有遇到需要削峰的处理。对于域名的解析我们选择使用Traefik作为LB这个同样使用Golang编写同样拥有将近13,000 Stars并且兼具简单的服务注册和服务发现功能。更值得一提的是Rancher catalog里的Traefik非常友好的集成了Lets EncryptACME的功能可以做到自动申请SSL证书过期自动续期。当然不推荐在生产环境使用SSL免费证书的数量非常容易达到阈值而使得域名无法访问。Traefik内部架构图Image from traefik.io如何安装Traefik呢我们以Rancher catalog中的Traefik为例不使用ACME我们的目的是做域名解析integration mode应该设置为metadata。Http Port设置为80Https Port设置为443Admin Port可以根据自己实际情况填写默认8000。此时的Traefik已经准备就绪但是打开traefik_host:8000查看控制面板时发现Traefik并没有做任何代理。原因是需要在代理的目标中使用rancher labels标示出traefik的代理方式。比如刚才安装的Drone如果我们想代理到drone.company.com这个域名则需要在drone server的container中设置lablestraefik.enabletrue 表示启用traefik代理traefik.domaincompany.com 表示traefik代理的根域名traefik.port8000 表示这个container对外暴露的端口traefik.aliasdrone 表示想将drone server这个container解析为drone.company.com需要注意的是traefik.alias有可能导致重复解析同时traefik有自己的一套默认解析规范。更详细的文档请看GitHub 地址rawmind0/alpine-traefik在设置Rancher labels后可以看到Traefik的控制面板中已经注册了服务地址利用Traefik的这个特性和Rancher对于Container的弹性计算可以做到简单的服务注册和服务发现。最后需要在域名服务商那里做A记录解析解析的IP地址应为Traefik的公网地址。 因为域名解析的默认端口是80和443后面发生的事情就和Nginx的作用一毛一样了。域名解析到Traefik服务器的80端口https则是443Traefik发现这个域名已经注册到服务中于是代理到10.xx开头的虚拟IP转发请求并发送response。与Nginx Conf如出一辙至此我们已经完全实现从代码提交到自动部署以及域名解析的自动化。在生产环境的Traefik on Rancher中开启Https可以把ssl的整个信任链以文本的形式粘贴进去同时修改Traefik的Https选项为true即可另外Traefik并不是LB/Proxy的唯一选择甚至不是最酷的选择但确是目前与Rancher集成最好的。下面图中的程序都值得做调研可以小小的注意一下istio天庭饱满骨骼轻奇这还只是2017年7月底的数据……事实上对于Traefik我们是又爱又恨。它能非常方便的与Rancher集成功能简便强大性能可观。但在最开始着实踩了不少坑一度打算放弃并回归到传统的Nginx做反向代理的方式甚至写了PR并被merge到master中。截止目前Rancher Catalog中最新的1.5版本已经是一个真正稳定可用的版本了。小技巧Node.js的项目中书写Dockerfile时经常会用到yarn或者npm i来拉取依赖包。但npm的服务器远在世界的另一端这时可以使用淘宝的镜像进行加速。通常我们在本地开发时执行会记得加上npm镜像在服务器上跑Dockerfile也是一样的道理FROM node:alpine
WORKDIR /app
COPY package.json .
RUN npm i --registry https://registry.npm.taobao.org
COPY . .
CMD [ node, bin/www ]Drone在构建镜像并推送到镜像仓库时需要根据Dockerfile的基础镜像进行构建而docker服务器也远在世界的另一端同样的可以使用mirror来指定镜像仓库并尽量使用alpine镜像缩小体积pipeline:build_step:image: plugins/dockerusername: harbor_namepassword: harbor_pwdregistry: harbor.company.comrepo: harbor.company.com/repo/testmirror: https://registry.docker-cn.com作大死命令不要在服务器上使用。但本地开发很好用。意思是停止所有container删除所有container删除所有imagedocker stop $(docker ps -aq) docker rm $(docker ps -aq) docker rmi $(docker images -aq)结语附带工具链汇总罗马不是一天建成万丈高楼平地起。在企业发展之初我们在打基础的同时也要保证项目高速迭代。短时间内无法做到Netflix的体量以及其对于微服务治理的精妙在运作的细节中也有诸多需要完善的部分例如BDD、TDD的实践传统意义上的UAT与蓝绿灰度发布移动时代的全链路日志服务熔断、隔离、限流以及降级的能力亦或是星火燎原的Service Mesh……所以退一步讲必须先生存才能生活。我们可以允许服务死掉但是要保证无感知或极短感知的情况下服务能迅速的活过来。在持续交付的过程中我们也尝试使用sonar代码质量管理使用phabricator作为code review环节因为配置的变更和微服务数量的逐渐增多配置中心(主要考虑携程的Apollo)的引入也迫在眉睫调用链监控以及代码重新埋点的成本(二节所述npm package rpc的优势又可体现)是否能抵过其带来的好处等等。但因目前尚未达到一个非常成熟的阶段所以本次不再分享仅表述其名来启发各位聪明的小伙伴。除此之外技术视野的成长也非朝夕。就像我国政府在大家买不起自行车时就开始修建高速公路时至今日还能说它是面子(KPI)工程吗与社区一同进步开阔视野的同时保持独立思考的能力是比上述所有更为重要的技能。 回到本文开头所写一切都是赶鸭子上架。与其说笔者天资聪慧才貌过人风度翩翩儒雅风流不如说这都是被逼的。同事抱怨流程繁琐不直观若要做到代码和咖啡那样大繁若简就需要思考CI/CD的目的与本质。大智若愚真正的天才必须能够让事情变得简单。拓展资料Rancher: https://github.com/rancher/rancherDrone: https://github.com/drone/droneDrone企业微信API插件: clem109/drone-wechatHarbor: vmware/harborTraefik: containous/traefikPhabricator: phacility/phabricatorSonarQube: SonarSource/sonarqubeLogspout: gliderlabs/logspout配置中心(携程做的代码写的还不错): ctripcorp/apolloSuperSet(BI): apache/incubator-superset 转载于:https://blog.51cto.com/12462495/2068237