20

Kubernetes 实战-Cluster API 升级流程 | Yiran's Blog

 5 years ago
source link: https://zdyxry.github.io/2019/12/22/Kubernetes-%E5%AE%9E%E6%88%98-Cluster-API-%E5%8D%87%E7%BA%A7%E6%B5%81%E7%A8%8B/?
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Kubernetes 实战-Cluster API 升级流程

发表于 2019-12-22

|

之前已经介绍过 ClusterAPI 及相应实现方式,但是针对使用 ClusterAPI 部署的 K8s 集群社区中一直没有升级方案,其中 vmware 实现了一个简单的升级工具,可以在社区没实现之前提供使用,今天来看下这个工具是如何实现的。

cluster-api-upgrade-tool

项目地址:https://github.com/vmware/cluster-api-upgrade-tool

因为这只是一个单独的工具,因此代码结构比较简单:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
yiran@t480:~/go/src/github.com/vmware/cluster-api-upgrade-tool 
master ✔ $ tree .
.
├── CODE-OF-CONDUCT.md
├── CONTRIBUTING.md
├── Dockerfile
├── go.mod
├── go.sum
├── hack
│   └── tools
│   ├── go.mod
│   ├── go.sum
│   └── main.go
├── LICENSE.txt
├── main.go # 命令行入口
├── Makefile
├── NOTICE.txt
├── pkg
│   ├── internal
│   │   └── kubernetes
│   │   ├── client.go # 获取 client
│   │   └── pod_exec.go
│   ├── logging
│   │   └── logrus_logr.go
│   └── upgrade
│   ├── config.go
│   ├── control_plane.go # 主要升级逻辑
│   └── control_plane_test.go
├── README.md
└── test
└── integration
├── go.mod
├── go.sum
└── main_test.go

首先在 main.go 封装了相应的命令行用于升级,获取到相应配置后,开始升级:

1
2
3
4
5
6
upgrader, err := upgrade.NewControlPlaneUpgrader(newLogger(), finalConfig)
if err != nil {
return err
}

return upgrader.Upgrade()

在 control_plane.go 文件中是升级的主要逻辑,所有的步骤都是顺序执行的,摘要下主要的步骤:

