Skip to content

集群架构,安装和配置(25%)

1. 管理基于角色的访问控制(RBAC)

Manage role based access control (RBAC)

1.1 介绍

  • Role 和 ClusterRole: 角色权限分配,集群级别的可以访问非资源类型、所有 namespace 以及集群范围的资源;
  • RoleBinding 和 ClusterRoleBinding: 科目角色授权,区别在于是否能跨 namespace 的权限,ClusterRole-RoleBinding 作为通用设置,所有 namespace 可用,分配后只能查看自己的 namespace 内容;
  • Referring to Resources: 绑定资源
  • Referring to Subjects: Subjects 可以是groups、users和service accounts。

1.2 命令

kubectl api-resources | grep rbac  # 查看资源
kubectl get roles/clusterroles/rolebindings/clusterrolebindings  # 查看权限
kubectl describe role redis-ha -n default  # 查看详情
kubectl create xxx  # 创建
kubectl delete xxx  # 删除
kubectl apply -f xxx  # 更新

2. 使用 Kubeadm 安装基本集群

Use Kubeadm to install a basic cluster

  1. kubeadm 过程

kubeadm init

2.1 硬件要求

  • 服务器:2C+、2G+、Linux、关闭 swap
  • 网络:设备互通
  • 端口开放:

    Master

    端口范围 Master Worker 用途
    6443 * Kubernetes API server
    2379-2380 etcd server client API
    10251 kube-scheduler
    10252 kube-controller-manager
    10250 Kubelet API
    10255 Read-only Kubelet API (Heapster)
    30000-32767 NodePort Services默认端口范围。

2.2 配置

ll /etc/kubernetes
# k8s 配置根目录
-rw------- 1 root root 5560 Feb 25 03:50 admin.conf
-rw------- 1 root root 5586 Feb 25 03:50 controller-manager.conf
-rw------- 1 root root 1964 Feb 25 03:50 kubelet.conf
drwxr-xr-x 1 root root 4096 Feb 25 03:50 manifests/
drwxr-xr-x 3 root root 4096 Feb 25 03:50 pki/
-rw------- 1 root root 5534 Feb 25 03:50 scheduler.conf

ll /etc/kubernetes/manifests
# k8s 部署组件自描述
-rw------- 1 root root 2193 Feb 25 03:50 etcd.yaml
-rw------- 1 root root 3826 Feb 25 03:50 kube-apiserver.yaml
-rw------- 1 root root 3351 Feb 25 03:50 kube-controller-manager.yaml
-rw------- 1 root root 1384 Feb 25 03:50 kube-scheduler.yaml

ll /etc/kubernetes/pki
# k8s TSL 证书
-rw-r--r-- 1 root root 1135 Feb 25 03:50 apiserver-etcd-client.crt
-rw------- 1 root root 1679 Feb 25 03:50 apiserver-etcd-client.key
-rw-r--r-- 1 root root 1143 Feb 25 03:50 apiserver-kubelet-client.crt
-rw------- 1 root root 1675 Feb 25 03:50 apiserver-kubelet-client.key
-rw-r--r-- 1 root root 1310 Feb 25 03:50 apiserver.crt
-rw------- 1 root root 1675 Feb 25 03:50 apiserver.key
-rw-r--r-- 1 root root 1066 Feb 25 03:50 ca.crt
-rw------- 1 root root 1675 Feb 25 03:50 ca.key
drwxr-xr-x 2 root root 4096 Feb 25 03:50 etcd/
-rw-r--r-- 1 root root 1078 Feb 25 03:50 front-proxy-ca.crt
-rw------- 1 root root 1675 Feb 25 03:50 front-proxy-ca.key
-rw-r--r-- 1 root root 1103 Feb 25 03:50 front-proxy-client.crt
-rw------- 1 root root 1675 Feb 25 03:50 front-proxy-client.key
-rw------- 1 root root 1675 Feb 25 03:50 sa.key
-rw------- 1 root root  451 Feb 25 03:50 sa.pub

