阿里、蚂蚁、晟腾、中科加禾精彩分享 AI 基础设施洞见,现购票可享受 9 折优惠 |AICon 了解详情
写点什么

经典案例复盘——运维专家讲述如何实现 K8S 落地

  • 2019-01-02
  • 本文字数:3625 字

    阅读完需:约 12 分钟

经典案例复盘——运维专家讲述如何实现K8S落地

背景介绍

运满满自开始微服务改造以来,线上线下已有数千个微服务的 Java 实例在运行中。这些 Java 实例部署在数百台云服务器或虚机上,除少数访问量较高的关键应用外,大部分实例均混合部署。


这些实例的管理,采用自研平台结合开源软件的方式,已实现通过平台页面按钮菜单执行打包、部署、启动、停止以及回滚指定的版本等基本功能,取得了不错的效果。但仍然存在如下几个痛点:


  1. 实例间资源隔离,尤其在高峰期或故障期间,单服务器上不同实例间 CPU 和内存资源的争抢特别明显。

  2. 线上某个应用实例异常时需要人工干预,导致较长的故障时间。

  3. 大批服务端应用新版上线后,如网站关键功能故障,需要针对每个应用,选择对应的版本,执行回滚操作,整个过程耗时较长。

  4. 线下 DEV/QA 环境频繁发布,每次发布都需要先停止老的版本再发布新的版本,会影响到日常测试。


运满满飞速发展的业务,对系统稳定性的要求越来越高,我们急需解决如上问题。

技术调研、选型

最初吸引我们的是容器技术良好的隔离和水平扩展等特性,而 Docker 的口碑以及几年前参与的一些 Docker 项目经验,使得采用 Docker 容器技术成了我们的不二选择。


但我们仍然需要一套容器编排系统,来实现自动化管理 Docker 容器,大致了解下来有 3 个选项:Kubetnetes(K8S)、swarm、mesos


这 3 个我们都不熟悉,而这个项目的节奏很紧迫,不允许我们对这 3 个系统深入了解后再做选择。好在 Github 有一个统计功能,我们在 Github 上查到了这 3 个开源项目的一些基本情况,如下图:





根据这份统计数据,以及拥有 Google 公司的光环,我们在很短的时间内确定了使用 K8S 作为容器编排管理系统。K8S,这个开源项目号称可以自动部署、扩展和管理容器应用,并且能解决如下核心问题:


负载均衡 - 一个应用运行多个同样的容器,内部 Service 提供了统一的访问定义,以负载均衡的方式来提供访问。


服务发现 - Service 和 Kube-DNS 结合,只需要通过固定的 Service 名称就可以访问到对应的容器,不需要独立寻找使用服务发现组件。


高可用 - K8S 会检查服务的健康状态,发现异常时会自动尝试重新启动服务,保障正常运行。


滚动升级 - 在升级过程中 K8S 会有规划的挨个容器滚动升级,把升级带来的影响降低到最小。


自动伸缩 - 可以配置策略当容器资源使用较高会自动增加新的容器来分担压力,当资源使用率降低会回收容器。


快速部署 - 编写好对应的编排脚本,可以在极短的时间部署一套环境。


资源限制 - 对程序限制最大资源使用量避免抢占资源遇到事故或压力也能从容保障基础服务不受影响。


进一步深入了解 K8S 之后,我们大致确定了会用到如下组件、相关技术和系统:


  • 应用部署 K8S Deployment,HPA;

  • 少量基础服务 K8S Daemonset, kube-dns;

  • 对外服务暴露 K8S Ingress, Traefik, Service;

  • 网络插件 Flannel;

  • 监控告警 Heapster, InfluxDB, Grafana, Prometheus;

  • 管理界面 Kubectl, Dashboard, 自研发布管理系统;

  • 制作镜像 Jenkins, Maven, Docker;

  • 镜像仓库 Harbor;

  • 日志收集 Filebeat, Kafka, ELK。

难点和基本原则

  1. 线上服务必须在不间断提供服务的情况下迁移,每个应用按比例切分流量,在确保稳定性的前提下迁移到 K8S 集群中。

  2. DEV 环境可批量上线,QA 和 Production 环境上线需要考虑各应用的版本依赖关系。

  3. 初期只上无状态的应用。

  4. 对研发/QA 的影响最小化(尽量不给繁忙的研发/QA 同学增加工作量)。

落地过程剖析

Docker 化前后应用发布流程对比

从下图中可以看到 2 个明显的变化:


  1. 之前部署的是 war 包、jar 包,之后部署的是 Docker 镜像(镜像中包含 war 包、jar 包)。

  2. 之前是先停止再启动应用进程,发布过程中服务会中断,之后是先启动新版本容器,再停止旧版本容器,发布过程中应用一直在提供服务。


迁移中的系统架构

