官方文档:https://karmada.io/zh/docs/
github地址:https://github.com/karmada-io/karmada
环境
我这里是3台机器,单节点的k8s集群。k8s版本是1.20.15。
master1:172.16.255.183 member1
master2:172.16.255.181 member2
master3:172.16.255.182 member3
部署
安装karmadactl
使用master1来当作karmada控制平面。版本是最新的v1.5.0。
curl -s https://raw.githubusercontent.com/karmada-io/karmada/master/hack/install-cli.sh | sudo bash
我这里下载卡主了,我的机器访问不了github,所以直接从release中下载。
wget https://github.com/karmada-io/karmada/releases/download/v1.5.0/karmadactl-linux-amd64.tgz
tar xvf https://github.com/karmada-io/karmada/releases/download/v1.5.0/karmadactl-linux-amd64.tgz
rm -f LICENSE
cp karmadactl /usr/local/bin
安装kubectl-karmada
curl -s https://raw.githubusercontent.com/karmada-io/karmada/master/hack/install-cli.sh | sudo bash -s kubectl-karmada
这里也选择直接下载release包。
wget https://github.com/karmada-io/karmada/releases/download/v1.5.0/kubectl-karmada-linux-amd64.tgz
tar xvf kubectl-karmada-linux-amd64.tgz
rm -f LICENSE
cp kubectl-karmada /usr/local/bin
安装Karmada
# 在线安装:默认将从 Karmada 官网 release 页面(例如 https://github.com/karmada-io/karmada/releases/tag/v0.10.1)下载 API(CRD),并从官方镜像仓库加载镜像。
kubectl karmada init
# 离线安装
wget https://github.com/karmada-io/karmada/releases/download/v1.5.0/crds.tar.gz
kubectl karmada init --crds /$HOME/crds.tar.gz
## 高可用部署
kubectl karmada init --karmada-apiserver-replicas 3 --etcd-replicas 3
# kind
## 创建host集群
git clone https://github.com/karmada-io/karmada
cd karmada
hack/create-cluster.sh host $HOME/.kube/host.config
kubectl karmada init --crds https://github.com/karmada-io/karmada/releases/download/v1.2.0/crds.tar.gz --kubeconfig=$HOME/.kube/host.config
# helm
## 本地安装
helm install karmada -n karmada-system --create-namespace --dependency-update ./charts/karmada
## 远程安装
helm repo add karmada-charts https://raw.githubusercontent.com/karmada-io/karmada/master/charts
helm search repo karmada
helm --namespace karmada-system upgrade -i karmada karmada-charts/karmada --version=<x.x.x> --create-namespace
## 指定插件
helm upgrade --install karmada -n karmada-system --create-namespace --dependency-update \
--cleanup-on-fail ./charts/karmada \
--set components={"descheduler"}
## 卸载
helm uninstall karmada -n karmada-system
这里选择离线安装
安装报错:error: failed to find a healthy node for karmada-etcd
原因:我这里是单节点,master上有taint,需要去掉。
k describe node master1 | grep -i taint
k taint node master1 node-role.kubernetes.io/master:NoSchedule-
k karmada init --crds /root/crds.tar.gz
这里会报错拉取不到镜像
手动指定镜像仓库为阿里云,重新安装:
k delete svc etcd karmada-apiserver -n karmada-system
k delete sts etcd -n karmada-system
k delete deploy karmada-apiserver -n karmada-system
rm -rf /var/lib/karmada-etcd/
kubectl karmada init --crds /root/crds.tar.gz --kube-image-registry=registry.cn-hangzhou.aliyuncs.com/google_containers
安装成功
查看pod,svc,karmada配置文件
其中etcd是statefulset,数据目录是/var/lib/karmada-etcd/
添加alias
echo "alias ka='kubectl --kubeconfig /etc/karmada/karmada-apiserver.config'" >> ~/.bashrc
source ~/.bashrc
集群注册
Karmada 支持 Push 和 Pull 两种模式来管理成员集群。 Push 和 Pull 模式的主要区别在于部署应用时访问成员集群的方式。
push
Karmada 控制平面将直接访问成员集群的 kube-apiserver 以获取集群状态和部署清单。
可以使用 kubectl-karmada CLI 来 join (注册)和 unjoin (注销)集群。
使用以下命令将名称为 member1 的集群加入 Karmada。
# --kubeconfig 指定 Karmada 的 kubeconfig 文件,--cluster-kubeconfig指定成员集群的 kubeconfig
kubectl karmada join member1 --kubeconfig=<karmada kubeconfig> --cluster-kubeconfig=<member1 kubeconfig>
# 如果在 kubeconfig 文件中配置了多个context,建议通过 --karmada-context 标志指定context。
kubectl karmada join member1 --kubeconfig=<karmada kubeconfig> --karmada-context=karmada --cluster-kubeconfig=<member1 kubeconfig>
# 如果 kubeconfig 文件中配置了多个上下文,或者不想使用上下文名称注册,建议通过 --cluster-context 标志指定上下文。
kubectl karmada join member1 --kubeconfig=<karmada kubeconfig> --karmada-context=karmada \
--cluster-kubeconfig=<member1 kubeconfig> --cluster-context=member1
# 注册集群名称可以与指定 --cluster-context 的上下文不同。
kubectl karmada --kubeconfig /etc/karmada/karmada-apiserver.config join member1 --cluster-kubeconfig=$HOME/.kube/config
scp /etc/karmada/karmada-apiserver.config 172.16.255.181:/root
kubectl karmada --kubeconfig /root/karmada-apiserver.config join member2 --cluster-kubeconfig=$HOME/.kube/config
添加其他集群,也是同样的步骤。
取消注册
kubectl karmada unjoin member1 --kubeconfig=<karmada kubeconfig> --cluster-kubeconfig=<member1 kubeconfig>
pull
Karmada 控制平面不会访问成员集群,而是将其委托给名为 karmada-agent 的额外组件。
每个 karmada-agent 服务于一个集群并负责:
- 将集群注册到 Karmada(创建 Cluster 对象)
- 维护集群状态并向 Karmada 报告(更新 Cluster 对象的状态)
- 从 Karmada 执行空间(命名空间, karmada-es-
)观察清单并将观察到的资源部署到代理服务的集群。
karmadactl register 用于以PULL方式将成员集群注册到Karmada控制平面。
注意:目前它仅支持由 karmadactl init 安装的 Karmada 控制平面。
kubectl karmada register 172.16.255.183:32443 --token 1m6mo8.67kyttanwzdtkyie --discovery-token-ca-cert-hash sha256:eb0a2521a061df87d8a76db378f11b2d08ecd0a9fbf0a26455eee81b827c118d
# token过期的话,重新生成
karmadactl token create --print-register-command --kubeconfig /etc/karmada/karmada-apiserver.config
如果没有指定的话,用的是kubernets为集群名,需要将集群重命名。
删除原集群
删除原有资源,添加cluster-name参数。
kubectl delete cluster kubernetes --kubeconfig /etc/karmada/karmada-apiserver.config
rm -rf /etc/karmada
k delete secrets -n karmada-system karmada-kubeconfig
k delete sa -n karmada-system karmada-agent-sa
k delete deploy karmada-agent -n karmada-system
kubectl karmada register 172.16.255.183:32443 --token 1m6mo8.67kyttanwzdtkyie --discovery-token-ca-cert-hash sha256:eb0a2521a061df87d8a76db378f11b2d08ecd0a9fbf0a26455eee81b827c118d --cluster-name=member3
添加其他集群,也是同样的步骤。
查看集群
启用karmada-search
创建crd
tar xvf crds.tar.gz
cd crds
k apply -f bases/
cat karmada-search-api.yaml
apiVersion: apiregistration.k8s.io/v1
kind: APIService
metadata:
name: v1alpha1.search.karmada.io
labels:
app: karmada-search
apiserver: "true"
spec:
insecureSkipTLSVerify: true
group: search.karmada.io
groupPriorityMinimum: 2000
service:
name: karmada-search
namespace: karmada-system
version: v1alpha1
versionPriority: 10
k apply -f karmada-search-api.yaml
karmadactl addons enable karmada-search
启用karmada-descheduler
karmadactl addons enable karmada-descheduler
启用karmada-scheduler-estimator
karmadactl addons enable karmada-scheduler-estimator -C member1 --member-kubeconfig /etc/karmada/karmada-apiserver.config --member-context karmada-apiserver
scp 172.16.255.181:/root/.kube/config /root/.kube/member2.config
scp 172.16.255.182:/root/.kube/config /root/.kube/member3.config
karmadactl addons enable karmada-scheduler-estimator -C member2 --member-kubeconfig /root/.kube/member2.config --member-context kubernetes-admin@kubernetes
karmadactl addons enable karmada-scheduler-estimator -C member3 --member-kubeconfig /root/.kube/member3.config --member-context kubernetes-admin@kubernetes
添加karmada-scheduler的启动参数。
测试
创建nginx测试
注意:这里要用karmada的context,即ka。
cd karmada-master/samples/nginx (git clone后的目录)
ka apply -f deployment.yaml
创建将 nginx 分发到成员集群的 PropagationPolicy
cat propagationpolicy.yaml
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
name: nginx-propagation
spec:
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
name: nginx
placement:
clusterAffinity:
clusterNames:
- member2
- member3
replicaScheduling:
replicaDivisionPreference: Weighted
replicaSchedulingType: Divided
weightPreference:
staticWeightList:
- targetCluster:
clusterNames:
- member2
weight: 1
- targetCluster:
clusterNames:
- member3
weight: 1
ka create -f propagationpolicy.yaml
查看部署情况:
使用OpenSearch图形化展示k8s资源
创建ResourceRegistry,Cache Deployment resources。
cat deployment-search.yaml
apiVersion: search.karmada.io/v1alpha1
kind: ResourceRegistry
metadata:
name: deployment-search
spec:
targetCluster:
clusterNames:
- member2
- member3
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
ka create -f deployment-search.yaml
测试API访问
ka get --raw /apis/search.karmada.io/v1alpha1/search/cache/apis/apps/v1/deployments
部署OpenSearch
./hack/deploy-karmada-opensearch.sh $HOME/.kube/config kubernetes-admin@kubernetes
修改karmada-opensearch-dashboards svc为nodePort
更新ResourceRegistry
cat deployment-search.yaml
apiVersion: search.karmada.io/v1alpha1
kind: ResourceRegistry
metadata:
name: deployment-search
spec:
backendStore:
openSearch:
addresses:
- http://karmada-opensearch.karmada-system.svc:9200
targetCluster:
clusterNames:
- member2
- member3
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
ka apply -f deployment-search.yaml
查看index
OpenSearch可以查询到member2和member3的deployment。
测试descheduler
修改PropagationPolicy的weightPreference为dynamicWeight,添加member1,测试descheduler。
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
name: nginx-propagation
spec:
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
name: nginx
placement:
clusterAffinity:
clusterNames:
- member1
- member2
- member3
replicaScheduling:
replicaDivisionPreference: Weighted
replicaSchedulingType: Divided
weightPreference:
dynamicWeight: AvailableReplicas
将member2设置不可调度,并删除nginx pod
等5-7分钟,member2上的pod会被驱逐,重新调度到其他cluster中。
调度器日志,重新调度rb到member3上。
控制器日志,判断member2上的nginx是unhealthy。
测试Cluster Accurate Scheduler Estimator
这两个参数replicaSchedulingType: Divided,replicaDivisionPreference: Aggregated。
调度器将尝试根据成员集群的所有可用资源来聚合划分副本。精准调度。
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
name: nginx-propagation
spec:
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
name: nginx
placement:
clusterAffinity:
clusterNames:
- member1
- member2
- member3
replicaScheduling:
replicaSchedulingType: Divided
replicaDivisionPreference: Aggregated
修改nginx deployment,添加resource
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
resources:
requests:
cpu: "100"
memory: 200Gi
查看pod,都没有调度成功。
调度器日志显示没有足够的资源去调度rb。