热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

k8s使用volume将ConfigMap作为文件或目录直接挂载_K8s应用管理之道有状态服务

摘要:用户通过Deployment、ReplicationController可以方便地在kubernetes中部署一套高可用、可扩展的分布式无状态服务。这类应用不在

摘要: 用户通过 Deployment、ReplicationController 可以方便地在 kubernetes 中部署一套高可用、可扩展的分布式无状态服务。这类应用不在本地存储数据,通过简单的负载均衡策略可实现请求分发。

背景

用户通过 Deployment、ReplicationController 可以方便地在 kubernetes 中部署一套高可用、可扩展的分布式无状态服务。这类应用不在本地存储数据,通过简单的负载均衡策略可实现请求分发。随着 k8s 的普及和云原生架构的兴起,越来越多的人希望把数据库这类有状态服务也通过 k8s 进行编排。但因为有状态服务的复杂性,这一过程并不容易。本文将以最流行的开源数据库 MySQL 为例,介绍如何在 k8s 上部署运维有状态服务。本文所作的调研基于k8s 1.13。

使用 StatefulSet 部署 MySQL

本章将以 k8s 官方教程 Run a Replicated Stateful Application 中提供的样例为基础,介绍如何基于 StatefulSet 部署高可用 MySQL 服务。

StatefulSet 简介

Deployment、ReplicationController 是为无状态服务而设计的,它们中 pod 的名称、主机名、存储都是不稳定的,且 pod 的启动、销毁顺序随机,并不适合数据库这样的有状态应用。为此,k8s 推出了面向有状态服务的工作负载 StatefulSet。其管理的 pod 具有如下特点:

  1. 唯一性 - 对于包含 N 个副本的 StatefulSet,每个 pod 会被分配一个 [0,N)范围内的唯一序号。
  2. 顺序性 - StatefulSet 中 pod 的启动、更新、销毁默认都是按顺序进行的。
  3. 稳定的网络身份标识 - pod 的主机名、DNS 地址不会随着 pod 被重新调度而发生变化。
  4. 稳定的持久化存储 - 当 pod 被重新调度后,仍然能挂载原有的 PersistentVolume,保证了数据的完整性和一致性。

服务部署

这里介绍的高可用 MySQL 服务由一个 master 节点和多个从 master 上异步复制数据的 slave 节点组成,即一主多从复制模型。其中,master 节点可用来处理用户的读写请求,slave 节点只能用来处理用户的读请求。

为了部署这样的服务,除了 StatefulSet 之外,还需要使用许多其它类型的 k8s 资源对象,包括 ConfigMap、Headless Service、ClusterIP Service 等。正是它们间的相互配合,才能让 MySQL 这样的有状态服务有条件运行在 k8s 之上。

5077e61048afe94cebbe91f5d2fa21e5.png

ConfigMap

为了便于维护应用配置,大型系统和分布式应用常常采用集中式的配置管理策略。在 k8s 环境下,用户可以通过 ConfigMap 将配置和 pod 分离,这有助于保持工作负载的可移植性,使其配置更易于更改和管理。

样例包含一个名为mysql的 ConfigMap,当 StatefulSet 中的 pod 启动时,会根据自己的角色从 ConfigMap 中读取合适的配置。

Headless Service

Headless Service 会为关联的每一个 pod 提供对应的 DNS 地址,格式为.。这样,客户端就可以自由地选择想要访问的应用实例,同时也能够解决分布式环境下不同实例之间身份识别的问题。

样例包含一个名为mysql的 Headless Service,该 service 与 StatefulSet 中的 pod 相关联,这些 pod 将被分配如下 DNS 地址mysql-0.mysql、mysql-1.mysql、mysql-2.mysql。这样,客户端就可以通过mysql-0.mysql访问 master 节点,通过mysql-1.mysql或mysql-2.mysql访问 slave 节点。

ClusterIP Service

为了方便只读场景下的访问,样例提供了一个名为mysql-read的普通 service。该 service 拥有自己的 cluster IP,并会将请求分发至关联的 pod(包括 master 和 slave),为用户屏蔽 pod 的访问细节。