当前业务应用主要分为 2 种,仅供内部应用调用的 RPC 服务(Pigeon 框架)和对外提供服务的 REST API,REST API 可进一步细分为 2 种,已接入 API 网关和未接入 API 网关。其中 RPC 服务和已接入 API 网关的应用均有自己的注册中心,迁移步骤相对简单,在 K8S 集群中启动对应的应用即可。未接入 API 网关的应用采用 K8S Ingress 插件提供对外服务入口,需要一些配置。系统架构如下图,最终目标是要实现将图中下方的两个框内的应用全部迁入 K8S 集群中。


Master 集群的高可用

由于公有云的限制,我们主要结合服务商提供的 SLB 来实现,示意图如下:


K8S 集群内应用对外提供服务

由于集群内 POD 的 IP 地址动态变化,我们采用 Traefik+Ingress+Nginx+SLB 的方式,来提供一个对外服务的统一入口。Traefik 根据 HTTP 请求的域名和路径路由到不同的应用服务,Nginx 则执行一些复杂的诸如 rewrite 等操作,SLB 提供高可用。架构示意图如下:


容器内应用初始化

为了实现同一个镜像可以兼容运行在 DEV、QA、Production 等各种环境,必须编写一个初始化脚本,该脚本被存放在镜像中。当容器启动时,从 Env 变量中读取当前所在的环境,并创建一系列软链到各环境对应的配置文件以及设置日志目录等其他初始化操作,随后 fork 一个新进程用于检测和设置该容器内应用是否已完成正常启动(配合容器 readiness 探针使用),同时调用应用启动脚本。


下图为容器内通过软链指向不同的环境配置文件:



下图为容器内通过软链设置日志目录:


K8S 日志收集

当前应用日志均以文件形式存放,且单个实例对应多个日志文件,无法采用 K8S 官方推荐的日志方案。同时由于容器的无状态化,我们必须另想其他办法保存日志。目前采用的是将 Node 上的固定目录作为存储卷挂载到容器内,在容器启动时通过初始化脚本按照应用名+容器 IP 生成该容器特定的日志路径。为了便于查看日志,我们提供 3 种途径:


  1. 容器内启用 SSH 服务端,发布管理系统中实现 WEBSSH,正常情况下可通过 WEB 页面进入容器命令行查看日志,由于其便利性,推荐首选此方式。

  2. 有些情况下容器会启动失败,此时无法进入命令行,可在发布管理系统中找到日志的链接地址,下载到本机后再查看。

  3. 此外,我们在所有 Node 上各运行一个 Filebeat 容器,将 Node 上收集到的日志实时发送到 Kafka 集群中,经过处理后存储到 ES 集群,以便日后检索。


下图为 Node 服务器上的日志目录结构:



下图为 Node 服务器上共享的日志下载路径:


K8S 监控

采用 Heapster+InfluxDB+Grafana 组合,需要注意的是其中 InfluxDB 用于存放监控数据,需要将数据持久化。在 Grafana 上制作了不同维度的 dashboard,可根据 Namespace、Node、应用名进行检索,可按照 CPU、内存、网络带宽、硬盘使用量筛选应用,方便故障排查和日常优化。(当然,更好的监控系统是 Prometheus,已经在上线的路上。)


下图为监控大盘:



下图为监控菜单:



下图为某应用的监控图:


Harbor 镜像仓库

Harbor 我们目前采用的是一主多从结构,主库与打包 Jenkins 都在线下网络中,镜像上传到主库后会被自动同步到线下另一个从库以及线上的从库中,如下图所示:


镜像树

我们的规划是构建一颗镜像树,所有的应用都基于这颗树上的基础镜像来构建应用镜像,各应用构建时选择最相似的基础镜像,再增加应用的特殊需求即可。基于此镜像树,我们 95%以上的应用均无需在 Gitlab 里放置 Dockerfile,Dockerfile 在打包时根据变量自动生成即可,例如:


下图为脚本自动生成的某应用 Dockerfile:



镜像树结构示意图如下:


当前状态

容器化:DEV/QA 环境的应用已完成 Docker 化,产品环境中应用约 98%已完成 Docker 化。


系统自愈:应用 OOM 或其他 Crash 时,系统能够自动拉起新的节点以替换故障节点,高级健康检查暂未开启(需其他方面配合)。


弹性伸缩:关键应用全部开启弹性伸缩,访问量高峰期观察到的效果很好。


滚动发布:可按指定的比例分批次部署更新应用版本,先更新一批,成功后销毁一批,依次滚动。


快速回滚:当前仅支持单应用快速回滚,后期如需要增加事务级回滚能力,采用 K8S 的 rollout 功能可以方便实现。