1
2
3
4
5
6
7
8
9
10
11
12
13
// Upgrade does the upgrading of the control plane.
func (u *ControlPlaneUpgrader) Upgrade() error {
machines, err := u.listMachines()
...
if err := u.reconcileKubeadmConfigMapAPIEndpoints(); err != nil {
err = u.updateKubeletConfigMapIfNeeded(u.desiredVersion)
err = u.updateKubeletRbacIfNeeded(u.desiredVersion)
if err := u.etcdClusterHealthCheck(15 * time.Second); err != nil {
if err := u.UpdateProviderIDsToNodes(); err != nil {
return updateKubeadmKubernetesVersion(in, "v"+u.desiredVersion.String())
if err := u.updateMachines(machines); err != nil {
if err := u.reconcileKubeadmConfigMapAPIEndpoints(); err != nil {
}
  1. u.listMachines获取 TargetCluster 所有的 ControlPlane 节点
    a. 通过 label 来进行 machine 过滤
    b. 如果 Machine 的 DeletionTimestamp 字段为 0,则追加到列表中
  2. u.reconcileKubeadmConfigMapAPIEndpoints 这里主要是确保对应的 APIEndpoints 节点都在 k8s 集群中,通过对比 nodeList 与 APIEndpoints 来进行过滤
  3. u.updateKubeletConfigMapIfNeeded 在 k8s 中,在 ConfigMap 中是有保存 kubelet 配置信息的,在升级过程中,需要重新创建对应版本的 kubelet 配置信息,这个函数中直接将原版本的 kubelet 复制了一份,创建一份目标版本的 kublet 配置 ConfigMap
  4. u.updateKubeletRbacIfNeeded 创建目标版本的 Role 和 RoleBinding 资源
  5. u.etcdClusterHealthCheck 检查 etcd 集群是否健康,这里主要通过 endpoint health --endpoints 来检查 etcd 是否健康
  6. u.UpdateProviderIDsToNodes 通过 Cluster-API 创建出来的节点,需要设置 node.ProviderID 才可以被 Cluster-API 识别为 running 状态,ProviderId 格式为:vmware://xxxxx ,这里根据 ProviderID 来检测出具体的 ID,并将其作为一个 map 返回
  7. u.updateKubeadmKubernetesVersion 将 kubeadm ConfigMap 中的 kubernetesVersion 字段更新为目标版本,便于后续添加节点时指定的是目标版本
  8. u.updateMachines 在所有配置文件已经准备、更新完成后,开始做整个升级中最重要的部分,节点(Machine)升级,首先遍历所有 Machine 资源,针对每个 Machine,进行如下动作:
    a. u.etcdClusterHealthCheck 检查 etcd 集群是否健康,如果不健康,则退出升级
    b. generateReplacementMachineName 生成替代 Machine 相应配置信息,如 MachineName
    c. u.updateInfrastructureReference 创建替代 Machine 的 Infrastructure Object
    d. u.updateBootstrapConfig 创建替代 Machine 的 Bootstrap Config,因为默认 Cluster-API 使用的 kubeadm Bootstrap,所以这里其实是生成替代 Machine 执行的 kubeadm 配置
    e. u.updateMachine 真正创建替代 Machine 的步骤,创建对应的目标虚拟机,等待目标虚拟机添加到 K8s 集群中且处于 Ready 后,将原虚拟机对应 etcd 节点从 etcd 集群中移除,随后将原虚拟机对应节点从 K8s 集群中移除
  9. u.reconcileKubeadmConfigMapAPIEndpoints 等待所有 Machine 替换完成后,重新配置 kubeadm ConfigMap 保证 kubeadm ConfigMap 中保存所有的 APIEndpoints 信息。

Cluster-API 作为 K8s cluster-lifecycle SIG 的一个还处于 Alpha 阶段的项目,还处于一个快速更新迭代的状态,因此最终升级流程是怎样还不确定,但是从 vmware 的这个工具来看,后续很有可能采用这种方案,毕竟 Cluster-API 不想通过 SSH 这种比较麻(恶)烦(心)的方式对节点进行管理,从 kubeadm Bootstrap 使用 Cloud-init 就可以看出,尤其是当支持多种 Linux 发行版后,可以预想这是一个灾难。因此使用这种节点逐一替换的方式是很方便的,具体实现看 v1alpha3 发布之后社区的讨论结果吧。

吐槽:
Cluster-API 项目在代码中很少使用缩写,带来的好处很明显,易读易懂,上手容易,我自己的项目也一直秉承着这种观点,但是当我看到 reconcileKubeadmConfigMapAPIEndpoints 这种长度的变量名,还是很崩溃的。


Recommend

  • 62

    MariadbgaleraCluster安装:操作系统:Centos7.4版本集群数量:3个节点主机信息:192.168.153.142node1selinux=disabledfirewalld关闭192.168.153.143node2selinux=disabledfirewalld关闭192.168.153.144node3selinux=disabledfirewalld关闭搭建步骤1.

  • 46
    • zdyxry.github.io 5 years ago
    • Cache

    Podman 初次体验 | Yiran's Blog

    CentOS8 在9月24号正式 Release 了,比 RHEL8 要推迟了4个月。这次的更新感觉比 CentOS7 的更新要来的重要,内核更新到了4.x,网络管理彻底替换了 network.service,防火墙管理等等,还包括去除了 Docker...

  • 25

    在部署应用时想要应用是高可用,通常会在应用前放置一个 HAProxy,当任何一个 Server 故障,HAProxy 会自动切换,但是 HAProxy 也存在单点故障,因此需要多个 HAProxy 来保证业务不中断,这时候我们需要...

  • 26
    • zdyxry.github.io 5 years ago
    • Cache

    zipstreamer 源码阅读 | Yiran's Blog

    在之前的一篇博客《HTTP Content-Length 学习》 中提到自己踩了一个坑,就是 conte...

  • 24
    • www.cnblogs.com 5 years ago
    • Cache

    Docker实战之Redis-Cluster集群

    概述 接上一篇 Docker实战之MySQL主从复制 , 这里是Docker实战系列的第二篇,主要进行Redis-Cluster集群环境的快速搭建。Redis作为基于键值对的NoSQL数据库...

  • 36
    • zdyxry.github.io 5 years ago
    • Cache

    SR-IOV 基本概念 | Yiran's Blog

    SR-IOV 基本概念 发表于...

  • 34
    • zdyxry.github.io 5 years ago
    • Cache

    fsck 是如何工作的 | Yiran's Blog

    在平时会遇到不少系统崩溃之后文件系统异常的情况,通常我们会通过 fsck 工具进行修复,今天来了解下 fsck 做了什么,是怎么做的。 工作负载示例假设现在存在一种工作...

  • 14

    昆仑万维是全球领先、业内前沿的综合性互联网集团,业务涵盖昆仑游戏(GameArk)、信息资讯(Opera)等多个业务板块。其中,昆仑游戏(GameArk)凭借研发及运营的核心优势,面向全球进行游戏的研发、发行与运营,形成多样性的产品矩阵。截止 2020...

  • 9

    Cluster API Provider for VMware Cloud Director VMware Cloud Director with Container Service Extension provides Kubernetes as a Service to Cloud Providers for Tanzu Kubernetes Clusters with Multi-tenancy at the core....

  • 4

    1、在k8s上部署redis单机 1.1、redis简介 redis是一款基于BSD协议,开源的非关系型数据库(nosql数据库),作者是意大利开发者Salvatore Sanfilippo在2009年发布,使用C语言编写;redis是基于内存存...

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK