Karmada (Kubernetes Armada) is a Kubernetes management system that enables you to run your cloud-native applications across multiple Kubernetes clusters and clouds, with no changes to your applications. By speaking Kubernetes-native APIs and providing advanced scheduling capabilities, Karmada enables truly open, multi-cloud Kubernetes.
Karmada aims to provide turnkey automation for multi-cluster application management in multi-cloud and hybrid cloud scenarios, with key features such as centralized multi-cloud management, high availability, failure recovery, and traffic scheduling.
Architecture
Source: https://karmada.io
Arquitetura do Lab
Deploy da infra
Cluster 1 ou pegasus:
[!NOTE]
Altere os valores em variables.tfvars se for necessário.
No arquivo nlb.tf, estamos informando um certificado do ACM. Altere para o seu certificado ou remova comentando as linhas 38, 39, 40 e descomentando a linha 37.
Com certificado:
load_balancer_arn = aws_lb.istio_ingress.arn
port = “443”
#protocol = “TCP”
protocol = “TLS”
certificate_arn = “arn:aws:acm:us-east-2:ACCOUNTID:certificate/bfbfe3ce-d347-4c42-8986-f45e95e04ca1”
alpn_policy = “HTTP2Preferred”
default_action {
type = “forward”
target_group_arn = aws_lb_target_group.https.arn
}
}
Sem certificado:
load_balancer_arn = aws_lb.istio_ingress.arn
port = “443”
protocol = “TCP”
# protocol = “TLS”
# certificate_arn = “arn:aws:acm:us-east-2:ACCOUNTID:certificate/bfbfe3ce-d347-4c42-8986-f45e95e04ca1”
# alpn_policy = “HTTP2Preferred”
default_action {
type = “forward”
target_group_arn = aws_lb_target_group.https.arn
}
}
Cluster 2 ou pegasus-2:
[!NOTE]
Altere os valores em variables.tfvars se for necessário.
Deploy do karmada
Entrando no contexto do cluster pegasus:
[!NOTE]
Os comandos a seguir serão executados no cluster pegasus (Cluster 1), onde temos o Argo rodando.
Verificando o deployment:
Agora já temos o controlplane do karmada rodando no cluster pegasus.
Com o deploy, é gerado um secret com o kubeconfig necessário para conectarmos no controlplane do karmada:
Criando IRSA (Iam Role for Service Account)
[!NOTE]
Altere os valores de ACCOUNTID na iam-policy-irsa-karmada.json e no comando eksctl abaixo.
Isso refletirá em uma Service Account dentro do cluster pegasus, usaremos ela montando em um pod do ubuntu como ponto de acesso temporário ao controlplane do karmada.
–policy-document file://iam-policy-irsa-karmada.json
–namespace karmada-system
–cluster pegasus
–attach-policy-arn arn:aws:iam::ACCOUNTID:policy/ubuntu-admin-karmada
–region us-east-2
–profile default
–approve
No lado AWS, isso reflete em uma IAM role que podemos adicionar nos dois clusters EKS.
EKS IAM – Console (pegasus-2):
Faça o mesmo para o cluster pegasus, onde o karmada controlplane está rodando.
Acessando Karmada API-Server
Vamos subir agora aquele pod do ubuntu-admin no cluster pegasus. No manifesto já está tudo definido para utilizar a Service Account que criamos mais acima.
Nesse momento, vamos entrar no container do ubuntu, que está rodando no cluster pegasus:
Instalando o kubectl karmada:
Entrando no contexto do cluster pegasus-2:
Vamos fazer o mesmo para o cluster pegasus:
Checando acesso ao karmada apiserver:
Join do pegasus-2 no karmada:
Join do pegasus no karmada:
Checando status dos clusters adicionados:
Instalando CLI do ArgoCD:
install -m 555 argocd-linux-amd64 /usr/local/bin/argocd
rm argocd-linux-amd64
Recuperando o secret / password do Argo server e fazendo login:
Adicionando o karmada como cluster no ArgoCD:
Deploy com ArgoCD
Se acessarmos a UI do Argo, que está rodando no cluster pegasus, veremos que o karmada está registrado como um cluster onde é possível o Argo fazer deploy:
Podemos agora aplicar um manifesto que irá definir uma nova fonte para o Argo buscar por deploys. Nesse caso, essa fonte é um repositório no GitHub:
Como já temos manifestos nesse repositório (no path /app-manifests), o Argo já faz o sync entregando essas aplicações no controlplane do karmada e o karmada por sua vez, entrega nos dois clusters de acordo com o que for definido nos manifestos de PropagationPolicy:
No cluster pegasus podemos ver:
Cluster pegasus-2:
No caso do deploy do RabbitMQ, podemos ver que existem replicas rodando nos dois clusters, quando olharmos os aquivos de PropagationPolicy poderemos entender.
Karmada OverridePolicy e PropagationPolicy
No repositório que o Argo está monitorando, podemos ver os manifestos do karmada e também o manifestos de deployment que usamos como exemplo.
Exemplo Redis
Regras de override e selector do deployment onde será aplicado, no caso ‘redis’:
kind: OverridePolicy
metadata:
name: redis-op
spec:
resourceSelectors:
– apiVersion: apps/v1
kind: Deployment
name: redis
overrideRules:
– targetCluster:
clusterNames:
– pegasus-2
overriders:
labelsOverrider:
– operator: add
value:
env: skoala-dev
– operator: add
value:
env-stat: skoala-stage
– operator: remove
value:
for: for
– operator: replace
value:
bar: test
– targetCluster:
clusterNames:
– pegasus
overriders:
annotationsOverrider:
– operator: add
value:
env: skoala-stage
– operator: remove
value:
bom: bom
– operator: replace
value:
emma: sophia
Regras de propagação, selector do deployment e target cluster. Nesse caso de failover, esse deployment deve ser migrado para o cluster pegasus-2 caso o cluster pegasus entre em falha:
kind: PropagationPolicy
metadata:
name: redis-propagation
spec:
propagateDeps: true
failover:
application:
decisionConditions:
tolerationSeconds: 120
purgeMode: Never
resourceSelectors:
– apiVersion: apps/v1
kind: Deployment
name: redis
placement:
clusterAffinity:
clusterNames:
– pegasus
– pegasus-2
spreadConstraints:
– maxGroups: 1
minGroups: 1
spreadByField: cluster
Exemplo Nginx
kind: OverridePolicy
metadata:
name: nginx-op
spec:
resourceSelectors:
– apiVersion: apps/v1
kind: Deployment
name: nginx
overrideRules:
– targetCluster:
clusterNames:
– pegasus-2
overriders:
labelsOverrider:
– operator: add
value:
env: skoala-dev
– operator: add
value:
env-stat: skoala-stage
– operator: remove
value:
for: for
– operator: replace
value:
bar: test
Neste caso, apenas o cluster pegasus-2 foi definido em ‘targetCluster’:
kind: PropagationPolicy
metadata:
name: nginx-propagation
spec:
resourceSelectors:
– apiVersion: apps/v1
kind: Deployment
name: nginx
placement:
clusterAffinity:
clusterNames:
– pegasus-2
replicaScheduling:
replicaDivisionPreference: Weighted
replicaSchedulingType: Divided
weightPreference:
staticWeightList:
– targetCluster:
clusterNames:
– pegasus-2
weight: 1
Exemplo RabbitMQ
kind: OverridePolicy
metadata:
name: rabbitmq-op
spec:
resourceSelectors:
– apiVersion: apps/v1
kind: Deployment
name: rabbitmq
overrideRules:
– targetCluster:
clusterNames:
– pegasus-2
overriders:
labelsOverrider:
– operator: add
value:
env: skoala-dev
– operator: add
value:
env-stat: skoala-stage
– operator: remove
value:
for: for
– operator: replace
value:
bar: test
– targetCluster:
clusterNames:
– pegasus
overriders:
annotationsOverrider:
– operator: add
value:
env: skoala-stage
– operator: remove
value:
bom: bom
– operator: replace
value:
emma: sophia
Aqui temos algo diferente, onde os dois clusters são definidos em ‘targetCluster’, porém com pesos (weights) diferentes, fazendo com que o karmada entregue as réplicas de acordo com o peso de cada cluster:
kind: PropagationPolicy
metadata:
name: rabbitmq-propagation
spec:
resourceSelectors:
– apiVersion: apps/v1
kind: Deployment
name: rabbitmq
placement:
clusterAffinity:
clusterNames:
– pegasus
– pegasus-2
replicaScheduling:
replicaDivisionPreference: Weighted
replicaSchedulingType: Divided
weightPreference:
staticWeightList:
– targetCluster:
clusterNames:
– pegasus
weight: 2
– targetCluster:
clusterNames:
– pegasus-2
weight: 1
Remover ubuntu-admin e IRSA
Podemos deletar o pod ubuntu que usamos para setup do karmada, e também a IRSA:
–namespace karmada-system
–cluster pegasus
–region us-east-2
–profile default
Para a próxima, vamos buscar um cenário total de DR com o karmada e ver até onde chegamos.
Keep shipping!