MongoDB Kubernetes Operator 简介

K8S 简介

k8s doc | 概述

Kubernetes 是一个可移植、可扩展的开源平台,用于管理容器化的工作负载和服务,可促进声明式配置和自动化。

K8S 框架结构

k8s doc | Kubernetes 架构

Image

k8s 主要分为两个组件:控制平面组件(Control Plane Components)和 Node 组件,控制平面组件又称 master 节点。

  • 控制平面组件:
    • kube-apiserver:上连其余组件,下接 etcd,提供各类 api 处理、鉴权,和 Node 上的 kubelet 通信等
    • etcd:用作 Kubernetes 所有集群数据的后台数据库
    • kube-scheduler:负责调度单个 Pod 及 Pods 集合的资源需求、软硬件及策略约束等
    • kube-controller-manager:控制各类 controller,通过控制器模式,致力于将当前状态转变为期望的状态
  • Node 组件:
    • kubelet:agent,负责管理容器的生命周期
    • kube-proxy:维护节点上的一些网络规则, 管理集群内部或外部的网络会话与 Pod 进行网络通信
    • cri:支持 k8s 容器运行环境接口的容器运行时,负责管理 Kubernetes 环境中容器的执行和生命周期

k8s 的工作流程

工作负载(资源对象)

Pod 是可以在 k8s 中创建和管理的、最小的可部署的计算单元。Pod 是一组(一个或多个) 容器; 这些容器共享存储、网络、以及怎样运行这些容器的声明。

工作负载是在 k8s 上运行的应用程序。在 k8s 中,无论你的负载是由单个组件还是由多个一同工作的组件构成, 你都可以在一组 pod 中运行它。k8s 提供了几个内置的 API 来声明式管理工作负载及其组件。

控制器

在 k8s 中,控制器通过监控集群的公共状态,并致力于将工作负载当前状态转变为工作负载期望的状态。

k8s 组件详细调用流程

参考:Kubernetes 入门教程-阿里云开发者社区

Image

  • 首先 controller-manager, scheduler, kubelet 都会和 apiserver 开始进行 List-Watch 模型,List 是拿到当前的状态,Watch 是拿到期望状态,然后 k8s 集群会致力于将当前状态达到达期望状态。
  • kubectl 下发命令到 apiserver,鉴权处理之后将创建信息存入 etcd,Deployment 的实现是使用 ReplicaSet 控制器,当 controller-manager 提前拿到当前的状态(pod=0),接着接收到期望状态,需要创建 ReplicaSet(pod=1),就会开始创建 Pod。
  • 然后 scheduler 会进行调度,确认 Pod 被创建在哪一台 Node 上。
  • 之后 Node 上的 kubelet 真正拉起一个 docker。

Operator 模式

Operator 模式

Operator 是 k8s 提供的一组扩展,它利用定制资源管理应用及其组件。

k8s 对通用的一些资源对象进行了抽象并设置了对应的控制器,但一些应用程序特定的资源也希望通过 k8s 来自动化管理,因此 k8s 开放了一些接口来定制自定义的资源以及管理这些资源的控制器。总的来说 operator 是自定义控制器 + 自定义资源。

Operator 作为 k8s 的扩展接口,提供了多种语言的 sdk,想要实现自己的 operator 只需要引入对应语言的 sdk 实现对应的接口然后安装到 k8s 中。

MongoDB Kubernetes Operator

github 仓库地址

MongoDB kubernetes operator 提供了 MongoDB 集群资源抽象,并且为其提供了对应的控制器。

我们可以对 MongoDB 集群进行 yaml 格式的资源声明,描述集群的节点版本,用户,节点数量,节点类型等。内置的控制器会识别这些描述并部署起对应的集群,并且对 yaml 声明的修改会触发 k8s 对集群的修改。

MongoDB Kubernetes Operator 社区版提供的功能概述:

  • 创建副本集
  • 升级和降级MongoDB服务器版本
  • 扩缩容副本集
  • 在扩展、升级和降级时读取和写入副本集。这些操作以“始终启动”的方式完成。
  • 通过 MongoDBCommunity 资源字段报告 MongoDB 服务器状态status
  • 使用任何可用的 Docker MongoDB 映像
  • 从 Kubernetes 集群内部连接到副本集(无外部连接)
  • 使用 TLS 保护客户端到服务器和服务器到服务器的连接
  • 使用 SCRAM 身份验证创建用户
  • 创建自定义角色
  • 启用可与 Prometheus 一起使用的指标目标

使用示范

部署一个 Replset MongoDB 集群

  1. 编写 replset 部署模式的 mongodb 集群 yaml 声明:
---
apiVersion: mongodbcommunity.mongodb.com/v1
kind: MongoDBCommunity
metadata:
  name: example-mongodb
spec:
  members: 4
  arbiters: 1
  type: ReplicaSet
  version: "6.0.5"
  security:
    authentication:
      modes: ["SCRAM"]
  users:
    - name: my-user
      db: admin
      passwordSecretRef: # a reference to the secret that will be used to generate the user's password
        name: my-user-password
      roles:
        - name: clusterAdmin
          db: admin
        - name: userAdminAnyDatabase
          db: admin
      scramCredentialsSecretName: my-scram
  additionalMongodConfig:
    storage.wiredTiger.engineConfig.journalCompressor: zlib
 
# the user credentials will be generated from this secret
# once the credentials are generated, this secret is no longer required
---
apiVersion: v1
kind: Secret
metadata:
  name: my-user-password
type: Opaque
stringData:
  password: "123456"
  1. 执行部署
kubectl apply -f xxx.yaml

集群扩容

  1. 修改 yaml 声明文件
---
apiVersion: mongodbcommunity.mongodb.com/v1
kind: MongoDBCommunity
metadata:
  name: example-mongodb
spec:
  members: 6
  arbiters: 1
  type: ReplicaSet
  version: "6.0.5"
  security:
    authentication:
      modes: ["SCRAM"]
  users:
    - name: my-user
      db: admin
      passwordSecretRef: # a reference to the secret that will be used to generate the user's password
        name: my-user-password
      roles:
        - name: clusterAdmin
          db: admin
        - name: userAdminAnyDatabase
          db: admin
      scramCredentialsSecretName: my-scram
  additionalMongodConfig:
    storage.wiredTiger.engineConfig.journalCompressor: zlib
 
# the user credentials will be generated from this secret
# once the credentials are generated, this secret is no longer required
---
apiVersion: v1
kind: Secret
metadata:
  name: my-user-password
type: Opaque
stringData:
  password: "123456"
  1. 应用集群的修改
kubectl apply -f xxx.yaml