2.3 指令

kubeadm init
kubeadm join

参考

3. 管理高可用性的 Kubernetes 集群

Manage a highly-available Kubernetes cluster

3.1 名词解释

(1)集群节点

集群存在所有主机都称为节点,每个HA集群最低要求需有2个节点;正常来说,节点数最好为奇数。在生产环境中,HA集群的节点数至少为3个,可以降低发生脑裂的概率。

(2)集群服务与资源

集群服务通常包括多个资源,多个资源组成某种集群服务。如mysql高可用服务,其资源包括vip、mysqld、共享存储等。资源是启动一个服务需要的子项目。例如启动一个httpd服务,需要ip,也需要服务脚本,还需要文件系统(用来存储数据的),这些我们都可以统称为资源。对于集群服务的管理,实际上就是对资源的管理。

(3)脑裂

脑裂是指因某种特殊原因造成集群分裂成两个小集群,而这两个小集群互相不能正常通信,此时,就会发生脑裂(Brain Split)现象。

(4)共享存储

高可用集群多节点都需要访问数据,如果各节点访问同一个数据文件都是在同一个存储空间内的,就是说数据共享的就一份,而这个存储空间就共享存储。如Web或Mysql高可用集群,他们的数据一般需要放在共享存储中,主节点能访问,从节点也能访问。

3.2 实现方式

(1)主从方式(非对称)

这种方式组建的高可用集群通常包含2个节点和一个或多个服务器,其中一台作为主节点(active),另一台作为备份节点(standy)。备份节点随时都在检测主节点的健康状况,当主节点发生故障时,服务会自动切换到备份节点上以保证服务正常运行。

这种方式下的高可用集群其中的备份节点平时不会启动服务,只有发生故障时才会有用,因此会造成一定浪费。

(2)对称方式

这种方式一般包含2个节点和一个或多个服务,其中每一个节点都运行着不同的服务且相互作为备份,两个节点互相检测对方的健康状况,这样当其中一个节点发生故障时,该节点上的服务会自动切换到另一个节点上去。这样可以保证服务正常运行。

(3)多机方式

这种集群包含多个节点和多个服务。每一个节点都可能运行和不运行服务,每台服务器都监视着几个指定的服务,当其中的一个节点发生故障时,会自动切换到这组服务器中的一个节点上去。

4. 设置基础架构以部署 Kubernetes 集群

Provision underlying infrastructure to deploy a Kubernetes cluster

5. 使用 Kubeadm 在 Kubernetes 集群上执行版本升级

Perform a version upgrade on a Kubernetes cluster using Kubeadm

kubeadm version # 查看版本
kubectl drain <cp-node-name> --ignore-daemonsets # 腾空节点
sudo kubeadm upgrade plan # 查看升级计划
sudo kubeadm upgrade apply v1.18.x # 升级到对应版本
kubectl uncordon <cp-node-name> # 取消节点保护
sudo kubeadm upgrade node

6. 实施 etcd 备份和还原

Implement etcd backup and restore

6.1 介绍

etcd 是一款基于 Raft 开源的分布式一致性键值存储,由 CoreOS 公司进行维护。

etcd = unix “/etc” + 分布式系统”d”istibuted,大规模分布式系统的配置信息存储系统;

最新版本为 v3.1.1,但 API 有 v3 和 v2 之分,通常指 API 版本号,主要是存储引擎、命令不一样;

数据存储:/var/lib/etcd

6.2 术语

  • Node 节点:raft 状态机的一个实例,有唯一标识,并内部记录其他节点的发展,如果它是 leader
  • Member 成员:etcd 的一个实例。它承载一个 node/节点,并为client/客户端提供服务
  • Cluster 集群:由多个 member/成员组成,每个成员的节点遵循 raft 一致性协议来复制日志。集群从成员中接收提案,提交他们并应用到本地存储
  • Peer 同伴:同一个集群中的其他成员
  • Proposal 提议:一个需要完成 raft 协议的请求(例如写请求,配置修改请求)
  • Client 客户端:集群 HTTP API 的调用者
  • Leader:
  • Follower:

6.3 架构

  • HTTP Server:用于处理用户发送的 API 请求以及其它 etcd 节点的同步与心跳信息请求。
  • Store:用于处理 etcd 支持的各类功能的事务,包括数据索引、节点状态变更、监控与反馈、事件处理与执行等等,是 etcd 对用户提供的大多数 API 功能的具体实现。
  • Raft:Raft 强一致性算法的具体实现,是 etcd 的核心。
  • WAL:Write Ahead Log(预写式日志),是 etcd 的数据存储方式。除了在内存中存有所有数据的状态以及节点的索引以外,etcd 就通过 WAL 进行持久化存储。WAL 中,所有的数据提交前都会事先记录日志。- - Snapshot 是为了防止数据过多而进行的状态快照;Entry 表示存储的具体日志内容。

6.4 备份

etcd 的数据默认会存放在我们的命令工作目录中,我们发现数据所在的目录,会被分为两个文件夹中:

  • snap: 存放快照数据,etcd防止WAL文件过多而设置的快照,存储etcd数据状态。
  • wal: 存放预写式日志,最大的作用是记录了整个数据变化的全部历程。在etcd中,所有数据的修改在提交前,都要先写入到WAL中。

恢复时会覆盖 snapshot 的元数据(member ID 和 cluster ID),所以需要启动一个新的集群。

在使用 API 3 时需要使用环境变量 ETCDCTL_API=3 明确指定。

# v2
etcdctl backup --data-dir /home/etcd/ --backup-dir /home/etcd_backup
etcd -data-dir=/home/etcd_backup/  -force-new-cluster
# v3
ETCDCTL_API=3 etcdctl --endpoints $ENDPOINT snapshot save snapshot.db

6.5 恢复

# v2
etcdctl snapshot restore snapshot.db --name m3 --data-dir=/home/etcd_data
# v3
$ ETCDCTL_API=3 etcdctl snapshot restore snapshot.db \
  --name m1 \
  --initial-cluster m1=http://host1:2380,m2=http://host2:2380,m3=http://host3:2380 \
  --initial-cluster-token etcd-cluster-1 \
  --initial-advertise-peer-urls http://host1:2380
$ ETCDCTL_API=3 etcdctl snapshot restore snapshot.db \
  --name m2 \
  --initial-cluster m1=http://host1:2380,m2=http://host2:2380,m3=http://host3:2380 \
  --initial-cluster-token etcd-cluster-1 \
  --initial-advertise-peer-urls http://host2:2380
$ ETCDCTL_API=3 etcdctl snapshot restore snapshot.db \
  --name m3 \
  --initial-cluster m1=http://host1:2380,m2=http://host2:2380,m3=http://host3:2380 \
  --initial-cluster-token etcd-cluster-1 \
$ etcd \
  --name m1 \
  --listen-client-urls http://host1:2379 \
  --advertise-client-urls http://host1:2379 \
  --listen-peer-urls http://host1:2380 &
$ etcd \
  --name m2 \
  --listen-client-urls http://host2:2379 \
  --advertise-client-urls http://host2:2379 \
  --listen-peer-urls http://host2:2380 &
$ etcd \
  --name m3 \
  --listen-client-urls http://host3:2379 \
  --advertise-client-urls http://host3:2379 \
  --listen-peer-urls http://host3:2380 &

考点

  1. node 维护(驱逐)

    kubectl cordon nodename  # 设为不可调度,防止新 Pod 调度过来
    kubectl drain nodename  # 驱逐运行的 Pod ,自动调度到可用的 node 上
    kubectl uncordon nodename  # 设为可调度,新的可以调度过来
    

参考

题目

  1. 使用etcd 备份功能备份etcd(提供enpoints,ca、cert、key)
  2. 给出一个集群,将节点node1添加到集群中,并使用TLS bootstrapping
  3. etcdctl 来 备份etcd

最佳实践