国内最具影响力科技创投媒体36Kr的容器化之路

本文由1月19日晚36Kr运维开发工程师田翰明在Rancher技术交流群的技术分享整理而成。微信搜索rancher2,添加Rancher小助手为好友,加入技术群,实时参加下一次分享~

田翰明,36Kr 运维开发工程师,在 36Kr 主要负责运维自动化,CI/CD 的建设,以及应用容器化的推动。

背景

36Kr是一家创立于2010年,专注于科技创投领域的媒体公司,业务场景并不复杂,前端主要使用NodeJS进行Render,移动端有Android也有iOS,后端服务几乎全都由PHP来支持。使用PHP的主要原因是在最初进行技术选型的时候发现,PHP进行Web开发效率比较高,后来就一直这样延续下来了。

但是在后期,随着业务的突飞猛涨,在程序设计中又没能进行解耦,就导致了许多服务耦合成了一个很臃肿的单体应用,逻辑耦合严重,进而导致了很多的性能问题,随着问题越来越难改,开发任务又越来越紧,就不得不往后拖,越往后拖留下的问题就更难改,形成了一个恶性循环,留下了很多的技术债,很不利于后续的开发任务,并且一旦出现了问题,也很难追溯具体原因,所以在那时候经常听到一句话 “这是历史遗留问题” 。

B/S、C/S、单体应用,这是一种很传统 也很简单的架构,但是缺点也暴露无遗,所以经常因为一个业务逻辑的性能问题,进而影响到所有的业务。在运维侧,运维只能够通过堆机器,升配置等策略来应对,投入了很多的机器成本和人力成本,但是收效甚微,很是被动。

这种情况已经是迫在眉睫了,终于技术团队决定使用 Java 语言进行重构,将单体应用进行微服务化拆解,彻底改变这种因为单体应用故障而导致生产环境出现大范围的故障。

需求分析 + 选型

在重构计划开始一段时间后,为了节省虚机资源,我们一台虚机上运行了多个 Java 程序,但是因为没有资源隔离和灵活的调度系统,其实也会导致一些资源的浪费。并且在高并发场景下,偶尔会有资源抢占导致一个应用影响另一个应用的情况。为此,我们运维专门开发了一套自动化部署系统,系统内包括部署、监控检测、部署失败回滚、重启等基础功能。

随着当时 K8s 的风靡,还有 Rancher 2.x 的发布,我们逐渐发现,我们所面临的这些问题,它们基本都能解决,比如资源隔离、deployment 的控制器模型、灵活的调度系统,这些都有,这就是最好的自动化部署系统啊,于是我们运维侧,也开始决定向容器化进军。

在选型上,因为我们的服务基本都在阿里云上面,所以第一个想到的是阿里云。时因为我们和华为有一些业务的往来,所以华为的 CCE 也作为了备选,但是考虑到我们的服务资源全部在阿里云上,这个迁移成本实在太大了,所以就没再考虑华为云。

我们一开始使用过Rancher 1.6,但是只是用来管理主机上部署的原生 Docker。也因此对Rancher的产品产生了很大的好感。

需求方面,因为要降低我们研发人员的学习成本,容器管理平台的易用性十分重要。此外,K8s 的基础功能是必须的,因为 K8s 还在高速发展阶段,所以能需要够随时跟上更新,有安全漏洞后也需要第一时间进行更新打补丁,同时还要有基本的权限控制。而且我们公司内部没有专门的K8S团队,运维人员也只有2位,所以如果能够有专业人员进行技术上的交流,发生了问题可以有专业的服务团队来协助也十分重要。

综上,基本上就是 Rancher 完胜,UI 做得非常友好,开发人员能够很快上手,更新迭代速度也非常快,发现漏洞后也会有详细的补丁方案,认证策略也完美支持我们的 OpenLDAP 协议,能够对开发、测试、运维人员进行不同权限控制,并且也是第一家做到支持多云环境的,方便以后我们做跨云的方案。

我们这次容器化的过程,主要经历了以下几个因素的考虑,今天我就来和大家分享我们在 Rancher 上的一些实践,希望能给大家带来帮助:

应用的容器化改造

Rancher 的高可用性

容器的运维

多租户隔离

应用的容器化改造

因为我们的开发人员,有相当一部分是没有接触过容器的,为了能对开发人员更友好一些,我们的镜像分成了两层,主要的 Dockerfile 编写是由我们运维人员来编写的,而开发人员代码仓库里的 Dockerfile 是最简单的,基本上只有代码拷贝的过程和一些必传的变量,具体可以参考以下示例:

## 这是运维人员维护的 Dockerfile 示例 ## 本示例仅做参考 FROM alpine:3.8 MAINTAINER yunwei <yunwei@36kr.com> WORKDIR /www RUN mv /etc/apk/repositories /etc/apk/repositories.bak \ && echo "http://mirrors.aliyun.com/alpine/v3.8/main/" >> /etc/apk/repositories \ && apk update && apk upgrade RUN apk --no-cache add ca-certificates wget && \ wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub && \ wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.29-r0/glibc-2.29-r0.apk && \ apk add glibc-2.29-r0.apk && rm -f glibc-2.29-r0.apk RUN apk add -U --no-cache \ bash \ sudo \ tzdata \ drill \ iputils \ curl \ busybox-extras \ && rm -rf /var/cache/apk/* \ && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime COPY java-jar/jdk1.8.0_131 /usr/local/jdk1.8.0_131 ENV TZ="Asia/Shanghai" ENV JAVA_HOME=http://www.likecs.com/usr/local/jdk1.8.0_131 ENV CLASSPATH=$JAVA_HOME/bin ENV PATH=.:$JAVA_HOME/bin:$PATH ENV JAVA_OPTS="-server -Xms1024m -Xmx1024m" CMD java -jar $JAVA_OPTS -Dserver.port=8080 server.jar ======================================= ## 这是开发人员维护的 Dockerfile 的示例 FROM harbor.36kr.com/java:v1.1.1 MAINTAINER developer <developer@36kr.com> ADD web.jar ./server.jar

可以看到,开发人员所维护的 Dockerfile 可以说相当简单了,这大大的降低了开发人员维护的难度。

另外,因为构建产物的大小,很大程度上决定了部署时间的长短,所以我们使用了号称最小的镜像——alpine,alpine 有很多的优点:

体积小

有包管理器、有丰富的依赖

大厂的支持,包含 Docker 公司在内的多家大厂官方使用

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpgsyw.html