一些踩过的坑和建议

  1. 底层操作系统采用 CentOS7.x 版本,会比较省事。

  2. 阿里云经典网络中的 ECS 无法访问容器 IP,需要先迁移到 VPC 环境,其他公有云情况类似,重点是能自主添加路由。

  3. 如果有应用级监控的话,从容器内部采集到的 Memory,Load Average 等信息是底层操作系统的,而不是容器的,这些指标可以依赖专门的容器监控系统。

  4. 要注意 ulimit 的限制,容器中并没有对它进行隔离,设置过小的话会遇到一些莫名其妙的问题。

  5. 容器中的 root 用户用 netstat 命令可能看不到其他用户所创建的进程的 owner,如果有一些老式的脚本可能会遇到类似问题。

  6. 如果有一些内部系统需要直接访问容器的特定端口,headless service 挺好用。

  7. Zookeeper 有一个单 IP 连接数 60 的默认限制,如果没修改过该参数的话应用迁移到 K8S 之后可能会遇到此问题。

  8. 产品环境中的某个访问量大的应用往 K8S 迁移时,可以先分配较多数量的容器,确保能吃下所有流量,之后再根据监控,用弹性伸缩功能来减掉多余的容器。

  9. 如果想提前知道 K8S 集群的性能,部署好应用之后做一次压测很有必要。




作者简介


王春林,就职于运满满技术保障部,关注容器、DevOPS 等领域。


2019-01-02 14:179232

评论 4 条评论

发布
用户头像
请问一下, 有状态服务如mysql, redis, rocketmq是如何部署的。直接通过stateset部署在k8s里么?
2020-04-16 14:11
回复
用户头像
想问了一下不算业务系统,用了多少台机器,什么配置,多少个服务实例,每个服务多少个副本
2019-01-02 15:27
回复
建议的配置:
Master:2台~3台,每台8核16G,量少4核8G
ETCD:3台或5台(保持奇数),每台8核16G,量少4核8G
应用:每个服务至少2个副本
2019-01-25 14:34
回复
没有更多了
发现更多内容

诊所数字化:连锁型诊所应用远程会诊做分级诊疗

boshi

数字化医疗 七日更 28天写作

2021版面试必问178条性能优化建议!(Java+JVM+Redis+MySQL等)

Java架构追梦

Java 架构 面试 性能优化 金三银四跳槽

第一篇文章

棉花糖

到底什么是敏捷

Teobler

敏捷 敏捷开发 敏捷精髓 敏捷书籍

LeetCode题解:718. 最长重复子数组,动态规划,JavaScript,详细注释

Lee Chen

算法 大前端 LeetCode

3分钟学会如何上手supervisor看门狗

happlyfox

Linux centos7 28天写作 2月春节不断更

使用Kong作为微服务网关

行者AI

kong

Oracle sqlldr快速导入和sqluldr2快速导出

阳光下、慵懒的熊

数据库

DCache 分布式存储系统|K-K-Row 缓存模块的创建与使用

TARS基金会

MySQL 数据库 nosql 分布式存储 TARS

简述:一款优秀的缺陷管理系统有哪些功能特点!

优秀

缺陷管理系统

话题讨论 | 英语对IT从业人员重要吗?

happlyfox

IT 话题讨论 28天写作 2月春节不断更 话题王者

国产芯片WiFi物联网智能插座—电源功能设计

不脱发的程序猿

28天写作 二月春节不断更 智能插座 WiFi物联网智能插座 电源设计

添加小助理vx:mxzFAFAFA即可!!

比伯

Java 编程 架构 面试 计算机

Git教程--git merge命令

生之欢愉,时间同行

git 程序员 git merge

优化软件测试成本的7个步骤

程序员阿沐

软件测试 自动化测试 测试工程师 黑盒测试 白盒测试

技术干货 | 趣谈哈希表优化:从规避 Hash 冲突到利⽤ Hash 冲突

百度开发者中心

算法 数据结构和算法

【文末彩蛋】数据仓库服务 GaussDB(DWS)单点性能案例集锦

华为云开发者联盟

sql 数据仓库 数据

魔改出一个 Encoder | Rust 学习笔记(一)

李大狗

区块链 rust 入门

2021金三银四涨薪季,这些面试题都掌握了嘛?

ios 面试

Centos7配置librdkafka运行时

happlyfox

Centos 7 28天写作 2月春节不断更

华为云“网红”语言Python课程来啦!

华为云开发者联盟

Python

常见的初级排序算法,这次全搞懂

Silently9527

Java 排序算法

安卓天气app开发!2021年Android开发者跳槽指南,社招面试心得

欢喜学安卓

android 程序员 面试 移动开发

研发效能的历史和未来

李小腾

研发效能 数据驱动

话题讨论 | 在中国程序员工作是青春饭吗?

happlyfox

话题讨论 2月春节不断更 话题王者

开工来面试了几十个人,一言难尽

yes

面试

技术干货 | 中间件技术在百度云原生测试中的应用实践

百度开发者中心

底层技术 #技术干货#

国产芯片WiFi物联网智能插座—项目简介

不脱发的程序猿

物联网 28天写作 二月春节不断更 WiFi物联网插座 智能插座

安卓软件开发教程!全世界都在问Android开发凉了吗?offer拿到手软

欢喜学安卓

android 程序员 面试 移动开发

日记 2021年2月25日(周四)

Changing Lin

2月春节不断更

运维工程师小张的日记

XSKY星辰天合

经典案例复盘——运维专家讲述如何实现K8S落地
_软件工程_王春林_InfoQ精选文章