华为云云原生之多云管理利器Karmada从0到1的实 *** 【与云原生的故事】

华为云云原生之多云管理利器Karmada从0到1的实 *** 【与云原生的故事】,第1张

文章目录
  • 一、Karmada的概念
    • 1.Karmada是什么
    • 2.Karmada的诞生背景
    • 3.Karmada的优势
  • 二、Karmada的架构
    • 1.Karmada控制平面的组成
    • 2.Karmada的Controller详解
      • 2.1 Cluster Controller
      • 2.2 Cluster status controller
      • 2.3 namespace sync controller
      • 2.4 Resourse Template controller
      • 2.5 Binding controller
      • 2.6 execution controller
      • 2.7 work status controller
      • 2.8 serviceexport controller
      • 2.9 endpointslice controller
      • 2.10 serviceimport controller
      • 2.11 hpa controller
  • 三、karmada安装
    • 1.安装Docker
      • 1.1 Docker的架构
      • 1.2 系统环境
      • 1.3 使用仓库安装
        • 1.3.1 设置仓库
        • 1.3.2 添加 GPG 密钥,并添加 Docker-ce 软件源
        • 1.3.3 安装Docker-ce
        • 1.3.4 测试Docker是否安装成功
      • 1.4 添加当前用户到 docker 用户组,可以不用 sudo 运行 docker
    • 2.安装GO
      • 2.1 下载并安装GO
      • 2.2 测试GO是否安装成功
      • 2.3 设置go环境为国内源
    • 3.安装k8s
      • 3.1 前置条件
        • 3.1.1 关闭swap内存
        • 3.1.2 关闭防火墙
        • 3.1.3 确保时区和时间正确
        • 3.1.3 主机名和hosts设置
      • 3.2 安装组件
        • 3.2.1 更改docker默认驱动为systemd
        • 3.2.2 配置NAT转发
        • 3.2.2 SSH密钥免密
      • 3.3 更新源
      • 3.4 下载公开签名秘钥、并添加k8s库
      • 3.5 更新 apt 包索引
      • 3.6 安装 kubelet、kubeadm 和 kubectl,并锁定其版本
      • 3.7 配置kubectl开机启动
      • 3.8 测试kubectl是否安装成功
      • 3.9 初始化主节点master
      • 3.10 配置kubernetes-admin来运行
      • 3.11 集群部署网络插件
    • 4.安装简易k8s开发集群管理工具:kind
      • 4.1 安装kind
      • 4.2 环境变量配置
      • 4.3 测试kind是否安装成功
    • 5.安装karmada控制面
      • 5.1 先行条件
      • 5.2 安装karmada
        • 5.2.1 下载karmada源码
        • 5.2.2 安装karmada控制面
      • 5.3 查看karmada控制面组成
        • 5.3.1 切换到karmada-host
        • 5.3.2 获取组件列表


一、Karmada的概念 1.Karmada是什么

Karmada(Kubernetes Armada)是一个Kubernetes管理系统,使您能够跨多个Kubernetes集群和云运行云原生应用程序,而无需更改您的应用程序。通过使用 Kubernetes 原生 API 并提供高级调度功能,Karmada 实现了真正开放的多云 Kubernetes。

Karmada旨在为多云和混合云场景中的多集群应用程序管理提供自动化功能,具有集中式多云管理,高可用性,故障恢复和流量调度等关键功能。

官方网站:https://karmada.io/

代码地址:https://github.com/karmada-io/karmada

2.Karmada的诞生背景

Karmada 项目由华为云、工商银行、小红书、中国一汽等 8 家企业联合发起,沉淀了各企业在多云管理领域的丰富积累,于 2021 年 4 月 25 日在华为开发者大会 2021(HDC.Cloud)上正式宣布开源。同年 9 月,Karmada 项目正式捐赠给云原生计算基金会 CNCF,成为 CNCF 首个多云容器编排项目。Karmada 项目的加入,也将 CNCF 的云原生版图进一步扩展至分布式云领域。

