Kubernetes|Kubernetes 笔记 / 生产环境

目录、参考文献
生产质量的 Kubernetes 集群需要规划和准备
如果你的 Kubernetes 集群是用来运行关键负载的,该集群必须被配置为弹性的(Resilient)
本页面阐述了在安装生产就绪的集群或将现有集群升级为生产用途时可以遵循的步骤
生产环境考量 【Kubernetes|Kubernetes 笔记 / 生产环境】生产环境可能需要被很多用户安全地访问
需要提供一致的可用性,以及能够与需求变化相适配的资源
随着情况的不同,如 Kubernetes 生产环境将在何处(本地或云端)运行
希望自己的或交给别人的管理工作量有多大
应该考虑以下这些问题如何影响对 Kubernetes 集群的需求:

  • 可用性
    一个单机的 Kubernetes 学习环境具有单点故障问题
    创建高可用的集群需要考虑:
    • 将控制平面与工作节点分开
    • 在多个节点上提供控制平面组件的副本
    • 对流向集群 API 服务器的流量进行负载均衡
    • 为不断变化的负载提供足够多的可用的(或能够迅速变为可用的)工作节点
  • 规模
    如果预期 Kubernetes 生产环境将承受固定量的请求
    则可以针对所需要的容量来一次性完成安装
    如果预期服务请求会随着时间增长,或者因为类似季节或特殊事件的原因而发生剧烈变化
    则需要规划如何处理请求上升时对控制平面和工作节点的压力
    或规划如何缩减集群规模以减少资源的浪费
  • 安全性与访问管理
    在针对运行着重要工作负载的共享集群,用户账户不止一个时
    需要更细粒度的方案来确定谁或者哪些主体可以访问集群资源
    可以使用基于角色的访问控制(RBAC)和其它安全机制来确保用户和负载能够访问到所需要的资源,同时确保工作负载及集群自身仍然是安全的
    可以通过管理策略和容器资源来对用户和工作负载所可访问的资源设置约束
除了自己构造 Kubernetes 生产环境
还可以考虑将这一任务部分或全部交给云解决方案供应商或其它Kubernetes 合作伙伴:
  • Serverless
    在第三方设备上运行负载,完全不必管理集群本身
    需要为 CPU 用量、内存和磁盘请求等付费
  • 托管控制平面
    让供应商决定集群控制平面的规模和可用性,并负责打补丁和升级等操作
  • 托管工作节点
    配置一个节点池来满足需求,由供应商来确保节点始终可用,并在需要的时候完成升级
  • 集成
    有一些供应商能够将 Kubernetes 与一些可能需要的其它服务集成
    这类服务包括存储、容器镜像仓库、鉴权方法以及开发工具等
