메인 콘텐츠로 건너뛰기
블로그 컨테이너(쿠버네티스, 도커) 리전 간 쿠버네티스 확장

지역 간 쿠버네티스 확장

리전 간 쿠버네티스 확장 그래픽

이 게시물은 쿠버네티스 스케일링 시리즈의 일부입니다. 등록하여 라이브로 시청하거나 녹화에 액세스하고 이 시리즈의 다른 게시물을 확인하십시오.

Kubernetes의 한 가지 흥미로운 과제는 여러 지역에 워크로드를 배포하는 것입니다. 기술적으로는 서로 다른 지역에 여러 노드가 있는 클러스터를 가질 수 있지만 일반적으로 추가 대기 시간으로 인해 피해야 하는 것으로 간주됩니다 .

인기 있는 대안은 각 지역에 클러스터를 배포하고 이를 오케스트레이션하는 방법을 찾는 것입니다.

여러 지역에 노드가 있는 Kubernetes 클러스터를 나타내는 다이어그램(항상 좋은 생각은 아님)과 배포해야 하는 각 지역에 클러스터가 있는 경우(고급 접근 방식)
여러 지역에 걸쳐 있는 노드가 있는 클러스터가 있거나 각 지역에 대한 클러스터가 있을 수 있습니다.

이 게시물에서는 다음을 수행합니다.

  1. 3개의 클러스터(북미, 유럽, 동남아시아에 하나씩)를 생성합니다.
  2. 다른 클러스터에 대한 오케스트레이터 역할을 할 네 번째 클러스터를 만듭니다.
  3. 원활한 통신을 위해 세 개의 클러스터 네트워크 중에서 단일 네트워크를 설정합니다.

이 게시물은 함께 작동하도록 작성되었습니다. Terraform 최소한의 상호 작용이 필요합니다. 이에 대한 코드는 LearnK8s GitHub에서 찾을 수 있습니다.

클러스터 관리자 작성

나머지를 관리할 클러스터를 만드는 것부터 시작하겠습니다. 다음 명령을 사용하여 클러스터를 생성하고 kubeconfig 파일을 저장할 수 있다.

bash
$ linode-cli lke cluster-create \
 --label cluster-manager \
 --region eu-west \
 --k8s_version 1.23
 
$ linode-cli lke kubeconfig-view "insert cluster id here" --text | tail +2 | base64 -d > kubeconfig-cluster-manager

다음을 사용하여 설치가 성공했는지 확인할 수 있습니다.

bash
$ kubectl get pods -A --kubeconfig=kubeconfig-cluster-manager

훌륭한!

클러스터 관리자에서 여러 Kubernetes 클러스터 및 클라우드에서 클라우드 네이티브 애플리케이션을 실행할 수 있는 관리 시스템인 Karmada를 설치합니다. Karmada에는 클러스터 관리자에 컨트롤 플레인이 설치되어 있고 다른 모든 클러스터에 에이전트가 설치되어 있습니다.

컨트롤 플레인에는 세 가지 구성 요소가 있습니다.

  1. An API 서버;
  2. 컨트롤러 관리자; 그리고
  3. 스케줄러
카르마다 제어 플레인으로 구성된 카르마다 제어 플레인 다이어그램 API 서버, 컨트롤러 관리자, 스케줄러로 구성된 제어 플레인 다이어그램.
카르마다의 조종기.

익숙해 보인다면 Kubernetes 컨트롤 플레인 이 동일한 구성 요소를 갖추고 있기 때문입니다! Karmada는 여러 클러스터에서 작동하도록 복사하고 보강해야 했습니다.

이론은 충분하다. 코드를 살펴봅시다.
헬름을 사용하여 Karmada API 서버를 설치합니다. 헬름 리포지토리를 추가해 보겠습니다:

bash
$ helm repo add karmada-charts https://raw.githubusercontent.com/karmada-io/karmada/master/charts
$ helm repo list
NAME            URL
karmada-charts   https://raw.githubusercontent.com/karmada-io/karmada/master/charts

카르마다 API 서버는 다른 모든 클러스터에서 연결할 수 있어야 하므로, 다음을 수행해야 합니다.

  • 노드에서 노출하십시오. 그리고
  • 연결을 신뢰할 수 있는지 확인합니다.

따라서 제어 평면을 호스팅하는 노드의 IP 주소를 검색해 보겠습니다.