CNCF 总经理 Priyanka Sharma 对此表示:“华为一直是云原生社区与开发者生态的重要参与者,Karmada 对所有企业构建多云业务架构至关重要,希望未来 CNCF 与华为云继续密切合作,持续帮助广大云原生开发者。”

Karmada 自开源以来受到了广泛的关注和支持,目前在代码托管平台上已有超过 30 家大型企业/机构/高校参与社区开发及贡献。

3.Karmada的优势

Karmada 结合了华为云容器平台 MCP 以及 Kubernetes Federation 核心实践,并融入了众多新技术:包括 Kubernetes 原生 API 支持、多层级高可用部署、多集群自动故障迁移、多集群应用自动伸缩、多集群服务发现等,并且提供原生 Kubernetes 平滑演进路径,让基于 Karmada 的多云方案无缝融入云原生技术生态,为企业提供从单集群到多云架构的平滑演进方案。Karmada的优势主要有以下几点:

1、K8s 原生 API 兼容

  • 既有应用配置及基础设施无需改造,由单集群架构平滑升级到多集群(多云)架构。
  • 无缝集成 Kubernetes 现有工具链生态。

2、开箱即用

  • 面向多场景的内置策略集,包括两地三中心、同城双活、异地容灾等。
  • 支持应用的跨集群上的自动伸缩、故障迁移和负载均衡。

3、避免供应商锁定

  • 与主流云提供商集成。
  • 自动分配,跨集群迁移。
  • 不受专有供应商编排的约束。

4、集中管理

  • 与位置无关的群集管理。
  • 支持公有云、本地或边缘的集群。

5、富有成效的多集群调度策略

  • 多集群亲和性调度、应用跨集群拆分、资源重新平衡。
  • 多维度多层次的高可用部署:区域/可用区/集群/供应商等。

6、开放和中立

  • 由互联网、金融、制造、电信、云提供商等共同发起。
  • 使用 CNCF 实现开放式治理的目标。
二、Karmada的架构 1.Karmada控制平面的组成

Karmada控制平面由以下组件组成:

  • Karmada API Server
  • Karmada Controller Manager
  • Karmada Scheduler

组件原生说明
etcd存储 karmada API 对象,API 服务器是所有其他组件与之通信的 REST 端点,Karmada 控制器管理器根据您通过 API 服务器创建的 API 对象执行 *** 作
kube-apiserverAPI Server是所有其他组件都可以与之通信的REST端点
kube-controller-managerController Manager将根据您通过API服务器创建的API对象执行 *** 作
karmada-controller-managerkarmadakarmada controller-manager, 监听相关资源,创建ResourceBinding及ClusterResourceBinding,更新work,同步集群间资源
karmada-schedulerkarmada加载Policy,分析资源,更新work
karmada-webhookkarmadakarmada资源校验
karmada-agentkarmada取决于Cluster的同步模式,若是push模式,则不需要部署,否则需要部署到管理的集群中

Karmada Controller Manager运行各种控制器,控制器监视karmada对象,然后与底层集群的API服务器通信以创建常规的Kubernetes资源。

控制器名称说明
集群控制器将 kubernetes 集群附加到 Karmada,用于通过创建集群对象来管理集群的生命周期。
策略控制器控制器监视传播策略对象。添加传播策略对象时,它会选择一组与资源选择器匹配的资源,并为每个资源对象创建资源绑定。
绑定控制器控制器监视资源绑定对象,并使用单个资源清单创建与每个群集对应的工作对象。
执行控制器控制器监视工作对象。创建 Work 对象时,它会将资源分发到成员集群。
2.Karmada的Controller详解

Controller (控制器) 在 Kubernetes 中是逻辑能力的主要体现所在,根据资源对象的状态来完成调和工作,让资源对象逐步接近期待的状态,这个就是 Kubernetes 的申明式特性。

在 Karmada 中,同样需要对 Karmada 自己的资源对象,实现对应的申明式特性,这就需要实现对应的 Controller。在Karmada 中目前的版本中有 11 个 Controllers,接下来就从每一个控制器所负责的资源对象,以及原理来分析一下,在 Karmada 中是怎样完成多云能力的。

