第 2 章 基础架构组件
2.1. Kubernetes 基础架构
2.1.1. 概述
在 OpenShift Container Platform 中,Kubernetes 在一组容器或主机间管理容器化应用,并提供部署、维护和应用程序的扩展机制。容器运行时软件包、实例化和运行容器化应用。Kubernetes 集群由一个或多个 master 和一组节点组成。
您可以选择将 master 配置为高可用性 (HA),以确保集群没有单点故障。
OpenShift Container Platform 使用 Kubernetes 1.11 和 Docker 1.13.1。
2.1.2. Master
master 是包含 control plane 组件的主机或主机,包括 API 服务器、控制器管理器服务器和 etcd。master 用于管理其 Kubernetes 集群中的节点,并调度 pod 以便在这些节点上运行。
组件 | 描述 |
---|---|
API Server | Kubernetes API 服务器验证并配置 pod、服务和复制控制器的数据。它还将 pod 分配给节点,并将 pod 信息与服务配置同步。 |
etcd | etcd 存储持久 master 状态,而其他组件会监视 etcd 的更改,以自行进入所需状态。etcd 可以配置为高可用性,通常使用 2n+1 对等服务部署。 |
Controller Manager Server | 控制器管理器服务器监视 etcd 是否有复制控制器对象的更改,然后使用 API 强制执行所需的状态。多个这样的过程会创建在某个时间点上有一个活跃群首的集群。 |
HAProxy |
可选,用于配置高可用性 master,使用 |
2.1.2.1. Control Plane 静态 Pod
核心 control plane 组件、API 服务器和控制器管理器组件,作为 kubelet 操作 的静态 pod 运行。
对于在同一主机上还存在 etcd 的 master,etcd 也会变为静态 pod。在不是 master 的 etcd 主机上仍然支持基于 RPM 的 etcd。
另外,节点组件 openshift-sdn 和 openvswitch 现在可以使用 DaemonSet 而不是 systemd 服务运行。
图 2.1. control plane 主机架构更改
即使作为静态 pod 运行 control plane 组件,master 主机仍然会从 /etc/origin/master/master-config.yaml 文件中提供其配置,如 Master 和 Node Configuration 所述。
启动序列概述
Hyperkube 是一个包含所有 Kubernetes 的二进制文件(kube-apiserver, controller-manager, scheduler, proxy, 和 kubelet)。在启动时,kubelet 创建 kubepods.slice。接下来,kubelet 在 kubepods.slice 中创建 QoS 级别片段 burstable.slice 和 best-effort.slice。当 pod 启动时,kubelet 使用格式为 pod< UUID-of-pod>.slice
的 pod 级别片段,并将该路径传递给容器运行时接口(CRI)的另一端的运行时。然后,Docker 或 CRI-O 会在 pod 级别片段中创建容器级别的片段。
镜像 Pod
master 节点上的 kubelet 会自动在 API 服务器上为每个 control plane 静态 pod 创建镜像 pod,以便 kube-system 项目中的集群可见。默认情况下,openshift-ansible 安装程序会安装这些静态 pod 的清单,位于 master 主机上的 /etc/origin/node/pods 目录中。
这些 pod 定义了以下 hostPath
卷:
/etc/origin/master | 包含所有证书、配置文件和 admin.kubeconfig 文件。 |
/var/lib/origin | 包含二进制文件的卷和潜在的内核转储。 |
/etc/origin/cloudprovider | 包含特定于云供应商的配置(AWS、Azure 等)。 |
/usr/libexec/kubernetes/kubelet-plugins | 包含其他第三方卷插件。 |
/etc/origin/kubelet-plugins | 包含系统容器的其他第三方卷插件。 |
您可以在静态 pod 上执行的操作集合有限。例如:
$ oc logs master-api-<hostname> -n kube-system
返回 API 服务器的标准输出。然而:
$ oc delete pod master-api-<hostname> -n kube-system
不会实际删除 pod。
再如,集群管理员可能需要执行一个常见操作,如增加 API 服务器的日志级别
,以便在出现问题时提供更详细的数据。您必须编辑 /etc/origin/master/master.env 文件,其中 OPTIONS
变量中的 --loglevel
参数可以被修改,因为此值被传递给容器中运行的进程。更改需要重启容器中运行的进程。
重启主服务
要重启在 control plane 静态 pod 中运行的 control plane 服务,请在 master 主机上使用 master-restart
命令。
重启 master API:
# master-restart api
重启控制器:
# master-restart controllers
重启 etcd:
# master-restart etcd
查看主服务日志
要查看在 control plane 静态 pod 中运行的 control plane 服务的日志,请为对应的组件使用 master-logs
命令:
# master-logs api api
# master-logs controllers controllers
# master-logs etcd etcd
2.1.2.2. 高可用性 Master
您可以选择将 master 配置为高可用性(HA),以确保集群没有单点故障。
要减少有关 master 可用性的问题,建议进行两个操作:
在生产环境的 OpenShift Container Platform 集群中,您必须维护 API 服务器负载均衡器的高可用性。如果 API 服务器负载均衡器不可用,节点无法报告其状态,则所有 pod 都会标记为 dead,pod 的端点也会从服务中删除。
除了为 OpenShift Container Platform 配置 HA 之外,还必须为 API 服务器负载均衡器单独配置 HA。要配置 HA,最好集成一个企业负载均衡器(LB),例如 F5 Big-IP™ 或 Citrix Netscaler™ 设备。如果此类解决方案不可用,可以运行多个 HAProxy 负载均衡器,并使用 Keepalived 为 HA 提供浮动虚拟 IP 地址。但是,不建议在生产环境中使用这个解决方案。
当在 HAProxy 中 使用原生
HA 方法时,master 组件有以下可用性:
角色 | 样式 | 备注 |
---|---|---|
etcd | Active-active | 具有负载平衡的完全冗余部署。可以安装在单独的主机上,也可以将 collocated 安装到 master 主机上。 |
API Server | Active-active | 由 HAProxy 管理. |
Controller Manager Server | Active-passive | 一个实例被选为集群领导。 |
HAProxy | Active-passive | 在 API 主(master)端点之间进行负载平衡。 |
虽然集群 etcd 需要奇数个主机的仲裁数,但 master 服务没有奇数个主机的仲裁数或要求。但是,因为您需要至少两个 master 服务用于 HA,因此在找到 master 服务和 etcd 时,通常要维护一个统一奇数的主机。
2.1.3. 节点
节点为容器提供运行时环境。Kubernetes 群集中的每个节点都需要由主控机管理的服务。节点也具有运行 pod 所需的服务,包括容器运行时、kubelet 和服务代理。
OpenShift Container Platform 从云供应商、物理系统或虚拟系统创建节点。Kubernetes 与代表这些节点的节点对象进行交互。主控机(master)使用来自节点对象的信息执行健康检查,以此验证节点。在通过健康检查前,节点会被忽略,master 会继续检查节点,直到节点有效。Kubernetes 文档包含有关节点状态和管理的更多信息。
管理员可以使用 CLI 在 OpenShift Container Platform 实例中管理节点。要在启动节点服务器时定义完整的配置和安全选项,请使用 专用节点配置文件。
有关推荐的节点数,请参阅集群限制部分。
2.1.3.1. kubelet
每个节点都有一个 kubelet,它更新由容器清单指定的节点,它是一个描述 pod 的 YAML 文件。kubelet 使用一组清单来确保其容器已启动并且它们继续运行。
容器清单可以通过以下方法提供给 kubelet:
- 命令行中每 20 秒检查一次的文件路径。
- 一个 HTTP 端点会传递到命令行,它每 20 秒检查一次。
- kubelet 监视 etcd 服务器,如 /registry/hosts/$(hostname -f),并作用于任何更改。
- kubelet 侦听 HTTP 并响应简单的 API 来提交新清单。
2.1.3.2. 服务代理
每个节点还运行一个简单的网络代理,它反映了节点上 API 中定义的服务。这允许节点在一组后端上执行简单的 TCP 和 UDP 流转发。
2.1.3.3. 节点对象定义
以下是 Kubernetes 中的节点对象定义示例:
apiVersion: v1 1 kind: Node 2 metadata: creationTimestamp: null labels: 3 kubernetes.io/hostname: node1.example.com name: node1.example.com 4 spec: externalID: node1.example.com 5 status: nodeInfo: bootID: "" containerRuntimeVersion: "" kernelVersion: "" kubeProxyVersion: "" kubeletVersion: "" machineID: "" osImage: "" systemUUID: ""
2.1.3.4. 节点引导
节点的配置从 master 启动,这意味着节点会从 master 拉取其预定义配置和服务器证书。这可通过减少节点之间的区别以及集中更多配置并让集群在所需状态进行聚合,从而加快节点启动速度。证书轮转和集中式证书管理会被默认启用。
图 2.2. 节点 bootstrap 工作流概述
当节点服务启动时,节点会在加入集群前检查 /etc/origin/node/node.kubeconfig 文件和其他节点配置文件是否存在。如果不存在,节点将从 master 中拉取配置,然后加入集群。
ConfigMap 用于在集群中存储节点配置,这会在节点主机上的 /etc/origin/node/node-config.yaml 填充配置文件。有关默认节点组及其 ConfigMap 集合的定义,请参阅在安装集群中定义节点组和主机映射。
节点 Bootstrap 工作流
自动节点 bootstrap 过程使用以下工作流:
默认情况下,会在集群安装过程中创建一组
clusterrole
、clusterrolebinding
和serviceaccount
对象以用于节点引导:system:node-bootstrapper 集群角色用于在节点引导期间创建证书签名请求(CSR):
$ oc describe clusterrole.authorization.openshift.io/system:node-bootstrapper
输出示例
Name: system:node-bootstrapper Created: 17 hours ago Labels: kubernetes.io/bootstrapping=rbac-defaults Annotations: authorization.openshift.io/system-only=true openshift.io/reconcile-protect=false Verbs Non-Resource URLs Resource Names API Groups Resources [create get list watch] [] [] [certificates.k8s.io] [certificatesigningrequests]
以下 node-bootstrapper 服务帐户是在 openshift-infra 项目中创建的:
$ oc describe sa node-bootstrapper -n openshift-infra
输出示例
Name: node-bootstrapper Namespace: openshift-infra Labels: <none> Annotations: <none> Image pull secrets: node-bootstrapper-dockercfg-f2n8r Mountable secrets: node-bootstrapper-token-79htp node-bootstrapper-dockercfg-f2n8r Tokens: node-bootstrapper-token-79htp node-bootstrapper-token-mqn2q Events: <none>
以下 system:node-bootstrapper 集群角色绑定用于节点 bootstrapper 集群角色和服务帐户:
$ oc describe clusterrolebindings system:node-bootstrapper
输出示例
Name: system:node-bootstrapper Created: 17 hours ago Labels: <none> Annotations: openshift.io/reconcile-protect=false Role: /system:node-bootstrapper Users: <none> Groups: <none> ServiceAccounts: openshift-infra/node-bootstrapper Subjects: <none> Verbs Non-Resource URLs Resource Names API Groups Resources [create get list watch] [] [] [certificates.k8s.io] [certificatesigningrequests]
另外,在集群安装过程中,openshift-ansible 安装程序会在 /etc/origin/master 目录中创建 OpenShift Container Platform 证书颁发机构和各种其他证书、密钥和 kubeconfig 文件。注意的两个文件有:
/etc/origin/master/admin.kubeconfig
使用 system:admin 用户。
/etc/origin/master/bootstrap.kubeconfig
用于不是 master 节点的 bootstrap 节点。
在安装程序使用 node-bootstrapper 服务帐户时,会创建 /etc/origin/master/bootstrap.kubeconfig,如下所示:
$ oc --config=/etc/origin/master/admin.kubeconfig \ serviceaccounts create-kubeconfig node-bootstrapper \ -n openshift-infra
- 在 master 节点上,/etc/origin/master/admin.kubeconfig 用作引导文件,并复制到 /etc/origin/node/boostrap.kubeconfig。在另外一个非 master 节点上,/etc/origin/master/bootstrap.kubeconfig 文件会复制到每个节点主机上的 /etc/origin/node/boostrap.kubeconfig 的所有其他节点上。
然后,使用
--bootstrap-kubeconfig
标记将 /etc/origin/master/bootstrap.kubeconfig 传递给 kubelet,如下所示:--bootstrap-kubeconfig=/etc/origin/node/bootstrap.kubeconfig
- kubelet 首先使用提供的 /etc/origin/node/bootstrap.kubeconfig 文件启动。在初始内部连接后,kubelet 创建证书签名请求(CSR)并将其发送到 master。
CSR 通过控制器管理器(特别是证书签名请求)进行验证和批准。如果批准,kubelet 客户端和服务器证书会在 /etc/origin/node/ceritificates 目录中创建。例如:
# ls -al /etc/origin/node/certificates/
输出示例
total 12 drwxr-xr-x. 2 root root 212 Jun 18 21:56 . drwx------. 4 root root 213 Jun 19 15:18 .. -rw-------. 1 root root 2826 Jun 18 21:53 kubelet-client-2018-06-18-21-53-15.pem -rw-------. 1 root root 1167 Jun 18 21:53 kubelet-client-2018-06-18-21-53-45.pem lrwxrwxrwx. 1 root root 68 Jun 18 21:53 kubelet-client-current.pem -> /etc/origin/node/certificates/kubelet-client-2018-06-18-21-53-45.pem -rw-------. 1 root root 1447 Jun 18 21:56 kubelet-server-2018-06-18-21-56-52.pem lrwxrwxrwx. 1 root root 68 Jun 18 21:56 kubelet-server-current.pem -> /etc/origin/node/certificates/kubelet-server-2018-06-18-21-56-52.pem
- 在 CSR 批准后,node.kubeconfig 文件会在 /etc/origin/node/node.kubeconfig 中创建。
- kubelet 使用 /etc/origin/node/node.kubeconfig 文件以及 /etc/origin/node/certificates/ 目录中的证书重启,直到它准备好加入集群。
节点配置工作流
为节点配置提供使用以下工作流:
- 最初,节点的 kubelet 是在节点置备时创建的 /etc/origin/node/ 目录中的 bootstrap-node-config.yaml 启动。
- 在每个节点上,节点服务文件使用 /usr/local/bin/ 目录中的本地脚本 openshift-node 来通过提供的 bootstrap-node-config.yaml 启动 kubelet。
- 在每个 master 上,目录 /etc/origin/node/pods 包含 apiserver 的 pod 清单,控制器和 etcd 在 master 上作为静态 pod 创建。
在集群安装过程中,会创建一个同步 DaemonSet,在每个节点上创建一个同步 pod。sync(同步)pod 会监控文件 /etc/sysconfig/atomic-openshift-node 中的更改。它专门用于监视要设置的
BOOTSTRAP_CONFIG_NAME
。BOOTSTRAP_CONFIG_NAME
由 openshift-ansible 安装程序设置,它是根据节点所属节点配置组的 ConfigMap 名称。默认情况下,安装程序会创建以下节点配置组:
- node-config-master
- node-config-infra
- node-config-compute
- node-config-all-in-one
- node-config-master-infra
在 openshift-node 项目中为每个组创建一个 ConfigMap。
-
同步 pod 根据
BOOTSTRAP_CONFIG_NAME
中设置的值提取适当的 ConfigMap。 - 同步 pod 将 ConfigMap 数据转换为 kubelet 配置,并为该节点主机创建一个 /etc/origin/node/node-config.yaml。如果对此文件进行了更改(或者是文件的初始创建),则 kubelet 会重启。
修改节点配置
通过编辑 openshift-node 项目中的相应 ConfigMap 来修改节点的配置。不要直接修改 /etc/origin/node/node-config.yaml。
例如,对于 node-config-compute 组中的节点,使用以下内容编辑 ConfigMap:
$ oc edit cm node-config-compute -n openshift-node