bash
kubectl get nodes -o jsonpath='{.items[0].status.addresses[?(@.type==\"ExternalIP\")].address}' \
 --kubeconfig=kubeconfig-cluster-manager

이제 다음을 사용하여 Karmada 컨트롤 플레인을 설치할 수 있습니다.

bash
$ helm install karmada karmada-charts/karmada \
 --kubeconfig=kubeconfig-cluster-manager \
 --create-namespace --namespace karmada-system \
 --version=1.2.0 \
 --set apiServer.hostNetwork=false \
 --set apiServer.serviceType=NodePort \
 --set apiServer.nodePort=32443 \
 --set certs.auto.hosts[0]="kubernetes.default.svc" \
 --set certs.auto.hosts[1]="*.etcd.karmada-system.svc.cluster.local" \
 --set certs.auto.hosts[2]="*.karmada-system.svc.cluster.local" \
 --set certs.auto.hosts[3]="*.karmada-system.svc" \
 --set certs.auto.hosts[4]="localhost" \
 --set certs.auto.hosts[5]="127.0.0.1" \
 --set certs.auto.hosts[6]="<insert the IP address of the node>"

설치가 완료되면, kubeconfig를 검색하여 카르마다에 연결할 수 있다. API 에 연결할 수 있습니다:

bash
kubectl get secret karmada-kubeconfig \
 --kubeconfig=kubeconfig-cluster-manager \
 -n karmada-system \
 -o jsonpath={.data.kubeconfig} | base64 -d > karmada-config

하지만 잠깐, 왜 다른 kubeconfig 파일입니까?

카르마다 API 는 표준 쿠버네티스를 대체하도록 설계되었지만 API 를 대체하도록 설계되었지만 익숙한 모든 기능을 그대로 유지합니다. 즉, kubectl을 사용하여 여러 클러스터에 걸친 배포를 생성할 수 있습니다.

Karmada API 및 kubectl을 테스트하기 전에 kubeconfig 파일을 패치해야 한다. 기본적으로 생성된 kubeconfig는 클러스터 네트워크 내에서만 사용할 수 있다.

그러나 다음 줄을 바꾸어 작동하도록 할 수 있습니다.

yaml
apiVersion: v1
kind: Config
clusters:
 - cluster:
     certificate-authority-data: LS0tLS1CRUdJTi…
     insecure-skip-tls-verify: false
     server: https://karmada-apiserver.karmada-system.svc.cluster.local:5443 # <- this works only in the cluster
   name: karmada-apiserver
# truncated

이전에 검색한 노드의 IP 주소로 바꿉니다.

yaml
apiVersion: v1
kind: Config
clusters:
 - cluster:
     certificate-authority-data: LS0tLS1CRUdJTi…
     insecure-skip-tls-verify: false
     server: https://<node's IP address>:32443 # <- this works from the public internet
   name: karmada-apiserver
# truncated

좋아, 카르마다 시험할 시간이야.

카르마다 에이전트 설치

다음 명령을 실행하여 모든 배포 및 모든 클러스터를 검색합니다.

bash
$ kubectl get clusters,deployments --kubeconfig=karmada-config
No resources found

당연히 배포와 추가 클러스터가 없습니다. 클러스터를 몇 개 더 추가하고 Karmada 컨트롤 플레인에 연결해 보겠습니다.

다음 명령을 세 번 반복합니다.

bash
linode-cli lke cluster-create \
 --label <insert-cluster-name> \
 --region <insert-region> \
 --k8s_version 1.23
 
linode-cli lke kubeconfig-view "insert cluster id here" --text | tail +2 | base64 -d > kubeconfig-<insert-cluster-name>

값은 다음과 같아야 합니다.

  • 클러스터 이름 eu부위 eu-west 및 kubeconfig 파일 kubeconfig-eu
  • 클러스터 이름 ap부위 ap-south 및 kubeconfig 파일 kubeconfig-ap
  • 클러스터 이름 us부위 us-west 및 kubeconfig 파일 kubeconfig-us

다음을 사용하여 클러스터가 성공적으로 생성되었는지 확인할 수 있습니다.

bash
$ kubectl get pods -A --kubeconfig=kubeconfig-eu
$ kubectl get pods -A --kubeconfig=kubeconfig-ap
$ kubectl get pods -A --kubeconfig=kubeconfig-us