11种控制器结构图如下:

2.1 Cluster Controller

cluster controller 主要就是处理 Cluster 资源对象的逻辑,负责处理 Cluster 对应需要的关联资源。

2.2 Cluster status controller

cluster status controller 主要就是处理 cluster status 资源对象的逻辑,用来收集 Cluster 的状态,保存到 Cluster 的 status 字段中,同步上报到 Karmada 的控制平面中。

2.3 namespace sync controller

namespace sync controller 主要就是处理 namespace 资源对象的逻辑,负责将 Karmada 控制平面创建的 namespace 在集群中同步创建出来。

2.4 Resourse Template controller

detector 模块中包含了通用 controller 负责 resource template 的 Kubernetes 资源对象的调和处理逻辑,以及匹配 PropagationPolicy。主要就是处理 PropagationPolicy 资源对象的逻辑,来派生出资源对象对应的ResourceBinding 对象。

2.5 Binding controller

binding controller 主要就是处理 ResourceBinding 资源对象的增删改逻辑,ResourceBinding 的调和能力是派生出 work 对象,work 对象是和特定集群关联的。一个 work 只能属于一个集群,代表一个集群的资源对象的模型封装。

2.6 execution controller

execution controller 主要就是处理 Work 资源对象的增删改逻辑,用于处理 Work,将 Work 负责的 Kubernetes 资源对象在对应的集群上创建出来。

2.7 work status controller

work status controller 主要就是处理 Work 资源对象的状态逻辑,负责收集 Work 的状态,也就是 Work 对应的资源对象的状态,只是这个状态是保存在 Work 的 status 字段里的。

2.8 serviceexport controller

serviceexport controller 主要就是处理 serviceexport 资源对象的状态逻辑,将需要被其它集群发现的服务暴露出来。

2.9 endpointslice controller

endpointslice controller 主要根据 serviceexport 资源对象对应到处的 Service,Service 对应的 endpointslice 上报到 Karmada 的控制面。

2.10 serviceimport controller

serviceimport controller 主要负责根据 ServiceExport 暴露出来的 Service,在自己负责的集群中创建对应的 service,注意 service 的名称不是完全一样的,同时在自己负责的集群中也创建对应的 EndpointSlice,这个EndpointSlice 的数据就是来源于 EndpointSlice controller 中上报到 karmada 控制平面的 EndpointSlice 对象,具体是通过在 karmada-webhook 中给 ServiceImport 的 PropagationPolicy 中增加了 EndpointSlice 的下发能力。

2.11 hpa controller

hpa controller 主要负责将 Karmada 控制面中创建的 HPA 对象通过创建 Work 的方式下发到对应的集群中。

三、karmada安装 1.安装Docker

Docker的相关文档网站如下:

  • Docker官网:https://hub.docker.com/search?type=edition&offering=community
  • Ubuntu安装Docker文档:https://docs.docker.com/engine/install/ubuntu/
1.1 Docker的架构

Docker的架构设计分为三个组件:一个客户端,一个REST API和一个服务器(守护进程):

  • Client :与REST API交互。主要目的是允许用户连接守护进程。
  • REST API:充当客户端和服务器之间的接口,实现通信。
  • 守护进程:负责实际管理容器 - 启动,停止等。守护进程监听来自docker客户端的API请求。
1.2 系统环境

本人使用的是ubuntu22.04 LTS版本,查看系统版本命令如下

lsb_release -a
cat /proc/version

1.3 使用仓库安装

如果以前有安装需要先卸载旧版Docker,docker, docker.io, docker-engine。

卸载旧版本的命令如下:

sudo apt-get remove docker docker-engine docker.io containerd runc

1.3.1 设置仓库

更新apt-get

sudo apt-get update

安装包使得apt可以使用https

sudo apt-get install apt-transport-https ca-certificates software-properties-common curl

