SegmentFault 基于 Kubernetes 的容器化与持续交付实践
本文是根据 KubeSphere 云原生 Meetup 杭州站讲师祁宁分享内容整理而成。
SegmentFault 是一家综合性技术社区,由于它的内容跟编程技术紧密相关,因此访问量的波动也和这一群体的作息时间深度绑定。通常情况下 web 页面的请求量峰值在 800 QPS 左右,但我们还做了前后端分离,所以 API 网关的峰值 QPS 是请求量峰值的好几倍。
架构历史
SegmentFault 作为一个技术社区的系统架构变化,里面有些东西还是很有意思的。
- 2012 年当时我还在北京的一家公司打工,当我在出租屋里写下它的第一行代码时,我不会想象到它到后面会成为我的事业。当时我的想法很简单,就是想帮助中文开发者用母语在像 StackOverflow 这样的网站上提问,因此它的第一个版本非常简陋,考虑到它的访问量很少以及自己的经济能力不足,我将它放在了国外的 VPS 托管商 Linode 上,所有的应用、数据库、缓存都挤在一个实例上。
- 2013-2014 年,单独出来创业,业务逐渐步入正轨。我们选择了自己购买服务器去机房托管,当然服务器也是从淘宝上购买的二手服务器,经常遇到问题,我们团队在外地又去不了机房,只能等管理员去机房帮我们解决。正好在2014年我们的网站被 DDos 攻击了,机房为了不连累其他服务器,直接把把我们的网线拔掉了。
- 2014-2019 年,中国的云计算也开始起步了,于是我们把整个网站从物理服务器迁移到了云服务上。当然使用上并没有什么不同,只是把物理机器替换成了虚拟主机。
- 2020 年至今,随着云原生理念的兴起,我们的业务模式也发生了很大变化,为了让系统架构适应这些变化,我们把网站的主要业务都迁移到了 KubeSphere 上。
遇到的挑战
紧接着,我们遇到了不少挑战,促使使我们不得不往 K8s 架构上迁移。
首先,虽然我们是一家小公司,但是业务线却非常复杂,整个公司只有 30 人左右,技术人员只占其中三分之一左右,所以承载这么大的业务量负担还是很重的。而且创业公司的业务线调整非常频繁,临时性工作也比较多,传统的系统架构在应对这种伸缩性要求比较高的场景是比较吃力的。
其次,复杂的场景引发了复杂的配置管理,不同的业务要用到不同的服务,不同的版本,即使用自动化脚本效率也不高。
另外,我们内部人员不足,所以没有专职运维,现在 OPS 的工作是由后端开发人员轮值的。但后端开发人员还有自己本职工作要做,所以对我们最理想的场景是能把运维工作全部自动化。
最后也是最重要的一点就是我们要控制成本,这是高情商的说法,低情商就是一个字“穷”(笑)。当然,如果资金充足,以上的问题都不是问题,但是对于创业公司(特别是像我们这种访问量比较大,但是又不像电商,金融那些挣钱的公司)来说,我们必将处于且长期处于这个阶段。因此能否控制好成本,是一个非常重要的问题。
前后端分离
2020 年以前,SegmentFault 的网站还是非常传统的后端渲染页面的方法,所以服务端的架构也非常简单。服务端将浏览器的 http 请求转发到后端的 php 服务,php 服务渲染好页面后再返回给浏览器。这种架构用原有的部署方法还能支撑,也就是在各个实例上部署 php 服务,再加一层负载均衡就基本满足需求了。
然而随着业务的持续发展,后端渲染的方式已经不适合我们的项目规模了,因此我们在 2020 年做了架构调整,准备将前后端分离。前后端分离的技术特点我在这里就不赘述了,这里主要讲它给我们带来了哪些系统架构上的挑战。一个是入口增多,因为前后端分离不仅涉及到客户端渲染(CSR),还涉及到服务端渲染(SSR),所以响应请求的服务就从单一的服务变成了两类服务,一类是基于 node.js 的 react server 服务(用来做服务端渲染),另一类是 基于 php 写的 API 服务(用来给客户端渲染提供数据)。而服务端渲染本身还要调用 API,而我们为了优化服务端渲染的连接和请求响应速度,还专门启用了了使用专有通讯协议的内部 API 服务。
所以实际上我们的 WEB SERVER 有三类服务,每种服务的环境各不相同,所需的资源不同,协议不同,各自之间可能还有相互连接的关系,还需要负载均衡来保障高可用。在快速迭代的开发节奏下,使用传统的系统架构很难再去适应这样的结构。
我们迫切需要一种能够快速应用的,方便部署各种异构服务的成熟解决方案。
Kubernetes 带来了什么?
开箱即用
首先是开箱即用,理论上来说这应该是 KubeSphere 的优点,我们直接点一点鼠标就可以打造一个高可用的 K8s 集群。这一点对我们这种没有专职运维的中小团队来说很重要。根据我的亲身经历,要从零开始搭建一个高可用的 K8s 集群还是有点门槛的,没有接触过这方面的运维人员,一时半会是搞不定的,其中的坑也非常多。
如果云厂商能提供这种服务是最好的,我们不用在服务搭建与系统优化上花费太多时间,可以把更多的精力放到业务上去。之前我们还自己搭建数据库,缓存,搜索集群,后来全部都使用云服务了。这也让我们的观念有了转变,云时代的基础服务,应该把它视为基础设施的一部分加以利用。
用代码管理部署
如果能把运维工作全部用代码来管理,那就再理想不过了。而目前 K8s 确实给我们提供了这样一个能力,现在我们每个项目都有一个 Docker 目录,里面放置了不同环境下的 Dockerfile,K8s 配置文件等等。不同的项目,不同的环境,不同的部署,一切都可以在代码中描述出来加以管理。
比如我们之前提到的同样的 API 服务,使用两种协议,变成了两个服务。在这现在的架构下,就可以实现后端代码一次书写,分开部署。其实这些文件就代替了很多部署操作,我们需要做的只是定义好以后执行命令把它们推送到集群。
而一旦将这些运维工作代码化以后,我们就可以利用现有的代码管理工具,像写代码一样来调整线上服务。更关键的一点是,代码化之后无形中又增加了版本管理功能,这离我们理想中的全自动化运维又更近了一步。
持续集成,快速迭代
持续集成标准化了代码发布流程,如果能将持续集成和 K8s 的部署能力结合起来,无疑能大大加快项目迭代速度。而在使用 K8s 之前我们就一直用 GitLab 作为版本管理工具,它的持续集成功能对我们来说也比较适用。在做了一些脚本改造之后,我们发现它也能很好地服务于现有的 K8s 架构,所以也没有使用 K8s 上诸如 Jenkins 这样的服务来做持续集成。
步骤其实也很简单,做好安全配置就没什么问题。我们本地跑完单元测试之后,会自动上线到本地的测试环境。在代码合并到上线分支后,由管理员点击确认进行上线步骤。然后在本地 build 一个镜像推送到镜像服务器,通知 K8s 集群去拉取这个镜像执行上线,最后执行一个脚本来检查上线结果。整个流程都是可视化可追踪的,而且在代码管理界面就可以完成,方便开发者查看上线进度。
总结经验
管理好基础镜像
目前我们用一个专门的仓库来管理这些基础镜像,这可以使开发人员拥有与线上一致的开发环境,而且后续的版本升级也可以在基础镜像中统一完成。
除了将 Dockerfile 文件统一管理以外,我们还将镜像 build 服务与持续集成结合起来。每个 Dockerfile 文件都有一个所属的 VERSION 文件,每次修改里面的版本号并提交,系统都会自动 build 一个相应的镜像并推送到仓库。基础镜像的管理工作完全自动化了,大大减少了人为操作带来的错误与混乱。
KubeSphere 使用
- 别把日志服务放到集群里。这一点在 KubeSphere 文档中就有提及。具体到日志服务,主要就是一个 Elastic 搜索服务,自建一个Elastic 集群即可。因为日志服务本身负载比较大,而且对硬盘的持续性需求高,如果你会发现日志服务本身就占据了集群里相当大的资源,就得不偿失了。
- 如果生产环境要保证高可用,还是要部署 3 个或以上的节点。从我们使用的经验来看,主节点偶尔会出现问题。特别是遇到节点机器要维护或者升级的时候,多个主节点可以保证业务的正常运行。
- 如果你本身不是专门提供数据库或缓存的服务商,这类高可用服务就不要上K8s,因为要保证这类服务高可用本身就要耗费你大量的精力。我建议还是尽量用云厂商的服务。
- 副本的规模和集群的规模要匹配。如果你的容器只有几个节点,但一个服务里面扩展了上百个副本,系统的调度会过于频繁从而把资源耗尽。所以这两者要相匹配,在系统设计的时候就要考虑到。
最后是一点感想:当做完容器化后,会发现应用在集群里运行的时候并不需要占用那么多台服务器。这是因为降低了资源的粒度,所以可以做更多的精细化规划,因此使用效率也提高了。
本文由博客一文多发平台 OpenWrite 发布!
SegmentFault 基于 Kubernetes 的容器化与持续交付实践的更多相关文章
- 云端基于Docker的微服务与持续交付实践
云端基于Docker的微服务与持续交付实践笔记,是基于易立老师在阿里巴巴首届在线技术峰会上<云端基于Docker的微服务与持续交付实践>总结而出的. 本次主要讲了什么? Docker Sw ...
- [置顶]
Docker学习总结(7)——云端基于Docker的微服务与持续交付实践
本文根据[2016 全球运维大会•深圳站]现场演讲嘉宾分享内容整理而成 讲师简介 易立 毕业于北京大学,获得学士学位和硕士学位:目前负责阿里云容器技术相关的产品的研发工作. 加入阿里之前,曾在IBM中 ...
- [持续交付实践] Jenkins Pipeline 高可用设计方法
前言 这篇写好一段时间了,一直也没发布上来,今天稍微整理下了交下作业,部分内容偷懒引用了一些别人的内容.使用Jenkins做持续集成/持续交付,当业务达到一定规模的时候,Jenkins本身就很容易成为 ...
- Docker学习总结(14)——从代码到上线, 云端Docker化持续交付实践
2016云栖大会·北京峰会于8月9号在国家会议中心拉开帷幕,在云栖社区开发者技术专场中,来自阿里云技术专家罗晶(瑶靖)为在场的听众带来<从代码到上线,云端Docker化持续交付实践>精彩分 ...
- ASP.NET Core应用程序容器化、持续集成与Kubernetes集群部署(一)(转载)
本文结构 ASP.NET Core应用程序的构建 ASP.NET Core应用程序容器化所需注意的问题 应用程序的配置信息 端口侦听 ASP.NET Core的容器版本 docker镜像构建上下文(B ...
- IBM基于Kubernetes的容器云全解析
基于Kubernetes的容器云 容器云最主要的功能是以应用为中心,帮助用户把所有的应用以容器的形式在分布式里面跑起来,最后把应用以服务的形式呈现给用户.容器云里有两个关键点,一是容器编排,二是资源调 ...
- 039.[转] 基于 Kubernetes 和 Spring Cloud 的微服务化实践
http://dockone.io/article/2967 基于 Kubernetes 和 Spring Cloud 的微服务化实践 写在前面 网易云容器平台期望能给实施了微服务架构的团队提供完整的 ...
- 容器时代的持续交付工具---Drone:Drone介绍与安装
Drone:Drone is a Container-Native, Continuous Delivery Platform. 官方给的定义,从上面的定义可以得出两个关键点: 1,Container ...
- 联想企业网盘:SaaS服务集群化持续交付实践
1 前言 当代信息技术飞速发展,软件和系统的代码规模都变得越来越大,而且组件众多,依赖繁复,每次新版本的发布都仿佛是乘坐一次无座的绿皮车长途夜行,疲惫不堪.软件交付是一个复杂的工程,涉及到软 ...
- [持续交付实践] Jenkins 中国用户大会参会见闻
前言 上周日在上海召开了Jenkins中国用户大会(Jenkins User Confluence China),这应该是Jenkins在中国第一次举办吧.Jenkins的创始人Kohsuke Kaw ...
随机推荐
- 【转载】 深度学习——Xavier初始化方法
版权声明:本文为CSDN博主「shuzfan」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明.原文链接:https://blog.csdn.net/shuzfan/a ...
- milvus 结果
milvus (2.3.3) 两个查询方法 collection.query(...) 和 collection.search(...) 的返回类型是不同的,用错了会说 attribute error ...
- csv导入导出组件jcsv
jcsv 介绍 jcsv一个简单的.轻量级的csv导入.导出库,相对于opencsv与javacsv,jcsv侧重于导入导出,包括导入校验.导出模板等. 源代码地址:https://gitee.com ...
- Structures, unions, enumerations, and bitfields in ARM C and C++
Structures, unions, enumerations, and bitfields in ARM C and C++ Non-Confidential ARM DUI0375E ARM ...
- 22.11.20 ICPC合肥站 打星记录
A,B,H签到. B题:注意区分相对误差与绝对误差!!小数相对误差小于1e-6,至少要输出十二位! G题优先队列.场上十几分钟就想出来了,表扬自己一波,留个坑位写题解. M题情况不多直接暴搜, 最后一 ...
- zabbix 4.0修改页面LOGO
基本页面展示 一.Logo icon-sprite.svg是一个集合的图片,logo和一级菜单栏里面的图标是在这上面平移得到的 第一种方法 1. zabbix安装好以后的默认LOGO如下: 2. ...
- vs2022不安装docker desktop可以打包镜像吗
vs2022开发的项目可以直接打包镜像到 linux主机. idea 可以使用docker插件直接打包镜像到linux,我想vs2022也可以,于是开始摸索 官网只说支持docker desktop ...
- [kernel] 带着问题看源码 —— 脚本是如何被 execve 调用的
前言 在<[apue] 进程控制那些事儿>一文的"进程创建-> exec -> 解释器文件"一节中,曾提到脚本文件的识别是由内核作为 exec 系统调用处理 ...
- 移除 Parallels Access Sound 虚拟设备
在安装了 Parallels 之后,发现 Mac 没声音,打开声音设置一看音频输出设备被设为了 Parallels Access Sound.把输出设备调回 MacBook 扬声器就有声音了. 但是音 ...
- LCD屏幕显示PNG图像
正点原子LCD屏幕显示PNG图像 本文概要 这段时间在学习正点原子的IMX6ULL开发板,在应用编程中有一个代码练习是需要在LCD屏幕上显示PNG图像,但由于我的屏幕参数和教程中的有些出入,于是经过自 ...