设置生产环境的集群 在一个生产环境的 Kubernetes 集群中
控制平面会使用不同的方式来管理由可以分布在多个计算机上的服务组成的集群
每个工作节点则代表的是一个可配置来运行 Kubernetes Pod 的实体
生产环境的控制平面 在最简单的 Kubernetes 集群中,整个控制平面和工作节点服务都运行在同一台机器上
如果需要一个持久的、高可用的集群,就需要考虑扩展控制平面的方式
保持集群处于运行状态并确保在出现问题时能够被修复,可以考虑以下步骤:
  • 选择部署工具
    可以使用像 kubeadmkopskubespray 这类工具来部署控制平面
    “使用部署工具安装 Kubernetes”介绍了使用这类部署方法来完成生产环境部署的技巧
    部署时可以选择不同的容器运行时
  • 管理证书
    控制平面服务之间的安全通信是通过证书来完成的
    证书是在部署期间自动生成的,或者也可以使用自己的证书机构来生成它们
    详见 PKI 证书与需求
  • 为 API 服务器配置负载均衡
    配置负载均衡器来将外部的 API 请求分发给运行在不同节点上的 API 服务器服务实例
    详见创建外部负载均衡器
  • 分离并备份 etcd 服务
    etcd 服务可以在其它控制平面服务所在的机器上运行
    也可以在不同的机器上运行以获得更好的安全性和可用性
    因为 etcd 存储着集群的配置数据
    所以应该经常对 etcd 数据库进行备份,以确保在需要时可以恢复该数据库
    与配置和使用 etcd 相关的细节见etcd FAQ
    更多细节见“为 Kubernetes 运行维护 etcd 集群”和“用 kubeadm 配置高可用的 etcd 集群”
  • 创建多个控制平面系统
    为了实现高可用,控制平面不应该只部署在一台机器上
    如果控制平面服务是使用一个 init 服务(如 systemd)来运行的
    则每个服务应该运行在至少 3 台机器上
    将控制平面服务在 Kubernetes 中作为 Pods 运行
    则可确保所请求的服务副本数始终可用
    调度器应该是可容错的,但不是高可用的
    某些部署工具会配置 Raft 共识算法来为 Kubernetes 服务选举 leader
    如果主服务消失,另一个服务会推选自己并接管服务
  • 跨越多个 zone
    如果保持集群一直可用这点非常重要,可以考虑创建一个跨越多个数据中心的集群
    这些数据中心在云环境中被称为 zone,若干个 zone 构成一个 region
    可以通过将集群分散到同一个 region 中的多个 zone 来提高集群的可用性
    即使某个 zone 不可用了,整个集群仍然能够继续工作
    更多的细节见跨越多个 zone 运行
  • 管理不断变化的特性
    如果计划长时间地运行集群,就需要执行一些维护健康与安全的任务
    例如,如果是用 kubeadm 部署的集群
    则有一些可以帮助你完成证书管理和升级 kubeadm 集群的说明
    “管理集群”展示了一个更长的 Kubernetes 管理任务的列表
运行控制平面服务时的可用选项:kube-apiserver、kube-controller-manager、kube-scheduler
高可用控制平面的例子:高可用拓扑结构选项、使用 kubeadm 创建高可用集群、为 Kubernetes 运行 etcd 集群
制定 etcd 备份计划:为 etcd 集群备份
生产环境的工作节点 生产环境的工作负载和所有的依赖(如 CoreDNS)都需要是弹性的
无论是靠自己还是云供应商来管理控制平面,都需要考虑如何管理工作节点(有时也简称为节点)
  • 配置节点
    节点可以是物理机也可以说虚拟机
    要创建与管理自己的节点,可以安装一个受支持的操作系统
    然后添加与运行合适的“节点服务”,考虑:
    • 在安装节点时要通过配置适当的内存、CPU、磁盘速度、存储容量来满足负载需求
    • 通用的计算机系统是否能够满足需求
      是否有负载还需要使用 GPU 处理器、Windows 节点或 VM 隔离
  • 验证节点
    见“设置验证节点”,了解如何确保节点满足加入 Kubernetes 集群的要求
  • 将节点添加到集群
    当自己管理集群时,可以通过配置机器来让节点加入集群
    既可以手动将机器加入集群,也可以让机器自动注册到集群的 API 服务器
    见“节点”,了解如何配置 Kubernetes 以不同的方式添加节点
  • 节点扩缩容
    制定一个计划,让集群今后可以扩展到最终需要的容量
    见“大规模集群考虑事项”,确定所需要的节点数
    这一规模是基于要运行的 Pod 和容器个数来确定的
    如果自己管理集群节点,这可能意味着要购买和安装自己的物理设备
  • 节点自动扩缩容
    大多数云供应商支持“集群自动扩缩器(Cluster Autoscaler)”
    以便替换不健康的节点、根据需求来增加或缩减节点
    见“常见问题”,了解自动扩缩器的工作方式
    见“部署”了解不同云供应商是如何实现集群自动扩缩器的
    对于本地集群,有一些虚拟化平台可以通过脚本来控制按需启动新节点
  • 设置节点健康检查
    对于重要的工作负载,需要确保节点以及在节点上运行的 Pod 处于健康状态
    通过使用“节点问题探测器”可以确保节点是健康的