1.3.2 添加 GPG 密钥,并添加 Docker-ce 软件源

添加清华GPG密钥

curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add -

或者添加阿里云GPG密钥

curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -

添加清华Docker-ce 软件源

sudo add-apt-repository "deb [arch=amd64] https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu $(lsb_release -cs) stable"

或者添加阿里云Docker-ce 软件源

sudo add-apt-repository "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"


如果出现错误可以用以下命令删除重新执行命令

#注意:添加错了可以用以下命令删除
#查询keyid,下图
sudo apt-key list
#keyid 就是90那一串
sudo apt-key del <keyid>
#加参数-r可以移除
sudo add-apt-repository -r "deb [arch=amd64] https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
1.3.3 安装Docker-ce

再次更新系统

sudo apt-get update


安装docker-ce软件

sudo apt-get install docker-ce docker-ce-cli containerd.io -y

1.3.4 测试Docker是否安装成功

查看是否启动

ps aux|grep docker

测试运行容器

sudo docker run hello-world

1.4 添加当前用户到 docker 用户组,可以不用 sudo 运行 docker

将当前用户添加到 docker 组

sudo gpasswd -a ${USER} docker


重新登录或者用以下命令切换到docker组

newgrp - docker


重启docker服务

sudo service docker restart


不加sudo直接执行docker命令检查效果

docker ps

2.安装GO 2.1 下载并安装GO
sudo apt-get install golang-go

2.2 测试GO是否安装成功
go version

2.3 设置go环境为国内源
go env -w GOPROXY=goproxy.cn #设置go环境为国内源
3.安装k8s 3.1 前置条件

K8S官网:https://kubernetes.io/docs/setup/

最新版高可用安装:https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/high-availability/

3.1.1 关闭swap内存

这个swap其实可以类比成 windows 上的虚拟内存,它可以让服务器在内存吃满的情况下可以保持低效运行,而不是直接卡死。但是 k8s 的较新版本都要求关闭swap。所以咱们直接动手,修改/etc/fstab文件:

sudo gedit /etc/fstab

3.1.2 关闭防火墙

ubuntu 查看防火墙命令,ufw status可查看状态,ubuntu22.04默认全部关闭,无需设置。

设置命令如下:

sudo ufw status #查看防火墙状态
sudo ufw disable
sudo swapoff -a #临时禁止

3.1.3 确保时区和时间正确
systemctl start chrony
systemctl enable chrony
chronyc sources #看连接状态
chronyc tracking #看同步状态,时间差
chronyc -a makestep #立即同步时间

3.1.3 主机名和hosts设置

非必须,但是为了直观方便管理,建议设置。

在宿主机分别设置主机名:k8s-master01,k8s-node01

hostnamectl set-hostname k8s-master01

hosts设置

sudo gedit /etc/hosts

#配置host如下
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.16.133 k8s-master01.ilinux.io k8s-master01 k8s-api.ilinux.io
192.168.16.134 k8s-node01.ilinux.io k8s-node01
199.232.96.133 raw.githubusercontent.com

3.2 安装组件 3.2.1 更改docker默认驱动为systemd

为防止初始化出现一系列的错误,请检查docker和kubectl驱动是否一致,否则kubectl没法启动造成报错。版本不一样,docker有些为cgroupfs,而kubectl默认驱动为systemd,所以需要更改docker驱动。

可查看自己docker驱动命令:

sudo docker info|grep Driver


如果不是systemd需要执行以下命令:

#编辑创建文件
sudo gedit /etc/docker/daemon.json
#添加内容
{
  "exec-opts": ["native.cgroupdriver=systemd"]
}


重启docker

sudo systemctl restart docker.service
3.2.2 配置NAT转发
modprobe br_netfilter

cat /etc/profile

cat /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1

sudo sysctl -p /etc/sysctl.d/k8s.conf #执行同步参数

3.2.2 SSH密钥免密
sudo apt-get install openssh-server
ssh-keygen -t rsa


此时会在/home/ubuntu/.ssh目录下生成密钥对

ll .ssh


