본문 바로가기
Cloud Side/Platform > Azure

[Azure] Kubernetes를 이용한 MSA 배포 셋팅 일대기

by developerBeluga 2023. 4. 14.
728x90
반응형

 

 

 

결국 도움이 된다!

https://bcoding-lab.tistory.com/315

'AKS를 이용해 서버 배포하기' 라는 이름으로 포스팅을 한지 벌써 6개월 이상 지났네요. 당시 회사 서비스는 MVP 버전으로 아직 클라우드 진입까지는 힘든 시기였습니다. 하지만 먼저 공부해보는 것도 좋을 것 같아 동기님과 이거저거 만져봤었죠.

 

그때의 경험이 절 살렸습니다 🥹

 

최근 회사 서비스가 급속도로 개발되면서 클라우드 도입이 빠른 시일내에 완료되어야 하는 과제가 되었어요. 작년 8월에 미리 공부하지 않았다면 불과 일주일만에 클라우드 도입은 하지 못했을거라 예상해봅니다. 여러분들도 미리미리 공부하시면 나~중에 도움이 되실게요! 특히 블로그에 세세히 적어놓으니 제가 제걸 보고 따라하는 진풍경이 나왔답니다. 이미 겪은 에러도 피해갈 수 있었고요. 이렇게 블로그가 큰 도움이 된답니다.

 

 

 

 

pod간 통신.. 그거 어떻게 하는건데

자화상

 

본격적으로 제가 클라우드 배포 셋팅을 하면서 경험했던 일들을 이야기해보도록 하겠습니다.

 

MSA의 꽃이 뭘까요? 바로 서버간 통신이라고 생각합니다. 여러 서버가 서로에게 통신하면서 마치 하나의 서버처럼 움직이죠. Docker에서는 docker-compose를 이용해서 하나의 App에서 여러개의 container를 운영했습니다. 그래서 A라는 컨테이너가 B라는 컨테이너에 접속하기 위해서는 docker-compose.yaml 파일에 env 파일에서 가져오거나 컨테이너 이름을 넣어주면 됐습니다.

1. env에서 불러오기
  a:
    image: "a"
    build:
      ...
    environment:
      b: ${B_PORT}
      
2. 이름으로 호출하기
  a:
    image: "a"
    build:
      ...
    environment:
      B_URL: b

 

그렇다면 Kubernetes에서는 어떻게 해줘야 할까요? 

 

 

 

Pod 간 통신 ❌ 

리소스 단위를 작성하는 매니페스트를 kompose를 도움으로 한 번에 작성했습니다. 대체로 외부와 소통해야하는 proxy 서버를 제외하고는 Deplyment로만 작성되어져 있어 Service는 없고 Pod만 있는 상태였습니다. 이럴 경우 어떻게 해야할까요? 빠른 이해를 위해 간단한 예시 코드를 보도록 하죠.

 

        ...
        spec:
          containers:
            - env:
                - name: B_URL
                  value: b

아까 2. 이름으로 호출을 kompose로 전환하니 위와 같이 작성되었어요. 될까요? 아니야 되지 않습니다. 즉, Kubernetes에서는 Pod 이름을 작성한다고 해서 알아서 다른 서버의 IP를 가지고 오지 않습니다. 이게 Docker와 다른 부분이었습니다.

 

        ...
        spec:
          containers:
            - env:
                - name: B_URL
                  value: 12.345.6.789

그러면 직접 Pod의 IP를 적으면 되지 않을까요? 여기에서 가장 큰 문제가 생깁니다. 바로 Pod는 재시작할시 새로운 IP를 할당 받는다는 것! 왜 큰 문제냐고요? yaml 파일인 매니페스트에 환경변수를 적어 넣어으면서 새로운 IP를 할당 받을 경우 다시 환경변수를 변경해주어야 합니다. A라는 Pod의 환경변수에 B만 있으면 다행이지 C, D 등 N개의 Pod URL의 환경변수가 있으면 얼마나 귀찮게 변경해줘야 하는 일이 생길까요? 

 

1. A라는 Pod
        ...
        spec:
          containers:
            - env:
                - name: B_URL
                  value: 12.345.6.789




2. B라는 Pod
        ...
        spec:
          containers:
            - env:
                - name: C_URL
                  value: 00.000.0.000



3. C라는 Pod
        ...
        spec:
          containers:
            - env:
                - name: A_URL
                  value: 00.000.0.000