이제 카르마다 클러스터에 합류할 차례입니다.

Karmada는 다른 모든 클러스터에서 에이전트를 사용하여 컨트롤 플레인과의 배포를 조정합니다.

쿠버네티스 클러스터에서 클러스터 제어 플레인(API 서버, 컨트롤러 관리자 및 스케줄러)에 연결하는 Karmada 에이전트 다이어그램.
카르마다 요원.

Helm을 사용하여 Karmada 에이전트를 설치하고 클러스터 관리자에 연결합니다.

bash
$ helm install karmada karmada-charts/karmada \
 --kubeconfig=kubeconfig-<insert-cluster-name> \
 --create-namespace --namespace karmada-system \
 --version=1.2.0 \
 --set installMode=agent \
 --set agent.clusterName=<insert-cluster-name> \
 --set agent.kubeconfig.caCrt=<karmada kubeconfig certificate authority> \
 --set agent.kubeconfig.crt=<karmada kubeconfig client certificate data> \
 --set agent.kubeconfig.key=<karmada kubeconfig client key data> \
 --set agent.kubeconfig.server=https://<insert node's IP address>:32443 \

위의 명령을 세 번 반복하고 다음 변수를 삽입해야합니다.

  • 클러스터 이름입니다. 이것은 다음 중 하나입니다. eu, ap또는 us
  • 클러스터 관리자의 인증 기관입니다. 이 값은 karmada-config 파일 under clusters[0].cluster['certificate-authority-data'].
    다음에서 값을 디코딩 할 수 있습니다. 베이스64.
  • 사용자의 클라이언트 인증서 데이터입니다. 이 값은 karmada-config 파일 아래 users[0].user['client-certificate-data'].
    base64에서 값을 디코딩할 수 있습니다.
  • 사용자의 클라이언트 인증서 데이터입니다. 이 값은 karmada-config 파일 아래 users[0].user['client-key-data'].
    base64에서 값을 디코딩할 수 있습니다.
  • 카르마다 컨트롤 플레인을 호스팅하는 노드의 IP 주소입니다.

설치가 완료되었는지 확인하려면 다음 명령을 실행할 수 있습니다.

bash
$ kubectl get clusters --kubeconfig=karmada-config
NAME   VERSION   MODE   READY
eu     v1.23.8   Pull   True
ap     v1.23.8   Pull   True
us     v1.23.8   Pull   True

훌륭한!

Karmada 정책을 사용한 다중 클러스터 배포 오케스트레이션

현재 구성을 사용하면 Karmada에 워크로드를 제출한 다음 다른 클러스터에 분산합니다.

배포를 만들어 테스트해 보겠습니다.

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
 name: hello
spec:
 replicas: 3
 selector:
   matchLabels:
     app: hello
 template:
   metadata:
     labels:
       app: hello
   spec:
     containers:
       - image: stefanprodan/podinfo
         name: hello
---
apiVersion: v1
kind: Service
metadata:
 name: hello
spec:
 ports:
   - port: 5000
     targetPort: 9898
 selector:
   app: hello

배포를 Karmada API 서버에 배포를 제출할 수 있습니다:

bash
$ kubectl apply -f deployment.yaml --kubeconfig=karmada-config

이 배포에는 세 개의 복제본이 있으며 세 개의 클러스터에 균등하게 배포됩니까?

확인하자 :

bash
$ kubectl get deployments --kubeconfig=karmada-config
NAME    READY   UP-TO-DATE   AVAILABLE
hello   0/3     0            0

카르마다가 포드를 생성하지 않는 이유는 무엇입니까?

배포를 설명해 보겠습니다.

bash
$ kubectl describe deployment hello --kubeconfig=karmada-config
Name:                   hello
Namespace:              default
Selector:               app=hello
Replicas:               3 desired | 0 updated | 0 total | 0 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Events:
 Type     Reason             From               Message
 ----     ------             ----               -------
 Warning  ApplyPolicyFailed  resource-detector  No policy match for resource

Karmada는 정책을 지정하지 않았기 때문에 배포로 무엇을 해야 할지 모릅니다.

Karmada 스케줄러는 정책을 사용하여 클러스터에 워크로드를 할당합니다.

각 클러스터에 복제본을 할당하는 간단한 정책을 정의해 보겠습니다.