上传公钥到对应服务器

ssh-copy-id 192.168.16.133
ssh-copy-id 192.168.16.134

3.3 更新源
sudo apt-get update

3.4 下载公开签名秘钥、并添加k8s库

国外 :下载 Google Cloud 公开签名秘钥:

curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add
sudo apt-add-repository "deb http://apt.kubernetes.io/ kubernetes-xenial main"

国内:可以用阿里源即可:

curl -s https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo apt-key add -
sudo tee /etc/apt/sources.list.d/kubernetes.list <<EOF 
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF
3.5 更新 apt 包索引
sudo apt-get update

3.6 安装 kubelet、kubeadm 和 kubectl,并锁定其版本
sudo apt-get install -y kubectl kubelet kubeadm

sudo apt-mark hold kubelet kubeadm kubectl
  • kubeadm:用来初始化集群的指令。
  • kubelet:在集群中的每个节点上用来启动 Pod 和容器等。
  • kubectl:用来与集群通信的命令行工具。

3.7 配置kubectl开机启动
systemctl daemon-reload
systemctl enable kubelet

3.8 测试kubectl是否安装成功
kubelet --version
kubectl version --client
kubeadm version

3.9 初始化主节点master

拉取相关包

kubeadm config images pull --image-repository registry.aliyuncs.com/google_containers

初始化主节点master

kubeadm init \
--apiserver-advertise-address=192.168.16.133 \
--image-repository registry.aliyuncs.com/google_containers \
--pod-network-cidr=10.244.0.0/16

异常情况分析:

错误提示1:

[kubelet-check] It seems like the kubelet isn't running or healthy.
[kubelet-check] The HTTP call equal to 'curl -sSL http://localhost:10248/healthz' failed with error: Get "http://localhost:10248/healthz": dial tcp 127.0.0.1:10248: connect: connection refused.

原因:kubectl没法启动,journalctl -xe查看启动错误信息。

journalctl -xe
#信息显示docker和kubectel驱动不一致
kubelet cgroup driver: \"systemd\" is different from docker cgroup driver: \"cgroupfs\""

解决方案:k8s建议systemd驱动,所以更改docker驱动即可,编辑 /etc/docker/daemon.json (没有就新建一个),添加如下启动项参数即可:

#编辑创建文件
sudo vim  /etc/docker/daemon.json
#添加内容
{
  "exec-opts": ["native.cgroupdriver=systemd"]
}

重启docker和kubectl

#重启docker
sudo systemctl restart docker.service
#重载kubectl
sudo systemctl daemon-reload  
#重启kubectl
sudo systemctl restart kubelet.service 
#查看kubectl服务状态恢复正常
sudo systemctl status kubelet.service

错误提示2:

error execution phase preflight: [preflight] Some fatal errors occurred:
	[ERROR FileAvailable--etc-kubernetes-manifests-kube-apiserver.yaml]: /etc/kubernetes/manifests/kube-apiserver.yaml already exists
	[ERROR FileAvailable--etc-kubernetes-manifests-kube-controller-manager.yaml]: /etc/kubernetes/manifests/kube-controller-manager.yaml already exists
	[ERROR FileAvailable--etc-kubernetes-manifests-kube-scheduler.yaml]: /etc/kubernetes/manifests/kube-scheduler.yaml already exists
	[ERROR FileAvailable--etc-kubernetes-manifests-etcd.yaml]: /etc/kubernetes/manifests/etcd.yaml already exists
[preflight] If you know what you are doing, you can make a check non-fatal with `--ignore-preflight-errors=...`

原因:初始化生产的文件,重新初始化,需要删除即可