生产环境的用户管理 在生产环境中,可能不再是你或者一小组人在访问集群,而是几十上百人需要访问集群
在学习环境或者平台原型环境中,可能具有一个可以执行任何操作的管理员账号
但在生产环境中,需要更多不同级别的可以访问不同命名空间的账号
建立一个生产级别的集群,意味着需要决定如何有选择地允许其他用户访问集群
具体而言,需要用一些策略来验证尝试访问集群的人的身份(鉴权)
并确定他们是否有权限执行所请求的操作(授权):
  • 鉴权
    API 服务器可以使用客户端证书、持有者令牌(bearer token)、鉴权代理或 HTTP 基本认证机制来对用户进行鉴权,可以选择要使用的认证方法
    通过插件,API 服务器可以利用组织现有的鉴权方法,如 LDAP 或 Kerberos
    关于这些 Kubernetes 用户鉴权的方法,见“鉴权”
  • 授权
    在为一般用户授权时,可能需要在 RBAC 和 ABAC 之间做出选择
    见“授权概述”,了解为用户账户(以及访问集群的服务账户)授权的不同模式:
    • 基于角色的访问控制(Role-based access control (RBAC))
      通过为鉴权成功的用户授予特定的权限集合来控制对集群的访问
      可以为某个特定的命名空间(角色(Role))分配权限
      或为整个集群(集群角色(ClusterRole))分配权限
      然后通过使用角色绑定(RoleBinding)和集群角色绑定(ClusterRoleBinding)将这些权限分配给特定用户
    • 基于属性的访问控制(Attribute-based access control (ABAC))
      根据集群中的资源属性创建策略
      并根据这些属性允许或拒绝访问
      策略文件的每一行都标识了版本化的属性(apiVersion 和 kind)
      以及一个规范属性的映射
      用来匹配主体(用户或组)、资源属性、非资源属性 (/version 或 /apis)和只读属性,详见“例子”
在生产环境的 Kubernetes 集群中设置鉴权和授权时,要考虑:
  • 设置授权模式
    当启动 Kubernetes API 服务器(kube-apiserver)时
    必须使用 --authorization-mode 设置支持的授权模式
    kube-apiserver.yaml(位于 /etc/kubernetes/manifests)中对应的标志可以设置为 Node,RBAC
    这样就可以为那些成功鉴权的请求使用 Node 和 RBAC 授权
  • 创建用户证书与角色绑定(RBAC)
    如果使用的是 RBAC 授权,用户可以创建一个证书签名请求(CertificateSigningRequest(CSR)),可以由集群 CA 签名
    然后就可以将 Role 和 ClusterRole 绑定到用户
    详见“证书签名请求”
  • 创建结合属性的策略(ABAC)
    如果采用 ABAC 授权,可以分配属性组合来形成策略,为所选用户或用户组授予访问特定资源的权限(如 Pod)、命名空间或 apiGroup
    详见“例子”
  • 准入控制器
    API 服务器请求的其它授权形式包括“Webhook 令牌认证”
    Webhook 和其它的特殊授权类型,需要通过向 API 服务器添加“准入控制器”来开启
为负载资源设置限制 生产环境负载的需求可能对 Kubernetes 的控制平面内外造成压力
配置集群负载时,需要考虑以下这些问题:
  • 设置命名空间限制
    为每个命名空间的内存、CPU 这样的资源设置配额,详见“管理内存、CPU 和 API 资源”
    也可以通过设置“层次结构命名空间”来继承限制
  • 为 DNS 需求做好准备
    如果希望工作负载能够大规模的扩展,就需要让 DNS 服务为扩展做好准备
    见“自动扩缩集群中的 DNS 服务”
  • 创建额外的服务账户
    用户账户决定了用户可以在集群上做什么
    而服务账户则定义了特定命名空间下的 Pod 的访问权限
    默认情况下,Pod 使用所在命名空间中的默认服务账户
    见“管理服务账户”,以了解如何创建新的服务账户
    例如,你可能需要:
    • 为 Pod 添加 secret,Pod 可以用 secret 从某特定容器镜像仓库拉取镜像
      见“为 Pod 配置服务账户”
    • 为服务账户设置 RBAC 权限,详见“服务账户权限”
目录、参考文献

    推荐阅读