yaml
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
 name: hello-propagation
spec:
 resourceSelectors:
   - apiVersion: apps/v1
     kind: Deployment
     name: hello
   - apiVersion: v1
     kind: Service
     name: hello
 placement:
   clusterAffinity:
     clusterNames:
       - eu
       - ap
       - us
   replicaScheduling:
     replicaDivisionPreference: Weighted
     replicaSchedulingType: Divided
     weightPreference:
       staticWeightList:
         - targetCluster:
             clusterNames:
               - us
           weight: 1
         - targetCluster:
             clusterNames:
               - ap
           weight: 1
         - targetCluster:
             clusterNames:
               - eu
           weight: 1

다음을 사용하여 클러스터에 정책을 제출할 수 있습니다.

bash
$ kubectl apply -f policy.yaml --kubeconfig=karmada-config

배포 및 Pod를 검사해 보겠습니다.

bash
$ kubectl get deployments --kubeconfig=karmada-config
NAME    READY   UP-TO-DATE   AVAILABLE
hello   3/3     3            3
 
$ kubectl get pods --kubeconfig=kubeconfig-eu
NAME                    READY   STATUS    RESTARTS
hello-5d857996f-hjfqq   1/1     Running   0
 
$ kubectl get pods --kubeconfig=kubeconfig-ap
NAME                    READY   STATUS    RESTARTS
hello-5d857996f-xr6hr   1/1     Running   0
 
$ kubectl get pods --kubeconfig=kubeconfig-us
NAME                    READY   STATUS    RESTARTS
hello-5d857996f-nbz48   1/1     Running   0
각 지역(프리몬트, 캘리포니아, 런던, 싱가포르)에 위치한 쿠버네티스 클러스터를 보여주는 맵 그래픽
Karmada는 각 클러스터에 포드를 할당했습니다.

Karmada는 정책이 각 클러스터에 대해 동일한 가중치를 정의했기 때문에 각 클러스터에 포드를 할당했습니다.

다음을 사용하여 배포를 10개의 복제본으로 확장해 보겠습니다.

bash
$ kubectl scale deployment/hello --replicas=10 --kubeconfig=karmada-config

포드를 검사하면 다음을 찾을 수 있습니다.

bash
$ kubectl get deployments --kubeconfig=karmada-config
NAME    READY   UP-TO-DATE   AVAILABLE
hello   10/10   10           10
$ kubectl get pods --kubeconfig=kubeconfig-eu
NAME                    READY   STATUS    RESTARTS
hello-5d857996f-dzfzm   1/1     Running   0
hello-5d857996f-hjfqq   1/1     Running   0
hello-5d857996f-kw2rt   1/1     Running   0
hello-5d857996f-nz7qz   1/1     Running   0
 
$ kubectl get pods --kubeconfig=kubeconfig-ap
NAME                    READY   STATUS    RESTARTS
hello-5d857996f-pd9t6   1/1     Running   0
hello-5d857996f-r7bmp   1/1     Running   0
hello-5d857996f-xr6hr   1/1     Running   0
 
$ kubectl get pods --kubeconfig=kubeconfig-us
NAME                    READY   STATUS    RESTARTS
hello-5d857996f-nbz48   1/1     Running   0
hello-5d857996f-nzgpn   1/1     Running   0
hello-5d857996f-rsp7k   1/1     Running   0

EU 및 미국 클러스터가 포드의 40%를 보유하고 AP 클러스터에 20%만 남도록 정책을 수정해 보겠습니다.

yaml
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
 name: hello-propagation
spec:
 resourceSelectors:
   - apiVersion: apps/v1
     kind: Deployment
     name: hello
   - apiVersion: v1
     kind: Service
     name: hello
 placement:
   clusterAffinity:
     clusterNames:
       - eu
       - ap
       - us
   replicaScheduling:
     replicaDivisionPreference: Weighted
     replicaSchedulingType: Divided
     weightPreference:
       staticWeightList:
         - targetCluster:
             clusterNames:
               - us
           weight: 2
         - targetCluster:
             clusterNames:
               - ap
           weight: 1
         - targetCluster:
             clusterNames:
               - eu
           weight: 2

다음을 사용하여 정책을 제출할 수 있습니다.

bash
$ kubectl apply -f policy.yaml --kubeconfig=karmada-config

