【DevOps】阿里DevOps企业最佳实践
内容来自阿里云大学:《阿里专家带你玩转DevOps企业最佳实践》
一、DevOps、微服务与阿里云容器服务
1、DevOps概念入门
DevOps(Development和Operations的组合词)
要完成DevOps倡导的理念,不止是一个技术问题,更多的是一个流程、管理、乃至公司架构的问题。
DevOps:“时间”与“质量”
流程化、标准化减少脱节环节时间浪费
节约时间人人有责
自动化降低人工时间消耗
质量的提升可以避免返工
DevOps是为了解决“时间”和“质量”而产生的一种交付文化、流程、交付方式等等的统称。
DevOps期望通过消除“等待”与“浪费”的方式实现更快速、更高质量的交付。
2、微服务
微服务是由以单一应用程序构成的小服务,微服务之间相互解耦,以全自动的方式部署,与其他服务使用http API通讯。同时服务会使用最小的规模的集中管理(例如docker)能力,服务可以用不同的编程语言与数据库等元件。
微服务的特性:
服务组件化
按照业务组织团队
做产品的态度
智能短点与哑管道:服务之间调用的短点可以动态获取以服务发现的方式提供,对于出错的场景提供熔断器。
去中心化治理
去中心化管理数据
基础设施自动化:自动化部署、自动化交付
容错设计:组件是不可行的,对于失败的状态需要有降级的处理
演进式设计:设计组件的时候需要明确和规划组件的边界。
微服务的缺点:
将一个大型的系统拆分成微服务设计系统的分布式改造,带来了技术成本。
更清晰的边界划分也使得标准化变得困难,微服务依赖上层的框架进行规约。
单体应用内部的通信成本远低于微服务组件间通信。
管理多个组件或者组件拓扑成为微服务系统的头等要务。
数据库的设计与业务规划成为为服务中的难点,对开发者提出更多的要求。
容器如何解决微服务的缺点:
Dockerfile将微服务中语言、框架等的复杂性进行了封装。
Docker Image将交付最小单元进行了定义,降低了交付复杂性。
Docker的API以及上层的编排系统实现了拓扑的管理。
越来越丰富的容器生态使得微服务不止从交付,更从框架级别进行了支持。
https://github.com/AliyunContainerService/DevOps
二、如何快速高质量的应用容器化迁移
1、容器交付流程
(1)本地开发阶段
代码编写、测试编写、容器化测试、Dockerfile编写、编排模板编写
(2)持续集成与持续交付
构建代码、打包构建产物、构建Docker镜像、推送Docker镜像、部署编排模板
(3)环境部署
调整应用拓扑、调整接入层配置、调整扩缩容配置
(4)监控、运维与调优
基础监控资源设置告警、APM监控应用内部指标、安装调优工具进行调优
2、Dockerfile与Docker Image
Dockerfile的目标是将应用进行抽象打包,通过构建产出的docker image实现标准化交付。
Cloud Foundry将运行的应用分成了OS Image Layer、Runtime Layer、Application Layer三层,认为任何运行时的应用都可以通过这三个维度的抽象进行表达。
Dockerfile语法
ENTRYPOINT是/bin/sh –c来执行的,不是PID1的进程,无法收到SIGTERM。
Docker Image底层实现
联合文件系统(Union Filesystem)
写时复制(Copy On Write)
常见的存储驱动:
AUFS、OverlayFS:基于文件、启动快、效率稍差
Device Mapper:基于块设备、启动慢、效率高
3、高质量的Docker Image构建
(1)减少镜像的层数,尽量把一些功能上面统一的命令合到一起来做;
(2)助理清理镜像构建的中间产品,比如一些安装包在装完之后就把它删除;
(3)注意优化网络请求,应当用一些网络比较好的开源站点,可以节约时间,减少失败率;
(4)尽量用构建缓存,尽量把一些不变的东西,或者变得比较少的东西放在前面,因为不变的东西都是可以被缓存的。
(5)多阶段进行镜像构建,明确镜像制作的目的,将构建与真正的产物做分离,构建就用构建的镜像去做,最终产物就打最终产物的镜像。
4、容器编排系统
从设计思路来看kubernetes
面向资源简化模型(go-restful):所有在kubernetes中操作的实体都可以用资源进行抽象,所有的资源都有RESTful的API与之对应。
异步动作保证性能(informers):所有依赖资源的组件都通过异步进行监听(watch),具体的执行由各自的消费者决定频度。
状态机提供状态基线(etcd):所有的信息流都通过期望、实施、反馈的机制存储在etcd中,数据即状态。
反馈机制保证状态:informers中可以实现定期的sync,可以通过sync来处理中间状态。
组件松耦合可插拔:组件之间通信要么是通过APIServer进行中转,要么是通过APIGroup进行解耦,组件之间没有强依赖关系,部分组件自带熔断器。
Tips:
Kompose:http://kompose.io,swarm向k8s迁移的一个工具。
Podman:Podman 是一个开源的容器运行时项目,可在大多数 Linux 平台上使用。Podman 提供与 Docker 非常相似的功能。正如前面提到的那样,它不需要在你的系统上运行任何守护进程,并且它也可以在没有 root 权限的情况下运行。Podman 可以管理和运行任何符合 OCI(Open Container Initiative)规范的容器和容器镜像。Podman 提供了一个与 Docker 兼容的命令行前端来管理 Docker 镜像。
容器迁移工具:Derrick
三、从零搭建CICD系统标准化交付流程
1、CICD基本概念
持续集成(Continuous Integration,CI):是一种软件项目管理方法,依据资产库(源码、类库等)的变更自动完成编译、测试、部署和反馈。要求:自动构建,自动检测变更,反馈机制,纯净的构建环境等。
持续交付(Continuous Delivery,CD):频繁的将软件的新版本,交付给质量团队或者用户,以供评审尽早发现生产环境中存在的问题。
持续部署(Continuous Deployment,CD):是代码尽快向可运行的开发/测试交付,以便尽早测试;是持续交付的下一步,指的是代码通过评审以后,自动部署到生产环境。
Jenkins:
Master提供web让用户来管理job和slave,job可以运行在master本机或者被分配到slave上运行。一个master可以关联多个slave用来为不同的job或相同的job的不同配置来服务。
搭建Jenkins系统:
docker环境准备 –> 启动Jenkins Master容器 –> 安装插件 –> 配置构建节点 –> 运行第一个项目
# docker run -d -it -p 8080:8080 -p 50000:50000 –v /var/jenkins_home:/var/jenkins_home -v /var/run/docker.sock:/var/run/docker.sock -name jenkins-master jenkinsci/blueocean
配置构建节点:
运行构建节点,ssh端口映射
系统管理 – 管理节点 - 新建节点(通过ssh连接jenkins master)
插件的安装是要Jenkins master重启之后才会生效。
CICD系统:
Jenkins master容灾
Jenkins slave节点规划和镜像制作
插件管理
访问权限配置
源码管理、触发器、构建结果通知等
日常运维:数据清理、备份
组件更新升级
安全漏洞修补
阿里云CodePipeline是兼容Jenkins标准的、提供快速可靠的持续集成与持续交付服务。基于容器技术和阿里云基础服务架构,提供稳定和安全的代码/Docker编译构建,测试,扫描和部署的工具服务,并提供Pipeline As Code的编码级配置模式,满足应用程序和基础设施快速可靠的交付和更新。
四、云原生容器应用交付的设计与实践
云原生的代表技术包括容器、服务网格、微服务、不可变基础设施和声明式API。
五、多种发布模式实现容器化交付
容器的网络模型:单机网络模型、跨主机网络模型、
vpc网络:L3 Flat,指各个host中所有的容器都在virtual+physical网络中可路由,且路由以/32位的形式存在,使得容器在host间迁移时不需要改变ip地址。性能优于overlay网络,不需要ARP广播寻址,不需要封解包。
经典网络:overlay网络,需要通过ARP广播寻址。
常见的发布策略有蓝绿发布、金丝雀发布(灰度发布)、ABTest。
蓝绿发布:在发布的过程中用户无感知服务的重启,通常情况下是通过新旧版本并存的方式实现,也就是说在发布的流程中,新的版本和旧的版本是相互热备的,是通过切换路由权重的方式(非0即100)实现不同应用的上线或者下线。蓝绿发布适合绝大多数的应用场景的发布,能够零宕机更新,缺点是发布时资源消耗大。
金丝雀发布:通过在线上运行的服务中,新加入少量的新版本的服务,然后从这少量的新版中快速获得反馈,根据反馈决定最后的交付形态。金丝雀发布主要面向的场景是功能兼容的新版本验证,可以用最小的代价实现功能验证,且保证主体流量不受影响,缺思安是面向场景比较单一,对于开发者要求较高。
灰度发布:是通过切换线上并存版本之间的路由权重,逐步从一个版本切换为另一个版本的过程。
A/BTest:和灰度发布非常像,ABTest侧重的是从A版本或者B版本之间的差异,并根据这个结果进行决策,最终选择一个版本进行部署。因此和灰度发布相比,ABTest更倾向于去决策,和金丝雀发布相比,ABTest在权重和流量的切换上更灵活。
六、开源框架与阿里云容器服务集成
工具链:
Derrick:构建Dockerfile的自动化工具
Kompose:docker swarm资源转换为kubernetes资源
helm:kubernetes的包管理器,相当于centos的yum。
微服务示例:
eureka-server:incubator/ack-springcloud-eureka
demo:https://github.com/AliyunContainerService/spring-cloud-k8s-sample
服务发现的一个问题:集群内的一个应用将自己注册到集群外的一个注册中心(注册的IP是Pod IP),集群外的另一个应用从注册中心获取到这个应用的IP,但实际上集群外的应用是访问不到pod IP的。
解决方案:
网络配置:
Host Network
设置容器地址段到主机地址段
把外部的ECS纳入kubernetes管理,不运行Pod
https://developer.aliyun.com/article/603633
框架层面解决:
dubbo(在k8s中的应用:设置注册的ip和端口为对应service的外网访问ip和端口)、
Spring Cloud(注册hostname为service url)
Service Mesh:sidecar模式,不是简单的sidecar去接管单个的容器,而是容器服务之间的通信形成的网络的管理架构,上面加上control plane,形成一个控制平面,下面的服务通信形成数据平面。通过控制平面来控制数据平面之间的服务相互的连接关系,可以做服务路由之类的管理工作。
Istio:
七、容器化应用性能测试与调优
1、性能测试的常用方法
负载测试:负载测试时用户观点的测试行为。负载测试就是让系统在一定的负载压力下进行正常的工作,观察系统的表现是否满足用户的需求。
压力测试:通过对系统的极端加压,从而观察系统的所表现出来的性能问题。
并发测试:验证系统的并发能力。通过一定的并发量管擦系统在该并发量的情况下所表现出来的行为特征,确定系统是否满足设计的并发需要。并发测试是系统观点的测试行为。
基准测试:基准测试要有一个基准点。当软件系统中增加一个新的模块的时候,需要做基准测试,以判断新模块对整个软件系统的性能影响。
稳定性测试:长时间的负载测试,确定系统的稳定性。
可恢复性测试:测试系统能否快速地从错误状态中恢复到正常状态。
全链路测试:包含系统上下游的全链路压力测试与稳定性测试方式,通过模拟近似真实的用户流量和用户行为来仿真线上流量。
2、性能测试与调优的主要对象
程序瓶颈:
使用的I/O模型、是否能够使用多核处理器、部署的方式与资源分配
网络瓶颈:
网络模型与协议、网络防火墙设置、内核态与用户态切换
内核瓶颈:
内核参数调优、内核模块开启与加载、内核版本与性能
系统瓶颈:
不同操作系统对特定场景存在先天缺欠。
硬件瓶颈:
磁盘、网络设备、CPU
3、容器性能测试与调优的步骤
(1) 收集信息整理架构
收集的信息:应用的拓扑关系、使用的框架语言以及相应的版本、接入层的配置与链路、使用的网络模型、容器的分布、出现问题时的现象与场景,每一个链路的流量情况,先排查各种泄漏的问题
目标:通过信息的手机,能够在白板上重构出应用的拓扑关系、预估流量的量级以及目前来看异常的问题链路。
(2) 提出怀疑点指定测试方案
(3) 选择测试方法与工具集合
(4) 完整进行执行测试方案
(5) 结果比对修正方案
4、工具
压测工具:wrk、PTS
资源概览工具:Ctop(容器层级间监控进程,实时监控的指标)、Htop
CPU Memory性能工具:Perf、strace根据syscall的跟踪来统计的。
磁盘性能:iotop、iosnoop
网络性能:sar、netstat(ss)
网络诊断:tcpdump、wireshark
sysdig = strace + tcpdump + lsof + htop + iftop等工具的合集
snout:主动的性能调优诊断工具
八、容器化应用问题诊断、监控与运维
节点相关的问题:master宕机、worker节点宕机
etcd稳定性问题:
网络链路:
pod问题: