DevOps/Kubernetes

[Kubernetes Study - 05] 기본 실습 (3) - AKS를 이용한 내부 클러스터 통신

돌돌김 2021. 1. 22. 00:48

인프런에서 쿠버네티스 강의를 듣는데, 강의 환경은 VM 3개를 띄워서 1대는 마스터 노드, 나머지 2대는 워커노드로 사용을 한다.

 

이번 강의에서 실습한 내용은 아래와 같다

  • Pod에 Service를 붙이기
  • Master Node에서 curl로 Cluster IP를 호출한다
    • 해당 IP의 9000번 포트에 접근하여 hostname을 url 매개변수로 넘겨주면 9000번 포트에 올라가 있는  Pod의 호스트 네임이 출력된다. (Pod의 이미지의 내용이 이렇다)

 

우선 각 오브젝트들의 매니페스트 정보는 다음과 같다

 

pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-1
  labels:
    app: pod
spec:
  nodeSelector:
    kubernetes.io/hostname: aks-agentpool-19228959-vmss000000
  containers:
    - name: container
      image: tmkube/app
      ports:
        - containerPort: 8080
  • 3개의 Worker Node 중 aks-agentpool-19228959-vmss000000에 pod-1을 배포한다.
  • 이 Pod의 내용은 url에 hostname이 들어오면 해당 hostname을 출력해주는 것이다.

 

service.yaml
apiVersion: v1
kind: Service
metadata:
  name: svc-1
spec:
  selector:
    app: pod
  ports:
    - port: 9000
      targetPort: 8080
  • Type을 따로 명시하지 않았으므로 Cluster IP로 기본 설정된다.
  • 9000번 포트로 접근하면 (Pod가 떠있는)8080번 포트로 연결을 해준다

 

pod-1에 문제가 생겨 pod-1을 수동으로 삭제하거나, 자동으로 삭제되었다가 다시 pod-1이 만들어지면, svc-1의 selector로 pod-1의 label을 설정했기 때문에 pod-1을 삭제하고 다시 만들어도 svc-1에 자동으로 연결되게 된다.

 

이때 pod-1의 IP는 바뀌지만, svc-1의 IP는 그대로 유지되기 때문에 사용자 입장에서는 처음부터 사용하던 IP로 접속을 해도 아무 지장이 없다. 이것이 Service를 사용하는 이유이자 장점이다. 

 

단, Type이 Cluster IP이므로 클러스터 내부에서만 접근 가능하다.

  • 외부에서 접근 하려면 Type을 LoadBalancer로 지정해주면 된다

 

강의와 다른점

 

강의에서는 Master Node에서 아래와 같이 IP를 호출하면 호스트네임을 출력해준다.

하지만 내가 사용하는 AKS의 경우 Master Node가 Azure자체이고 사용자가 접근, 관리하는 노드는 워커노드이다. 그렇기 때문에 강의에서 curl 명령어로 한 것을 똑같이 하면 요청을 받지 못한다.

$ curl 10.240.0.4:9000/hostname
curl: (7) Failed to connect to 10.240.0.4 port 9000: Connection timed out

 

 

현재 떠있는 Pod, Service, Node의 상태는 아래와 같다.

$ ktl get pod -o wide
NAME                  READY   STATUS    RESTARTS   AGE     IP            NODE                                NOMINATED NODE   READINESS GATES
pod-1                 1/1     Running   0          4h49m   10.244.2.5    aks-agentpool-19228959-vmss000000   <none>           <none>
replication-1-jjwqq   1/1     Running   0          14h     10.244.1.21   aks-agentpool-19228959-vmss000001   <none>           <none>

$ ktl get svc -o wide
NAME         TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)          AGE     SELECTOR
hello-svc    ClusterIP      10.0.157.34    52.231.64.238   8200/TCP         38h     app=hello
kubernetes   ClusterIP      10.0.0.1       <none>          443/TCP          10d     <none>
svc-2        NodePort       10.0.187.187   <none>          9000:30000/TCP   4h17m   app=pod
svc-3        LoadBalancer   10.0.169.32    20.194.48.15    9000:31923/TCP   3h30m   app=pod

$ ktl get node -o wide
NAME                                STATUS   ROLES   AGE   VERSION    INTERNAL-IP   EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION     CONTAINER-RUNTIME
aks-agentpool-19228959-vmss000000   Ready    agent   10d   v1.18.10   10.240.0.4    <none>        Ubuntu 18.04.5 LTS   5.4.0-1034-azure   docker://19.3.12
aks-agentpool-19228959-vmss000001   Ready    agent   10d   v1.18.10   10.240.0.5    <none>        Ubuntu 18.04.5 LTS   5.4.0-1036-azure   docker://19.3.12
aks-agentpool-19228959-vmss000002   Ready    agent   10d   v1.18.10   10.240.0.6    <none>        Ubuntu 18.04.5 LTS   5.4.0-1034-azure   docker://19.3.12

 

 

이를 그림으로 나타내면 아래와 같다

 

 

여기서 node들은 vmss로 '가상머신 확장집합'이다.

 

즉, VM인 것이다. 강의에서 처럼 curl 을 통해 클러스터 내부 IP로 통신을 하는 것을 테스트 해보려면 node안으로 들어가야 한다. 방법은 아래 문서를 참고해서 할 수 있다.

 

 

AKS(Azure Kubernetes Service) 클러스터 노드에 대한 SSH 연결 만들기 - Azure Kubernetes Service

문제 해결 및 유지 관리 작업은 AKS(Azure Kubernetes Service) 클러스터 노드를 사용하여 SSH 연결을 만드는 방법을 알아봅니다.

docs.microsoft.com

 

AKS에서 Worker Node에 ssh로 접속하기

 

$ CLUSTER_RESOURCE_GROUP=$(az aks show --resource-group {resource-group-name} --name {aks-name} --query nodeResourceGroup -o tsv)
$ SCALE_SET_NAME=$(az vmss list --resource-group $CLUSTER_RESOURCE_GROUP --query [0].name -o tsv)
$ az vmss list --resource-group $CLUSTER_RESOURCE_GROUP --query [0].name -o tsv


# 접속을 위한 ssh key 생성. 
$ ssh-keygen -t rsa -C "inflearn-aks-node"


# SSH 키 가상 머신 확장 집합 노드에 추가
$  az vmss extension set  \
     --resource-group $CLUSTER_RESOURCE_GROUP \
     --vmss-name $SCALE_SET_NAME \
     --name VMAccessForLinux \
     --publisher Microsoft.OSTCExtensions \
     --version 1.4 \
     --protected-settings "{\"username\":\"azureuser\", \"ssh_key\":\"$(cat ~/.ssh/id_rsa.pub)\"}"

$ az vmss update-instances --instance-ids '*' \
     --resource-group $CLUSTER_RESOURCE_GROUP \
     --name $SCALE_SET_NAME

# 도우미 Pod 생성 (--rm 옵션이 붙어있어서 접속된 파드에서 나오면 파드가 죽는다. 죽으면 여기서부터 새로 다시 해줘야 한다)
$ kubectl run -it --rm aks-ssh --image=debian


# 도우미 Pod내에서 openssh 설치
root@aks-ssh:/# apt-get update && apt-get install openssh-client -y

# 도우미 Pod의 접속을 유지한 채로 새로운 터미널 창에서 작업 다시한다.
$ kubectl cp ~/.ssh/id_rsa $(kubectl get pod -l run=aks-ssh -o jsonpath='{.items[0].metadata.name}'):/id_rsa


root@aks-ssh:/# chmod 0600 id_rsa
root@aks-ssh:/# ssh -i id_rsa azureuser@10.240.0.4 # vmss의 private IP로 접속

 

접속 테스트

 

이렇게 하면 Worker Node 중 하나인 0000번 노드에 접속을 할 수 있다. 

 

접속해서 아래와 같이 cluster IP를 호출하면 hostname이 정상적으로 출력되는 것을 볼 수 있다.

 

# svc-2의 clusterIP 호출 (type : Nodeport)
azureuser@aks-agentpool-19228959-vmss000000:~$ curl 10.0.187.187:9000/hostname
Hostname : pod-1

# svc-2에서 30000번 포트 호출 : 여기서는 왜 localhost로 해야하는지 잘 모르겠다..
azureuser@aks-agentpool-19228959-vmss000000:~$ curl localhost:30000/hostname
Hostname : pod-1

# svc-3의 clusterIP 호출 (type : LoadBalancer)
azureuser@aks-agentpool-19228959-vmss000000:~$ curl 10.0.169.32:9000/hostname
Hostname : pod-1

# svc-3의 External-IP호출 (type : LoadBalancer)
azureuser@aks-agentpool-19228959-vmss000000:~$ curl 20.194.48.15:9000/hostname
Hostname : pod-1

LoadBalancer의 경우 AKS와 같은 SaaS를 이용하면 기본적으로  제공해주는 기능이지만, 직접 VM에 구축하는 경우에는 추가적인 플러그인을 설치해야만 LoadBalancer를 사용할 수 있다.