StatefulSet

StatefulSet 是服务部署的关键,它管理的每个 pod 会被分配一个唯一的名称,格式为-。样例中的 StatefulSet 名为mysql,因此这些 pod 分别被命名为mysql-0,mysql-1和mysql-2。默认情况下,它们会按顺序创建,并按逆序销毁。

如下图所示,一个 pod 包含 2 个 init container 和 2 个 app container,并且通过唯一的 PersistentVolumeClaim 和存储卷供应方提供的 PersistentVolume 绑定。

b4823da1e97aed33b75f8bbf9b6ba366.png

和 Pod 相关的各个组件的功能如下:

  • 容器init-mysql的主要功能是生成配置文件。它会从 hostname 中提取 pod 序号,并将该序号存入文件/mnt/conf.d/server-id.cnf中。另外,它还会根据节点类型将 master.cnf 或 slave.cnf 从 ConfigMap 中拷贝到/mnt/conf目录下。
  • 容器clone-mysql的主要功能是克隆数据。Pod 编号为N+1的clone-mysql会将数据从编号为N的 pod 中克隆至绑定的 PersistentVolume 里。
  • Init container 运行完成后,app container 开始运行。容器mysql负责运行着真正的 mysqld 服务。
  • 容器xtrabackup以 sidecar 模式运行。当它发现容器mysql中的 mysqld 就绪后,会通过命令START SLAVE启动 slave 节点的数据复制流程。另外,它还会监听来自其它 pod 的数据克隆请求。
  • StatefulSet 通过 volumeClaimTemplates 为每一个 pod 关联了一个独有的 PVC,样例中编号为N的 pod 关联了名为data-mysql-N的 PVC,而这个 PVC 又会和存储系统提供的 PV 绑定。正是这种机制,保证了 pod 被重新调度后仍然能挂载原有的数据。

服务运维

为了保证服务性能、提升系统可靠性,部署工作完成后还需要相应的运维支撑。对于数据库服务,常见的运维工作包括服务故障恢复、服务扩容缩容、服务状态监控、数据备份恢复等。

服务故障恢复

服务在遇到故障时能否自愈,是判断一个系统自动化程度的关键指标。在当前架构下,MySQL 服务在遇到宿主机宕机,master 或 slave 节点崩溃等问题时能自动恢复。在上述问题发生后,k8s 会重新调度遇到问题的 pod,让其重新运行。由于使用了 StatefulSet,这些 pod 的名称、主机名和存储会与原来保持一致。

服务扩容缩容

在 MySQL 一主多从复制模型下,扩容缩容意味着调整 slave 节点个数。得益于 StatefulSet 对 pod 启动、销毁顺序的保证,通过如下命令就可以轻松实现服务的扩容缩容。

kubectl scale statefulset mysql --replicas=

服务状态监控

要保证服务的稳定性离不开对服务运行状态的监控。除了通过就绪探针和活性探针检测服务是否正常外,往往还需要更细粒度的监控指标。用户可以借助 mysqld-exporter 将 MySQL 的核心指标暴露给 prometheus,然后基于 prometheus 做监控告警。对于 mysqld-exporter,推荐以 sidecar 模式和 mysqld 容器部署在同一个 pod 中。

数据备份恢复

数据的备份和恢复是保障数据安全的有效手段。这里,用户可以直接使用存储卷暴露的接口或者利用 VolumeSnapshot 功能完成数据的备份恢复工作,下面分别进行介绍。

使用存储卷接口

许多存储卷供应方都提供了保存数据快照和基于快照恢复数据的功能,这些功能通常以接口的形式暴露给用户。采样这种方式要求用户熟悉对应存储卷供应方提供的操作接口。例如服务选用了阿里云云盘作为外部存储卷,需要用户了解云盘提供的快照接口。

使用 VolumeSnapshot