또 무한 변경에 빠질 수 있습니다. 위 코드와 같이 A, B, C라는 Pod가 서로를 물고 있습니다. B Pod의 매니페스트를 변경할 경우 재시작 되면서 B Pod의 IP가 바뀌었습니다. 이럴경우 A Pod env에 있는 B_URL을 변경해줘야 합니다. A Pod가 변경되었으니 당연히 A Pod의 IP도 바뀌겠죠? 그럼 C Pod env에 있는 A_URL을 바꿔줘야 하고.. 결국 무한 변경에 빠지게 됩니다.

 

그렇기 때문에 env에 직접적으로 IP를 박아넣는건 위험합니다. 그러면 어떻게 해줘야 할까요?

 

 

 

Service간 통신 ⭕️

제목에서 알 수 있다시피 Pod간 통신이 아닌 Service간 통신을 해주시면 됩니다. Service의 경우 외부 통신을 하기 위해 IP의 주소가 고정되어져 있습니다. 아무리 재시작을 하더라도 IP의 주소가 바뀌지 않는것!

 

// 1. service 문법에 맞춰 넣어주기
-apiVersion: v1
    kind: Service
    metadata:
      name: B
    spec:
      selector:
        app.kubernetes.io/name: B
      ports:
        - protocol: TCP
          port: 80
          
// 2. yaml 적용시키기
kubectl apply -f [파일이름].yaml

// 3. 특정 Pod의 env 조회하기
kubectl exec [Pod 이름]  -- env

매니페스트에서 각 서버마다 Service를 추가해줬어요. 수정한 ymal 파일을 apply를 해주면 저절로 env에 B_SERVICE_HOST와 같이 서버들마다 가져올 수 있게 이름과 IP가 들어가 있습니다. 하나의 Pod에만 있는 env가 아니기 때문에 어디서든 가져다 쓸 수 있는 IP를 동적으로 가져올 수 있게 되었습니다.

 

내부에서만 통신하기 때문에 기본 형태인 ClusterIP로 가능해서 type을 기입하지 않았습니다. 혹시 외부와 통신해야 하는 분들은 type에 LoadBalancer를 입력해주세요. proxy를 ClusterIP로 하니깐 외부에서 통신을 못하더라고요 👀

 

 

  - apiVersion: apps/v1
    kind: Deployment
    metadata:
      ...
      name: A
    spec:
      ...
        spec:
          containers:
            - env:
                - name: B_URL
                  value: $(B_SERVICE_HOST)

위 코드처럼 다른 서버인 A에서 환경변수에 자동적으로 저장된 B_SERVICE_HOST를 가져와 사용하면 됩니다. 그러면 기존과 같이 A 서버에서 B서버로 통신 할 수 있어요.

 

실은 Service를 이용하면 된다는 것을 공식문서에서 봐서 알았지만 왜 Pod로는 안되는지 이해가 안되서 직접 실험해봤습니다. 스스로 이해하는게 가장 중요하다고 생각하기 때문에 할 수 있었던 뻘짓이라고 생각합니다 😅 여러분들은 바로 Service로 통신하세요. 

 

 

 

 

마무리 

실은 제가 클라우드에 막연한 두려움이 있답니다. 왜그럴까 고민해보니, 

1. 공짜인 개발환경과 달리 돈 폭탄을 맞을수도 있는 클라우드라서

2. 모르는게 많은데 무작정하면 안 될 것 같아서

 

그래서 이번 클라우드 개발에 참여할 때 어쩌다가 kubernetes까지 종합해서 서버 배포를 할 줄 몰랐어요. 일주일 동안 개발하면서 많은 것을 배웠고, 아마 제가 셋팅한 환경이 부족한 경우도 있을것이라 생각합니다. 이번 기회에 클라우드랑 친해졌으면 해요.

 

혹시 잘못된 정보나 새로운 정보가 있으시다면 언제든지 댓글 남겨주세요 🙌

 

 

 

 

 

참고

https://kubernetes.io/ko/docs/concepts/services-networking/connect-applications-service/

 

서비스와 애플리케이션 연결하기

컨테이너 연결을 위한 쿠버네티스 모델 지속적으로 실행중이고, 복제된 애플리케이션을 가지고 있다면 네트워크에 노출할 수 있다. 쿠버네티스는 파드가 배치된 호스트와는 무관하게 다른 파

kubernetes.io

 

 

 

 

 

728x90
반응형

댓글