그에 따라 포드의 분포가 변경되는 것을 관찰할 수 있습니다.

bash
$ kubectl get pods --kubeconfig=kubeconfig-eu
NAME                    READY   STATUS    RESTARTS   AGE
hello-5d857996f-hjfqq   1/1     Running   0          6m5s
hello-5d857996f-kw2rt   1/1     Running   0          2m27s
 
$ kubectl get pods --kubeconfig=kubeconfig-ap
hello-5d857996f-k9hsm   1/1     Running   0          51s
hello-5d857996f-pd9t6   1/1     Running   0          2m41s
hello-5d857996f-r7bmp   1/1     Running   0          2m41s
hello-5d857996f-xr6hr   1/1     Running   0          6m19s
 
$ kubectl get pods --kubeconfig=kubeconfig-us
hello-5d857996f-nbz48   1/1     Running   0          6m29s
hello-5d857996f-nzgpn   1/1     Running   0          2m51s
hello-5d857996f-rgj9t   1/1     Running   0          61s
hello-5d857996f-rsp7k   1/1     Running   0          2m51s
Karmada 컨트롤러가 설정한 정책에 따라 여러 지역에 분산된 포드를 보여주는 지도 다이어그램(캘리포니아 프리몬트에서 40%, 런던에서 40%, 싱가포르에서 20%).
Pod는 정책에 따라 배포됩니다.

대!

Karmada는 워크로드를 분산하기 위한 여러 정책을 지원합니다. 고급 사용 사례 에 대한 설명서를 확인할 수 있습니다 .

포드가 세 클러스터에서 실행되고 있지만 어떻게 액세스할 수 있습니까?

카르마다 서비스를 살펴 보겠습니다.

bash
$ kubectl describe service hello --kubeconfig=karmada-config
Name:              hello
Namespace:         default
Labels:            propagationpolicy.karmada.io/name=hello-propagation
                  propagationpolicy.karmada.io/namespace=default
Selector:          app=hello
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.105.24.193
IPs:               10.105.24.193
Port:              <unset>  5000/TCP
TargetPort:        9898/TCP
Events:
 Type     Reason                  Message
 ----     ------                  -------
 Normal   SyncSucceed             Successfully applied resource(default/hello) to cluster ap
 Normal   SyncSucceed             Successfully applied resource(default/hello) to cluster us
 Normal   SyncSucceed             Successfully applied resource(default/hello) to cluster eu
 Normal   AggregateStatusSucceed  Update resourceBinding(default/hello-service) with AggregatedStatus successfully.
 Normal   ScheduleBindingSucceed  Binding has been scheduled
 Normal   SyncWorkSucceed         Sync work of resourceBinding(default/hello-service) successful.

서비스는 세 클러스터 모두에 배포되지만 연결되어 있지 않습니다.

Karmada가 여러 클러스터를 관리할 수 있더라도 세 개의 클러스터가 연결되어 있는지 확인하는 네트워킹 메커니즘을 제공하지 않습니다 . 즉, Karmada는 클러스터 간에 배포를 오케스트레이션하는 훌륭한 도구이지만 이러한 클러스터가 서로 통신할 수 있도록 하려면 다른 것이 필요합니다.

다중 클러스터를 Istio와 연결

Istio 는 일반적으로 동일한 클러스터에 있는 애플리케이션 간의 네트워크 트래픽을 제어하는 데 사용됩니다. 나가는 모든 요청을 가로채고 Envoy를 통해 프록시하는 방식으로 작동합니다.

Envoy 프록시가 트래픽을 가로채서 다른 Pod에 배포하는 방법을 보여 주는 다이어그램입니다.
특사 프록시는 모든 트래픽을 가로챕니다.

Istio 컨트롤 플레인은 해당 프록시에서 메트릭을 업데이트하고 수집하는 작업을 담당하며 트래픽을 전환하기 위한 지침을 발행할 수도 있습니다.

Istio 컨트롤 플레인이 프록시를 즉시 재구성할 수 있는 방법을 보여주는 다이어그램으로, Pod 간의 트래픽을 거부하는 규칙을 가질 수 있습니다.
Istio를 사용하면 클러스터의 트래픽을 관리하는 정책을 정의할 수 있습니다.

따라서 Istio를 사용하여 특정 서비스에 대한 모든 트래픽을 가로채서 세 클러스터 중 하나로 보낼 수 있습니다. 이것이 Istio 다중 클러스터 설정의 아이디어입니다.

그것으로 충분한 이론입니다 – 우리 손을 더럽 히자. 첫 번째 단계는 세 클러스터에 Istio를 설치하는 것입니다.

Istio를 설치하는 방법에는 여러 가지가 있지만 일반적으로 Helm을 선호합니다.

bash
$ helm repo add istio https://istio-release.storage.googleapis.com/charts
$ helm repo list
NAME            URL
istio                 https://istio-release.storage.googleapis.com/charts

다음을 사용하여 세 클러스터에 Istio를 설치할 수 있습니다.

bash
$ helm install istio-base istio/base \
 --kubeconfig=kubeconfig-<insert-cluster-name> \
 --create-namespace --namespace istio-system \
 --version=1.14.1

교체해야 합니다. cluster-nameap, eu 그리고 us 각각에 대해 명령을 실행하십시오.

기본 차트는 역할 및 역할 바인딩과 같은 대부분의 공통 리소스를 설치합니다.

실제 설치는 istiod 차트. 그러나 계속 진행하기 전에 다음을 수행해야 합니다. 이스티오 인증 기관(CA) 구성 세 클러스터가 서로 연결하고 신뢰할 수 있는지 확인합니다.

새 디렉토리에서 다음을 사용하여 Istio 저장소를 복제합니다.

bash
$ git clone https://github.com/istio/istio

만들기 certs 폴더를 클릭하고 해당 디렉토리로 변경하십시오.

bash
$ mkdir certs
$ cd certs

다음을 사용하여 루트 인증서를 만듭니다.

bash
$ make -f ../istio/tools/certs/Makefile.selfsigned.mk root-ca

이 명령은 다음 파일을 생성했습니다.

  • root-cert.pem: 생성된 루트 인증서
  • root-key.pem: 생성된 루트 키
  • root-ca.conf: 루트 인증서를 생성하기 위한 OpenSSL에 대한 구성
  • root-cert.csr: 루트 인증서에 대해 생성된 CSR

각 클러스터에 대해 Istio 인증 기관에 대한 중간 인증서 및 키를 생성합니다.

bash
$ make -f ../istio/tools/certs/Makefile.selfsigned.mk cluster1-cacerts
$ make -f ../istio/tools/certs/Makefile.selfsigned.mk cluster2-cacerts
$ make -f ../istio/tools/certs/Makefile.selfsigned.mk cluster3-cacerts

이 명령은 다음과 같은 디렉터리에 다음 파일을 생성합니다. cluster1, cluster2그리고 cluster3:

bash
$ kubectl create secret generic cacerts -n istio-system \
 --kubeconfig=kubeconfig-<cluster-name>
 --from-file=<cluster-folder>/ca-cert.pem \
 --from-file=<cluster-folder>/ca-key.pem \
 --from-file=<cluster-folder>/root-cert.pem \
 --from-file=<cluster-folder>/cert-chain.pem

다음 변수를 사용하여 명령을 실행해야 합니다.

| cluster name | folder name |
| :----------: | :---------: |
|      ap      |  cluster1   |
|      us      |  cluster2   |
|      eu      |  cluster3   |

이 작업이 완료되면 마침내 istiod를 설치할 준비가 된 것입니다.

bash
$ helm install istiod istio/istiod \
 --kubeconfig=kubeconfig-<insert-cluster-name> \
 --namespace istio-system \
 --version=1.14.1 \
 --set global.meshID=mesh1 \
 --set global.multiCluster.clusterName=<insert-cluster-name> \
 --set global.network=<insert-network-name>

다음 변수를 사용하여 명령을 세 번 반복해야 합니다.

| cluster name | network name |
| :----------: | :----------: |
|      ap      |   network1   |
|      us      |   network2   |
|      eu      |   network3   |

또한 Istio 네임스페이스에 토폴로지 주석을 지정해야 합니다.

bash
$ kubectl label namespace istio-system topology.istio.io/network=network1 --kubeconfig=kubeconfig-ap
$ kubectl label namespace istio-system topology.istio.io/network=network2 --kubeconfig=kubeconfig-us
$ kubectl label namespace istio-system topology.istio.io/network=network3 --kubeconfig=kubeconfig-eu

그게 다야?

거의.

