VPGAME 是集赛事运营、媒体资讯、大数据分析、玩家社群、游戏周边等为一体的综合电竞服务平台。总部位于中国杭州,在上海和美国西雅图分别设立了电竞大数据研发中心和 AI 研发中心。本文将讲述 VPGAME 将服务器迁移至 Kubernetes 的过程。
背景
随着容器技术的日趋成熟,公司近期计划将服务迁移至容器环境,通过 Kubernetes 对容器进行调度、编排和管理。并借此机会,对服务进行标准化,优化整个 CI/CD 的流程,提高服务部署的效率。
CI/CD 工具的选择
CI/CD 工具上,我们选择了 GitLab-CI。GitLab-CI 就是一套配合 GitLab 使用的持续集成系统,以完成代码提交之后的安装依赖、编译、单元测试、lint、镜像构建以及发布等工作。
GitLab-CI 完美地和 GitLab 进行集成,在使用的时候只需要安装配置 gitlab-runner 即可。GitLab-Runner 在向 GitLab 完成注册后可以提供进行 CI/CD 操作的环境,负责从 GitLab 中拉取代码,根据代码仓库中配置的 gitlab-ci.yml ,执行相应的命令进行 CI/CD 工作。
相比于 Jenkins,GitLab-CI 配置简单,只需在工程中配置 gitlab-ci.yml 文件完成 CI/CD 流程的编写,不需要像在 Jenkins 里一样配置 webhook 回调地址,也不需要 Jenkins 新建这个项目的编译配置。并且个人认为 GitLab 的 CI/CD 过程显示比 Jenkins 更加美观。当然 Jenkins 依靠它丰富的插件,可以配置很多 GitLab-CI 不存在的功能。按照现在我们的需求, GitLab-CI 简单易用,在功能也满足我们的需求。
服务运行环境
容器环境优点
传统的服务部署方式是在操作系统中安装好相应的应用依赖,然后进行应用服务的安装,这种部署方式的缺点是将服务的程序、配置、依赖库以及生命周期与宿主机操作系统紧密地耦合在一起,对服务的升级、扩缩容、迁移等操作不是十分便利。
容器的部署方式则是以镜像为核心,在代码进行编译构建时,将应用程序与应用程序运行所需要的依赖打包成一个镜像,在部署阶段,通过镜像创建容器实例完成服务的部署和运行。从而实现以应用为中心的管理,容器的隔离性实现了资源的隔离,由于容器不需要依赖宿主机的操作系统环境,所以可以很好地保证开发、测试和生产环境的一致性。此外,由于构建好的镜像是不可变的,并且可以通过 tag 进行版本控制,所以可以提供可靠、频繁的容器镜像构建和部署,亦可方便及快速进行回滚操作。
Kubernetes 平台功能
Kubernetes(简称 k8s),作为一个容器调度、编排和管理平台,可以在物理或虚拟机集群上调度和运行应用程序容器,提供了一个以容器为核心的基础架构。通过 Kubernetes,对容器进行编排和管理,可以:
快速、可预测地部署服务
拥有即时扩展服务的能力
滚动升级,完成新功能发布
优化硬件资源,降低成本
阿里云容器服务优势
我们在服务迁移中选用了阿里云的容器服务,它基于原生 Kubernetes 进行适配和增强,简化集群的搭建和扩容等工作,整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳的 Kubernetes 容器化应用运行环境。在便捷性上,可以通过 Web 界面一键完成 Kubernetes 集群的创建、升级以及节点的扩缩容。功能上,在网络、存储、负载均衡和监控方面与阿里云资源集成,在迁移过程中可以最小化减少迁移带来的影响。
此外,在选择集群创建时,我们选择了托管版 Kubernetes,只需创建 Worker 节点,Master 节点由容器服务创建并托管。如此一来,我们在 Worker 节点的规划与资源隔离上还是具备自主性和灵活性的同时不需要运维管理 Kubernetes 集群 Master 节点,可以将更多的精力关注在应用服务上。
GitLab Runner 部署
GitLab CI 工作流程
GitLab CI 基本概念
在介绍 GitLab CI 之前,首先简单介绍一下 GitLab CI 里的一些基本概念,具体如下:
Pipeline:Gitlab CI 里的流水线,每一次代码的提交触发 GitLab CI 都会产生一个 Pipeline。
Stage:每个 Pipeline 由多个 Stage 组成,并且每个 Stage 是有先后顺序的。
Job:GitLab CI 里的最小任务单元,负责完成具有一件事情,例如编译、测试、构建镜像等。每个 Job 都需要指定 Stage ,所以 Job 的执行顺序可以通过制定不同的 Stage 来实现。
GitLab Runner:是具体执行 Job 的环境,每个 Runner 在同一时间只能执行一个 Job。
Executor:每个 Runner 在向 GitLab 注册的时候需要指定 Executor,来决定通过何种类型的执行器来完成 Job。
GitLab CI 的工作流程
当有代码 push 到 GitLab 时,就会触发一个 Pipeline。然后进行编译,测试和镜像构建等操作等操作,其中每一步操作都为一个 Job。在 CD 阶段,会将 CI 阶段构建出来的结果根据情况部署到测试环境或生产环境。
GitLab Runner 介绍
Gitlab Runner 分类
GitLab 中有三种类型的 Runner ,分别为:
shared:所有项目使用
group:group下项目使用
specific:指定项目使用
我们可以根据需要向 GitLab 注册不同类型的 Runner,注册的方式是相同的。
Gitlab Runner 工作过程
Runner 首先会向 GitLab 发起注册请求,请求内容中包含 token、tag 等信息,注册成功后 GitLab 会向 Runner 返回一个 token,后续的请求,Runner 都会携带这个请求。
注册成功后,Runner 就会不停的向 GitLab 请求 Job,时间间隔是 3s。若没有请求到 Job,GitLab 返回 204 No Content。如果请求到 Job,GitLab 会把 Job 信息返回回来,Runner 在接收到 Job 之后,会向 GitLab 发送一个确认请求,同时更新任务的状态。之后,Runner 开始 Job 的执行, 并且会定时地将中间数据,以 Patch 请求的方式发送给 GitLab。
GitLab Runner 的 Executor
Runner 在实际执行 Job 时,是通过调用 Executor 来完成的。Runner 在注册时提供了 SSH、Shell、Docker、docker-ssh、VirtualBox、Kubernetes 等不同类型的 Executor 来满足不同的场景和需求。
其中我们常用的有 Shell 和 Docker 等 Executor,Shell 类型主要是利用 Runner 所在主机的环境进行 Job的执行。而 Docker 类型的 Executor 在每个 Job 开始时,拉取镜像生产一个容器,在容器里完成 Job,在 Job 完成后,对应的容器就会被销毁。由于 Docker 隔离性强、轻量且回收,我们在使用时选用 Docker 类型的 Executor 去执行 Job,我们只要提前做好 Job 所需环境的 Docker 镜像,在每个 Job 定义好 image 即可使用对应的环境,操作便捷。
GitLab Runner 安装与配置
Docker 安装
由于我们需要使用 Docker 类型的 Executor,所以需要在运行 Runnner 的服务器上先安装 Docker,具体步骤如下(CentOS 环境):
安装需要的软件包,yum-util 提供 yum-config-manager 功能,另外两个是 DeviceMapper 驱动依赖:
yum install -y yum-utils device-mapper-persistent-data lvm2
设置 yum 源:
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
安装 Docker:
yum install docker-ce -y
启动并加