rm -fr /etc/kubernetes/manifests/*

错误提示3:

error execution phase preflight: [preflight] Some fatal errors occurred:
	[ERROR Port-10250]: Port 10250 is in use

解决方法:重置配置

sudo kubeadm reset
3.10 配置kubernetes-admin来运行
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> /etc/profile
source /etc/profile

3.11 集群部署网络插件

安装cni插件:

mkdir -p go/src/github.com/containernetworking/
cd go/src/github.com/containernetworking/
git clone https://github.com/containernetworking/plugins.git 
git clone https://github.com/containernetworking/cni.git 
cd plugins
./build_linux.sh
cd ../cni/cnitool
go build cnitool.go

部署网络插件命令如下:

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

4.安装简易k8s开发集群管理工具:kind

Kind 是 Kubernetes In Docker 的缩写,顾名思义是使用 Docker 容器作为 Node 并将 Kubernetes 部署至其中的一个工具。官方文档中也把 Kind 作为一种本地集群搭建的工具进行推荐。

4.1 安装kind
GOPROXY=goproxy.cn go install sigs.k8s.io/kind@v0.12.0

4.2 环境变量配置
sudo cp $(go env GOPATH)/bin/kind /usr/local/bin


kind使用一个容器来模拟一个node,在容器内部使用systemd托管kubelet和containerd(不是docker),然后通过被托管的kubelet启动其他k8s组件,比如kube-apiserver、etcd、CNI等跑起来。

由于kind使用containerd而非docker作为容器运行时,要查看kind启动的k8s节点内部容器运行情况,需要使用containerd的cli客户端ctr。可以通过下面这条命令查看后续步骤中karmada调用kind启动的单节点k8s集群内部容器的运行情况:

docker exec karmada-host-control-plane ctr --namespace k8s.io containers ls

注意点:ctr的flag --namespace不是k8s里的namespace,也不是linux内核支持的namespace,感兴趣的同学可以查看containerd的namespace相关概念

4.3 测试kind是否安装成功
kind --version

5.安装karmada控制面 5.1 先行条件

安装karmada需要先安装以下工具:

  • make
  • gcc
  • kubectl
  • go
  • kind
  • git
5.2 安装karmada 5.2.1 下载karmada源码
git clone https://github.com/karmada-io/karmada.git karmada-io/karmada
cd karmada-io/karmada

5.2.2 安装karmada控制面

执行安装命令如下:

docker tag docker.io/mirrorgooglecontainers/etcd:3.4.13-0 k8s.gcr.io/etcd:3.4.13-0 #版本和k8s.gcr.io无法下载需要设置tag标签

hack/local-up-karmada.sh

安装步骤详解:

  1. 检查go、kind等工具是否已经存在
  2. 调用kind创建host k8s集群,集群版本默认为1.19.1,与karmada重用的k8s组件(kube-apiserver、kube-controllermanager)版本一致
  3. build karmada控制面可执行文件及容器镜像,build结束后本地可以找到如下镜像:karmada-agent、karmada-webhook、karmada-scheduler、karmada-controller-manager
  4. 部署karmada控制面组件到host集群
  5. 创建CRD,也就是karmada自定义的多云工作负载API资源,包含:propgation policy,override policy,work,resource binding等
  6. 创建webhook
  7. 部署完成后,形成kubeconfig文件$HOME/kube/karmada.config,包含karmada-host和karmada-apiserver两个context,分别对应支撑karmada控制面运行的host集群,以及karmada控制面本身

注意:karmada还提供了remote-up-karmada.sh脚本,用以把一个现有的k8s集群加入联邦。感兴趣的读者可以阅读karmada项目的readme尝试

5.3 查看karmada控制面组成

使用karmada管理的多云环境包含两类集群:

  • host集群:即由karmada控制面构成的集群,接受用户提交的工作负载部署需求,将之同步到member集群,并从member集群同步工作负载后续的运行状况。
  • member集群:由一个或多个k8s集群构成,负责运行用户提交的工作负载
5.3.1 切换到karmada-host
kubectl config use-context karmada-host #切换到karmada-host控制面
5.3.2 获取组件列表
kubectl get po --all-namespaces

【与云原生的故事】有奖征文火热进行中:https://bbs.huaweicloud.com/blogs/345260

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/733523.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-27
下一篇 2022-04-27

发表评论

登录后才能评论

评论列表(0条)

保存