동서 게이트웨이를 사용한 터널링 트래픽

여전히 다음이 필요합니다.

  • 한 클러스터에서 다른 클러스터로 트래픽을 퍼널하는 게이트웨이; 그리고
  • 다른 클러스터에서 IP 주소를 검색하는 메커니즘입니다.
엔드포인트를 검색하고 Pod 간에 동서 게이트웨이를 설치하는 Istio 다중 클러스터를 보여 주는 다이어그램입니다.
Istio 다중 클러스터: 엔드포인트 검색 및 동서 게이트웨이 설치.

게이트웨이의 경우 Helm을 사용하여 설치할 수 있습니다.

bash
$ helm install eastwest-gateway istio/gateway \
 --kubeconfig=kubeconfig-<insert-cluster-name> \
 --namespace istio-system \
 --version=1.14.1 \
 --set labels.istio=eastwestgateway \
 --set labels.app=istio-eastwestgateway \
 --set labels.topology.istio.io/network=istio-eastwestgateway \
 --set labels.topology.istio.io/network=istio-eastwestgateway \
 --set networkGateway=<insert-network-name> \
 --set service.ports[0].name=status-port \
 --set service.ports[0].port=15021 \
 --set service.ports[0].targetPort=15021 \
 --set service.ports[1].name=tls \
 --set service.ports[1].port=15443 \
 --set service.ports[1].targetPort=15443 \
 --set service.ports[2].name=tls-istiod \
 --set service.ports[2].port=15012 \
 --set service.ports[2].targetPort=15012 \
 --set service.ports[3].name=tls-webhook \
 --set service.ports[3].port=15017 \
 --set service.ports[3].targetPort=15017 \

다음 변수를 사용하여 명령을 세 번 반복해야 합니다.

| cluster name | network name |
| :----------: | :----------: |
|      ap      |   network1   |
|      us      |   network2   |
|      eu      |   network3   |

그런 다음 각 클러스터에 대해 다음 리소스가 있는 게이트웨이를 노출합니다.

yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
 name: cross-network-gateway
spec:
 selector:
   istio: eastwestgateway
 servers:
   - port:
       number: 15443
       name: tls
       protocol: TLS
     tls:
       mode: AUTO_PASSTHROUGH
     hosts:
       - "*.local"

다음을 사용하여 클러스터에 파일을 제출할 수 있습니다.

bash
$ kubectl apply -f expose.yaml --kubeconfig=kubeconfig-eu
$ kubectl apply -f expose.yaml --kubeconfig=kubeconfig-ap
$ kubectl apply -f expose.yaml --kubeconfig=kubeconfig-us

검색 메커니즘의 경우 각 클러스터의 자격 증명을 공유해야 합니다. 이는 클러스터가 서로를 인식하지 못하기 때문에 필요합니다.

다른 IP 주소를 검색하려면 다른 클러스터에 액세스하여 트래픽의 가능한 대상으로 등록해야 합니다. 이렇게 하려면 다른 클러스터에 대한 kubeconfig 파일을 사용하여 쿠버네티스 시크릿을 생성해야 한다.

Istio는 이를 사용하여 다른 클러스터에 연결하고, 엔드포인트를 검색하고, Envoy 프록시에 트래픽을 전달하도록 지시합니다.

세 가지 비밀이 필요합니다.

yaml
apiVersion: v1
kind: Secret
metadata:
 labels:
   istio/multiCluster: true
 annotations:
   networking.istio.io/cluster: <insert cluster name>
 name: "istio-remote-secret-<insert cluster name>"
type: Opaque
data:
 <insert cluster name>: <insert cluster kubeconfig as base64>

다음 변수를 사용하여 세 개의 비밀을 만들어야 합니다.

| cluster name | secret filename |  kubeconfig   |
| :----------: | :-------------: | :-----------: |
|      ap      |  secret1.yaml   | kubeconfig-ap |
|      us      |  secret2.yaml   | kubeconfig-us |
|      eu      |  secret3.yaml   | kubeconfig-eu |

이제 AP 암호를 AP 클러스터에 제출하지 않도록 주의하면서 클러스터에 비밀을 제출해야 합니다.

명령은 다음과 같아야 합니다.

bash
$ kubectl apply -f secret2.yaml -n istio-system --kubeconfig=kubeconfig-ap
$ kubectl apply -f secret3.yaml -n istio-system --kubeconfig=kubeconfig-ap
 