K8s v1.12 引入了 3 个快照相关的资源对象VolumeSnapshot、VolumeSnapshotContent、VolumeSnapshotClass,通过它们提供了快照操作的标准方法。这样,用户可以在不感知外部存储卷的情况下,为存放 MySQL 数据的存储卷创建快照,或者基于快照恢复数据。

相比直接使用底层存储卷接口,使用 VolumeSnapshot 显然是更为理想的方法。但目前 VolumeSnapshot 还处在 Alpha 阶段,支持标准快照操作的外部存储卷也有限,这些都限制了当下 VolumeSnapshot 的应用场景。想进一步了解 VolumeSnapshot 可参考文档 Volume Snapshots。

使用 Operator 部署 MySQL

虽然用户可以基于 StatefulSet 在 k8s 中部署运维一套高可用 MySQL 服务,但过程相对复杂。用户既要熟悉各种 k8s 资源对象,又要学习很多 MySQL 的操作细节,同时还需维护一套复杂的管理脚本。为了降低在 k8s 中部署复杂应用的门槛,诞生了 Kubernetes Operator。

Operator 简介

Operator 是由 CoreOS 公司推出的,用来打包、部署和管理需要运行在 k8s 之上的复杂应用的一种方法。Operator 将运维人员对软件操作的知识代码化,同时综合运用 k8s 各种资源对象来实现复杂应用的部署和运维。

Operator 通过 CustomResourceDefinition 为服务定义了新的资源对象,同时通过自定义控制器来保证应用处于预期状态。

742d26d73a5ae8e19f6c4963294b2d5f.png

Operator 的工作流程可抽象成以下三个步骤:

  1. Observe - 通过 k8s API 观察目标对象的状态。
  2. Analyze - 分析当前状态与期望状态的差别。
  3. Act - 执行编排操作,将当前状态调整为期望状态。

Oracle MySQL Operator

对于 MySQL 服务,已经有很多优秀的开源 Operator 解决方案,包括 grtl/mysql-operator、oracle/mysql-operator、presslabs/mysql-operator、kubedb/mysql 等。本节将要介绍的 Oracle MySQL Operator 便是这些开源解决方案的典型代表。

Oracle MySQL Operator 工作原理

Oracle MySQL Operator 支持以下 2 种 MySQL 部署模式。

  • Primary - 服务由一个可读写的主节点和多个只读的从节点组成。
  • Multi-Primary - 集群中各节点角色相同,没有主从的概念,每个节点都可以处理用户的读写请求。

下图展示了 Multi-Primary 模式下 Operator 的工作原理。

419e66388225f0369b9bafe18c3809bc.png

下列流程是理解 Operator 工作原理的关键:

  1. 使用 k8s 的 CustomResourceDefinition(CRD) 定义若干和 MySQL 部署运维相关的资源对象。
  • mysqlclusters - 用于描述集群的期望状态,包括部署模式、节点个数等。
  • mysqlbackups - 用于描述按需备份策略,可以配置备份数据的存放地点,如 AWS S3。
  • mysqlrestores - 用于描述数据恢复策略,需要配置备份数据和目标集群。
  • mysqlbackupschedules - 用于描述定期备份策略,可以配置备份的时间间隔。
  1. 在 k8s 中部署一个 Operator 实例,该 Operator 会持续监听针对这些资源对象的 CRUD 操作,并观察对象状态。
  2. 当用户执行了某项操作,例如创建一个 MySQL 集群时,一个新的 MySQLCluster 资源对象会被创建。当 operator 监听到了 MySQLCluster 的创建事件后,会根据用户配置创建符合需求的集群。这里创建了一个基于 Group Replication 的高可用 MySQL 集群,使用了 StatefulSet、Headless service 等原生 k8s 资源对象。
  3. 当 Operator 观察到 MySQLCluster 的当前状态与期望状态存在差别时,会执行相应的编排操作,保证状态的一致性。

服务部署

得益于 Operator 对复杂部署细节的封装,现在创建一个集群变得非常简单。例如,通过如下配置就可以部署一个包含 3 个节点的 MySQL Multi-Primary 集群。

apiVersion: mysql.oracle.com/v1alpha1kind: Clustermetadata: name: mysql-multimaster-clusterspec: multiMaster: true members: 3

服务运维

在 Operator 模式下,同样会涉及服务故障恢复、服务扩容缩容、服务状态监控、数据备份恢复等运维工作。

服务故障恢复

由于 StatefulSet 的存在,当某个 MySQL 服务实例崩溃时,k8s 会对其重新调度。另外,如果 StatefulSet 被误删,Operator 也会对其进行重建。

服务扩容缩容

通过更改资源对象 MySQLCluster 的字段spec.members可以轻松实现服务扩容缩容。这里只对用户暴露了 MySQLCluster,屏蔽了底层 k8s 资源对象。

服务状态监控

可以在 k8s 中部署 Prometheus 监控 Operator 和各个 MySQL 集群的状态。具体步骤可参考文档 Monitoring。

数据备份恢复

可以通过资源对象 MySQLBackup、MySQLRestore 对数据进行备份和恢复,为用户屏蔽了不同存储卷操作上的差别。另外,还可以通过 MySQLBackupSchedule 创建定时备份任务。

例如,以下配置可以每隔 30 分钟对 MySQL 集群mysql-cluster的数据库test进行备份。

[...]kind: BackupSchedulespec: schedule: '*/30 * * * *' backupTemplate: cluster: name: mysql-cluster executor: provider: mysqldump databases: - test[...]总结

本文分别介绍了通过原生 k8s 资源对象 StatefulSet 以及通过 MySQL Operator 部署运维一套高可用 MySQL 服务的方法和原理。可以看到 Operator 屏蔽了复杂应用的编排细节,大大降低了它们在 k8s 中的使用门槛。如果您有其它复杂应用需要部署,建议采用 Operator 方式。

参考资料
  • 亲历者说:Kubernetes API 与 Operator,不为人知的开发者战争

https://yq.aliyun.com/articles/685522

  • Running MySQL on Kubernetes using an operator

https://banzaicloud.com/blog/mysql-on-kubernetes/

扩展阅读
  • K8s 应用管理之道 - 升级篇(一)

https://yq.aliyun.com/articles/688626

  • K8s 应用管理之道 - 升级篇(二)

https://yq.aliyun.com/articles/688627

作者:吴波bruce_wu