$ kubectl apply -f secret1.yaml -n istio-system --kubeconfig=kubeconfig-us
$ kubectl apply -f secret3.yaml -n istio-system --kubeconfig=kubeconfig-us
 
$ kubectl apply -f secret1.yaml -n istio-system --kubeconfig=kubeconfig-eu
$ kubectl apply -f secret2.yaml -n istio-system --kubeconfig=kubeconfig-eu

그리고 그게 다야!

설정을 테스트할 준비가 되었습니다.

멀티클러스터 네트워킹 테스트

절전 포드에 대한 배포를 만들어 보겠습니다.

이 포드를 사용하여 이전에 생성한 Hello 배포에 대한 요청을 수행합니다.

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
 name: sleep
spec:
 selector:
   matchLabels:
     app: sleep
 template:
   metadata:
     labels:
       app: sleep
   spec:
     terminationGracePeriodSeconds: 0
     containers:
       - name: sleep
         image: curlimages/curl
         command: ["/bin/sleep", "3650d"]
         imagePullPolicy: IfNotPresent
         volumeMounts:
           - mountPath: /etc/sleep/tls
             name: secret-volume
     volumes:
       - name: secret-volume
         secret:
           secretName: sleep-secret
           optional: true

다음을 사용하여 배포를 만들 수 있습니다.

bash
$ kubectl apply -f sleep.yaml --kubeconfig=karmada-config

이 배포에 대한 정책이 없으므로 Karmada는 이를 처리하지 않고 보류 상태로 둡니다. 다음과 함께 배포를 포함하도록 정책을 수정할 수 있습니다.

yaml
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
 name: hello-propagation
spec:
 resourceSelectors:
   - apiVersion: apps/v1
     kind: Deployment
     name: hello
   - apiVersion: v1
     kind: Service
     name: hello
   - apiVersion: apps/v1
     kind: Deployment
     name: sleep
 placement:
   clusterAffinity:
     clusterNames:
       - eu
       - ap
       - us
   replicaScheduling:
     replicaDivisionPreference: Weighted
     replicaSchedulingType: Divided
     weightPreference:
       staticWeightList:
         - targetCluster:
             clusterNames:
               - us
           weight: 2
         - targetCluster:
             clusterNames:
               - ap
           weight: 2
         - targetCluster:
             clusterNames:
               - eu
           weight: 1

다음과 함께 정책을 적용할 수 있습니다.

bash
$ kubectl apply -f policy.yaml --kubeconfig=karmada-config

다음을 사용하여 Pod가 배포된 위치를 파악할 수 있습니다.

bash
$ kubectl get pods --kubeconfig=kubeconfig-eu
$ kubectl get pods --kubeconfig=kubeconfig-ap
$ kubectl get pods --kubeconfig=kubeconfig-us

이제 포드가 미국 클러스터에 도착했다고 가정하고 다음 명령을 실행합니다.

Now, assuming the pod landed on the US cluster, execute the following command:
bash
for i in {1..10}
do
 kubectl exec --kubeconfig=kubeconfig-us -c sleep \
   "$(kubectl get pod --kubeconfig=kubeconfig-us -l \
   app=sleep -o jsonpath='{.items[0].metadata.name}')" \
   -- curl -sS hello:5000 | grep REGION
done

응답이 다른 지역의 다른 포드에서 오는 것을 알 수 있습니다!

작업 완료!

여기서 어디로 가야합니까?

이 설정은 매우 기본적이며 통합하려는 몇 가지 기능이 더 부족합니다.

이 게시물에서 다룬 내용을 요약하면 다음과 같습니다.

  • Karmada를 사용하여 여러 클러스터를 제어합니다.
  • 여러 클러스터에 걸쳐 워크로드를 예약하는 정책 정의;
  • Istio를 사용하여 여러 클러스터의 네트워킹을 연결합니다. 그리고
  • Istio가 트래픽을 가로채서 다른 클러스터로 전달하는 방법.

다른 확장 방법론 외에도 지역 간 Kubernetes를 확장하는 전체 연습은 웨비나 시리즈에 등록 하고 온디맨드로 시청하여 확인할 수 있습니다.

내용

댓글 남기기

이메일 주소는 게시되지 않습니다. 필수 필드가 표시됩니다 *