推荐阅读
  • ### 优化后的摘要本学习指南旨在帮助读者全面掌握 Bootstrap 前端框架的核心知识点与实战技巧。内容涵盖基础入门、核心功能和高级应用。第一章通过一个简单的“Hello World”示例,介绍 Bootstrap 的基本用法和快速上手方法。第二章深入探讨 Bootstrap 与 JSP 集成的细节,揭示两者结合的优势和应用场景。第三章则进一步讲解 Bootstrap 的高级特性,如响应式设计和组件定制,为开发者提供全方位的技术支持。 ... [详细]
  • 从0到1搭建大数据平台
    从0到1搭建大数据平台 ... [详细]
  • 本文深入探讨了NoSQL数据库的四大主要类型:键值对存储、文档存储、列式存储和图数据库。NoSQL(Not Only SQL)是指一系列非关系型数据库系统,它们不依赖于固定模式的数据存储方式,能够灵活处理大规模、高并发的数据需求。键值对存储适用于简单的数据结构;文档存储支持复杂的数据对象;列式存储优化了大数据量的读写性能;而图数据库则擅长处理复杂的关系网络。每种类型的NoSQL数据库都有其独特的优势和应用场景,本文将详细分析它们的特点及应用实例。 ... [详细]
  • REST与RPC:选择哪种API架构风格?
    在探讨REST与RPC这两种API架构风格的选择时,本文首先介绍了RPC(远程过程调用)的概念。RPC允许客户端通过网络调用远程服务器上的函数或方法,从而实现分布式系统的功能调用。相比之下,REST(Representational State Transfer)则基于资源的交互模型,通过HTTP协议进行数据传输和操作。本文将详细分析两种架构风格的特点、适用场景及其优缺点,帮助开发者根据具体需求做出合适的选择。 ... [详细]
  • 本文详细介绍了如何安全地手动卸载Exchange Server 2003,以确保系统的稳定性和数据的完整性。根据微软官方支持文档(https://support.microsoft.com/kb833396/zh-cn),在进行卸载操作前,需要特别注意备份重要数据,并遵循一系列严格的步骤,以避免对现有网络环境造成不利影响。此外,文章还提供了详细的故障排除指南,帮助管理员在遇到问题时能够迅速解决,确保整个卸载过程顺利进行。 ... [详细]
  • 在过去,我曾使用过自建MySQL服务器中的MyISAM和InnoDB存储引擎(也曾尝试过Memory引擎)。今年初,我开始转向阿里云的关系型数据库服务,并深入研究了其高效的压缩存储引擎TokuDB。TokuDB在数据压缩和处理大规模数据集方面表现出色,显著提升了存储效率和查询性能。通过实际应用,我发现TokuDB不仅能够有效减少存储成本,还能显著提高数据处理速度,特别适用于高并发和大数据量的场景。 ... [详细]
  • 应用链时代,详解 Avalanche 与 Cosmos 的差异 ... [详细]
  • Python 数据可视化实战指南
    本文详细介绍如何使用 Python 进行数据可视化,涵盖从环境搭建到具体实例的全过程。 ... [详细]
  • Docker 中创建 CentOS 容器并安装 MySQL 进行本地连接
    本文详细介绍了如何在 Docker 中创建 CentOS 容器,并在容器中安装 MySQL 以实现本地连接。文章内容包括镜像拉取、容器创建、MySQL 安装与配置等步骤。 ... [详细]
  • 如何在Linux服务器上配置MySQL和Tomcat的开机自动启动
    在Linux服务器上部署Web项目时,通常需要确保MySQL和Tomcat服务能够随系统启动而自动运行。本文将详细介绍如何在Linux环境中配置MySQL和Tomcat的开机自启动,以确保服务的稳定性和可靠性。通过合理的配置,可以有效避免因服务未启动而导致的项目故障。 ... [详细]
  • 在CentOS 7环境中安装配置Redis及使用Redis Desktop Manager连接时的注意事项与技巧
    在 CentOS 7 环境中安装和配置 Redis 时,需要注意一些关键步骤和最佳实践。本文详细介绍了从安装 Redis 到配置其基本参数的全过程,并提供了使用 Redis Desktop Manager 连接 Redis 服务器的技巧和注意事项。此外,还探讨了如何优化性能和确保数据安全,帮助用户在生产环境中高效地管理和使用 Redis。 ... [详细]
  • addInstrumentedPackage 方法不支持指定单一类进行 instrumentation ... [详细]
  • 您的数据库配置是否安全?DBSAT工具助您一臂之力!
    本文探讨了Oracle提供的免费工具DBSAT,该工具能够有效协助用户检测和优化数据库配置的安全性。通过全面的分析和报告,DBSAT帮助用户识别潜在的安全漏洞,并提供针对性的改进建议,确保数据库系统的稳定性和安全性。 ... [详细]
  • 在开发过程中,我最初也依赖于功能全面但操作繁琐的集成开发环境(IDE),如Borland Delphi 和 Microsoft Visual Studio。然而,随着对高效开发的追求,我逐渐转向了更加轻量级和灵活的工具组合。通过 CLIfe,我构建了一个高度定制化的开发环境,不仅提高了代码编写效率,还简化了项目管理流程。这一配置结合了多种强大的命令行工具和插件,使我在日常开发中能够更加得心应手。 ... [详细]
  • 本文深入探讨了 Git 与 SVN 的高效使用技巧,旨在帮助开发者轻松应对版本控制中的各种挑战。通过详细解析两种工具的核心功能与最佳实践,读者将能够更好地掌握版本管理的精髓,提高开发效率。 ... [详细]
author-avatar
灬段裝丶緈褔_998
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有