데보션앱 소개페이지 바로가기
로그인 선택

신고하기

CLOSE
신고사유 (대표 사유 1개)
상세내용 (선택)
0/200
  • 신고한 게시글은 더 이상 보이지 않습니다.
  • 이용약관과 운영정책에 따라 신고사유에 해당하는지 검토 후 조치됩니다.
  • 허위 신고인 경우, 신고자의 서비스 이용이 제한될 수 있으니 유의하시어 신중하게 신고해 주세요.
(이 회원이 작성한 모든 댓글과 커뮤니티 게시물이 보이지 않고, 알림도 오지 않습니다.)

미리보기

커뮤니티

      1,234

      badge 23.06.15

      글 등록

      카테고리를 선택해주세요.

      DEVOTEE를 활성화 시키면
      지금 작성한 커뮤니티 글에 대해 1개의 댓글을 달아줍니다.

      버튼을 누르면 글 수정 시 ChatGPT가 작성한 댓글이 수정됩니다.

      임시저장함에 저장되었습니다. 저장일시 : 2022.5.17 14:29:08

      임시저장함

      제목을 선택하시면 이어서 작성이 가능하며,
      최대 20건까지 저장합니다.
      컨텐츠 유형, 제목, 저장일시, 삭제로 이뤄진 임시저장 목록
      컨텐츠 유형 제목 저장일 삭제

      데보션 블로그 게재 요청

      CLOSE
      • *
      • *

      본인인증

      효율적인 데보션 서비스 이용 및
      고객님의 소중한 개인정보보호를 위해
      본인인증을 진행해주세요. 본인인증 미 진행 시 로그인이 제한됩니다.
      본인인증 실패

      본인인증 로그인에 실패하였습니다.
      회원이 아니시거나 본인인증 등록이
      완료되지 않은 사용자입니다.

      회원정보 연결

      [3기 스터디] 딥다이브 쿠버네티스 세번째 스터디 (07.23)

      강만쥬 24.07.27
      157 3 2
      DEVOTEE 요약
      7월 23일 삼화타워에서 진행된 딥다이브 쿠버네티스 3회차 오프라인 스터디에서는 주로 지난 회차의 복습이 이루어졌습니다. 쿠버네티스의 기본 개념과 배포 전략, 그리고 다양한 서비스 타입에 대해 설명하며, 실제 kubectl 명령어를 통한 실습 내용을 다루었습니다. 마지막으로 개인 실습과 관련된 질의응답 내용도 포함하여, 실습을 통해 이론을 굳히는 과제를 제시했습니다.
      DEVOTEE 추천 블로그

      안녕하세요, 데보션영 3기에서 활동 중인 강대훈입니다 🐈


      지난 7월 23일 삼화타워에서 딥다이브 쿠버네티스 3회차 오프라인 스터디가 진행되었습니다. 👋

      3회차 정도 되니까 찾아가는 길도 익숙하고, 어색함도 많이 없어졌습니다.

      이번에도 간단한 간식과 함께 스터디를 시작했는데요, 쉑쉑 버거에 야채튀김이 들어가 있는 건 처음 먹어봤는데 매콤하고 맛있었습니다 🤤


      스터디 내용

      이번 스터디는 2회차에 이어 약 한달 만에 진행되었다 보니, 주로 지난 회차 복습 위주로 진행되었습니다.

      지난 회차 후기 글에 학습 내용을 자세히 적어놓았기 때문에 이번 후기에서는 중요하게 다시 다룬 내용과, 나왔던 질문들 위주로 정리해보겠습니다.


      쿠버네티스의 특징

      우선 쿠버네티스가 생긴 배경은 다음과 같습니다.

      온프레미스 환경이든 클라우드든 일정한 컴퓨팅 리소스(ex 2core CPU & 8GB ram 등) 스펙이 있으면 그만큼 일을 할 수 있는 것인데,

      사용자가 많아져 서버를 스케일 아웃하게 될 때 생기는 문제는 엔트리 포인트(ip)가 그만큼 여러개가 생기는 것입니다.


      이를 해결하기 위해 대표 IP를 두고, 부하를 분산시켜주어야합니다.

      (L4 로드밸런서 등으로 로드밸런싱을 하며, L7 로드밸런서는 도메인이나, url 뒤쪽 path 경로에 따라서도 로드밸런싱을 시켜줄 수 있습니다.)


      쿠버네티스를 구현하기 위해 내부적으로는 iptables와 ipvs라는 모듈을 사용합니다.

      이 모듈들을 쿠버네티스는 핸들링하고, 클러스터 내에서 로드밸런싱을 해줍니다. (내부에서는 service가)

      iptables는 리눅스 커널에서 제공하는 패킷 필터링 및 네트워크 주소 변환(NAT) 프레임워크입니다.

      sNAT, dNAT등의 작업을 iptables에서 해줄 수 있습니다.

      IPVS(IP Virtual Server)는 리눅스 커널의 로드 밸런싱 기술로, 더 효율적이고 확장성이 뛰어난 네트워크 트래픽 처리를 제공합니다.

      kube-proxy는 IPVS를 사용하여 서비스 트래픽을 처리할 수 있습니다.


      용어 정리

      • 워크로드 : 우리가 실제로 만들고 실행중인 서비스. (컨트롤 플레인에는 배포 x)

      • kubectl : 쿠버네티스 API에 요청하기 위한 CLI tool.

      • apiVersion : yaml 파일이 나타내는 버전으로 v1이면 Pod의 core 버전. (그냥 외우기)

      • --dry-run : kubectl 사용 시 줄 수 있는 옵션으로 명령어를 서버에서 실제로 실행하진 않고, 서버에서 명령어를 테스트만 해서 어떻게 동작하는 지 보여준다.

      • 에어갭 : IDC 등 인터넷이 안되는 환경

      배포 전략

      • 블루그린 배포 : 새 버전을 한 환경에 배포하고 테스트한 후, 트래픽을 새 환경으로 전환하는 방식입니다.

      • 카나리 배포 : 새 버전을 소수의 사용자에게 먼저 배포하여 문제를 찾고, 점진적으로 트래픽을 늘리는 방식입니다.

      • 롤링 업데이트 : 시스템의 가용성을 유지하면서 새로운 버전을 점진적으로 배포하는 방식입니다.

      • Recreate : 기존 버전을 완전히 중단하고 새로운 버전을 배포하는 방식입니다.


      쿠버네티스 사용하기

      그렇다면 kubectl은 API 요청을 보내기 위해서 어떻게 인증받을까요?

      ➡️ 해당 인증 관련 내용은 config파일에 설정되어있습니다.


      kubectl describe pod 명령어를 통해 자세하게 pod의 정보를 볼 수 있는데, 각종 변경 사항은 event에 내용이 나옵니다.

      (2주 정도의 시간이 지나면 rotation이 일어나 내용이 없어진다.)



      kubectl logs <pod name> 명령어를 쓰면 log들을 볼 수 있습니다.



      쿠버네티스 배포

      실제 쿠버네티스 배포 환경에서는 deploy파일이나 명령어로 배포하는 경우는 거의 없고, 대부분 helm 차트로 배포합니다.


      helm 차트란?

      yalm 파일들을 모아놓은 것.


      디플로이먼트, 스테이트셋, 데몬 셋 등의 파드들을 재시작하고싶다면, 일일이 파드를 삭제하는 것 보단

      kubectl rollout restart deployment 등을 통해 파드를 재시작할 수 있습니다.


      특정 노드에 레이블을 주고, 그 레이블을 데몬셋에 적용하면 해당 레이블을 가진 노드들에만 배포가 됩니다.


      ConfigMap

      만약 volume mount한다는 yaml이 있으면, kubernetes에게 configmap을 달라고 요청을 합니다.

      그러면 먼저 서버에 tmpfs를 먼저 생성하고, 그걸 mount하는 순서로 이루어집니다.


      만약 네임스페이스가 다르면 configmap이 없는걸로 인식하고, 가져올 수 없기 때문에 이 경우엔 배포가 안되고 pending상태로 멈추게 됩니다.


      그 말인 즉슨 해당하는 configmap 혹은 secret이 존재하지 않을 때 pending 상태로 멈추게 됩니다.

      이 경우에 describe pod에서 event를 보면 원인이 나와있습니다.


      (중요) 따라서 kind로 설치했을 때 포트포워딩을 미리 해주는게 좋습니다.


      서비스

      ClusterIP

      apiVersion: v1
      
      kind: Service
      
      metadata:
        name: nginx-service
        namespace: ask
      
      spec:
        selector:
      	app: nginx
      
        ports:
        - protocol: TCP
      
      port: 8080
      
          targetPort: 80
      
        type: ClusterIP

      위 코드는 클러스터IP 타입인 서비스의 기본적인 yaml 파일입니다.


      위 yaml 파일을 보면 IP를 명시한 곳이 없습니다.

      그렇다면 서비스는 어떻게 IP를 안줘도 파드를 찾아갈 수 있을까요?


      바로 selector(혹은 label)를 보고 해당하는 파드를 찾아갑니다.


      타입이 ClusterIP 타입이면 내부적으로 사용한다는 의미입니다.

      파드는 다운되었다가 살아나면 ip가 업데이트 될 수 있으므로 파드에 접근하고 싶으면 꼭 서비스를 만들어야하고, 서비스의 dns로 접속하는 것이 권장됩니다.(추후 배울 ingress)


      엔드포인트는 pod의 ip와 port를 계속 가지고 있습니다.

      서비스에 접속이 잘 안되면 엔드포인트가 잘 생성되어 있는지를 먼저 확인합니다. (selector가 잘 지정되었는지)

      그래도 접속이 안되면? 타겟포트가 잘 지정되었는지를 확인합니다.


      Nodeport


      Nodeport 서비스의 구조는 위와 같습니다.


      여기서 서비스는 노드의 포트를 오픈시켜주는 역할과, 해당하는 파드로 연결되는 역할을 하고 포트 자체는 kubeproxy가 열게 됩니다.

      최근들어선 주로 Iptables 대신 ipvs를 사용합니다.


      노드포트란, 노드의 어떤 포트로 먼저 들어갈 지를 먼저 확인하고 지정해주어야합니다.

      만약 지정해주지 않으면 알아서 할당되긴 하지만, 그래도 직접 명시하는 편이 좋습니다.


      그러나 만약 클러스터 내에 여러 노드에 파드가 배포되어 있다면, 원하는 노드로 들어가지 않고 다른 노드의 파드에 접근할 수도 있다. (서비스를 통한 로드밸런싱)


      하지만 service.yaml 파일에서 spec.externalTrafficPolicy: Local 옵션을 통해 해당하는 IP의 노드의 파드에만 접근하도록 할 수 있습니다. (로드밸런싱 x)


      위에서 서비스가 다른 노드의 파드를 로드밸런싱 해줄 때는, 써드파티인 네트워크 모듈이 도와줍니다.

      포워딩 관련 정보는 ipvs에 적혀있게 됩니다.


      ++노드 포트는 테스트용으로만 사용하고, 실제로는 가상 ip를 사용하는 것이 좋습니다.


      LoadBalancer


      로드밸런서 타입은 퍼블릭 클라우드에 실제로 로드밸런서를 생성합니다.

      이는 클라우드 프로바이더들이 모두 만들어놓습니다.


      쿠버네티스에서 로드밸런서 타입이 들어오면,

      내 클라우드에 해당하는 L4 로드밸런서를 생성➡️ 가상 IP를 주고,➡️ 포트를 줍니다.➡️ 로드밸런서는 노드간의 로드밸런싱만 해줍니다.


      여기서 질문 드렸던 내용이,

      로드밸런서가 로드밸런싱을 해준다면, 한 노드의 포트로 들어온 API 요청에 대해 서비스는 다시 한 번 자신의 노드와 다른 노드의 파드에 대해 로드밸런싱을 해주는가? 였습니다.


      멘토님께서 이 문제로 인해 로드밸런서 타입에서는 externaltrafficpolicy: local 옵션이 자동으로 주어지기 때문에, 해당하는 노드의 파드에만 접근하도록 할 수 있다고 하셨습니다.

      (로드밸런싱을 여러번 하게 될 경우 그만큼 오버헤드로 인한 손실이 발생하므로)


      개인 실습

      멘토님께서 수업 중 Kind와 Minikube 등으로 쿠버네티스 클러스터를 설치한 경우, 포트포워딩을 미리 해주는 것이 좋다고 말씀해주셨습니다.

      다만 그 이유에 대해서는 잘 이해가 되지않았기에 실습을 통해 그 이유와 방법을 정리해보겠습니다.

      먼저 helm을 통해 간단한 API 서버를 띄워보았습니다.

      helm chart의 values.yaml은 다음과 같습니다.



      deployment와 파드도 정상적으로 띄워졌고



      서비스도 정상 작동 중인 것을 확인했습니다. (노드의 30080 포트와 컨테이너의 8080 포트를 연결)



      그러나 웹 브라우저에서 30080 포트로 접속해도 아무런 응답을 볼 수 없었습니다.


      분명 Nodeport 서비스를 이용하면 외부 접속을 허용해줄 수 있다고 하였는데 왜 그런 걸까요?


      그 이유인 즉슨, 로컬 환경에서 실행하는 kind와 minikube와 같은 tool들은 k8s 클러스터를 격리하여 실행시키는데,

      이로 인해서 외부에서 클러스터 내부로 직접적인 접근을 제한하기 때문입니다.

      그러므로 따로 port mapping을 통해서 외부에서 클러스터 내부로 트래픽을 전달할 수 있게 해야합니다.


      다음과 같이 kubectl port-forward를 통해 직접 포트포워딩을 해줄 수도 있습니다.




      그러나 위 방법은 터미널이 종료될 경우 포트포워딩이 끊긴다는 단점이 있습니다.

      따라서 이를 해결하기 위해서는 다른 방법이 필요합니다.


      Kind 클러스터 포트포워딩하기 (with config.yaml)


      이를 위해 클러스터를 새로 만들어보겠습니다. (이 때문에 클러스터를 생성할 때 포트포워딩을 하라는 말씀이었습니다.)


      먼저 다음과 같이 kind-config.yaml 파일을 생성해줍니다. (~/.kube/config의 config와는 다른 개념입니다.)

      extraPortMappings를 보면 호스트의 30080 포트를 노드의 30080 포트로 포트포워딩 하고있습니다.

      apiVersion: kind.x-k8s.io/v1alpha4
      kind: Cluster
      name: test
      networking:
        apiServerAddress: "0.0.0.0"
        apiServerPort: 6443
      nodes:
      - role: control-plane
        extraPortMappings:
        - containerPort: 30080
          hostPort: 30080
          protocol: TCP

      그리고 클러스터 생성시 다음처럼 옵션을 주어 생성해줍니다.



      클러스터가 생성되었다면 미리 만들어 둔 helm chart로 어플리케이션을 배포합니다.



      아까와 동일하게 파드와 서비스가 생성된 것을 확인할 수 있습니다.


      Nodeport 서비스에서 노드의 30080포트를 내부 컨테이너의 8080포트로 포트포워딩하고 있습니다.

      클러스터 설치 시 미리 호스트와 노드를 포트포워딩 했기 때문에 이번엔 별도의 포트포워딩 없이 배포가 완료된 모습입니다.



      수업 중 질문 모음

      Q. minikube와 kind의 차이점은 뭔가요?.

      A. 미니쿠베는 vm형에서 docker container형으로 변경되었고,minikube는 도커 컨테이너로 띄웠을 때 lb랑 통신하게끔 바깥에서 안쪽으로 들어오게 설정하는게 쉽지 않다.


      Q. 마스터 노드가 여러 개인 경우도 있나요?

      A. 당연히 존재하고, api 서버는 클러스터링으로 최소 3개씩사용하고, 나머지 컴포넌트들은 leader가 선출되어서 3개가 떠있어도 하나만 사용한다.

      etcd 또한 여러개 띄운 뒤 클러스터링 해서 동기화한다. 각 API 서버가 자기껄 하나씩 맡아서 쓰면 되니까 L4 스위치는 굳이 필요없기도 하지만, 모두 설정하기 나름이다.


      Q. 쿠버네티스가 참조하는 config 파일의 우선순위는 어떻게 되나요?

      A. 명령어에 파라미터로 주어진 컨피그를 참조하고, 존재하지 않는다면 KUBECONFIG 환경 변수를 참조하고, 둘 다 명시되지 않은 경우엔 default config 위치(~/.kube/config)를 바라본다.


      Q. 멀티 클러스터 환경에서 config 파일을 나눠서 클러스터를 관리하는 것과, config 파일 하나에 context정보를 모아놓고 관리하는 것의 차이점? 어떤 클러스터마다 config를 나눠주는 것이 좋을까요?

      A. 어차피 둘 다 API의 목적지가 되는 클러스터(혹은 컨텍스트)를 선택해야하는 것은 동일하다.

      보통 config를 분리하면 현재 선택된 context를 사용한다. 따라서 config를 분리하고 그 안에서 context를 또 여러 개 둔다면, 원하는 context를 사용하기 위해선 두 번 지정해야 한다.

      따라서 config 파일을 굳이 나눌 필요가 없다. (멘토님 또한 분리하지 않고 사용하신다고 하셨습니다.)


      과제

      다음 스터디까지 과제로는 서비스와 디플로이먼트 만들어서 보여주기 라고 하셨습니다.

      추가로 서비스에서는 노드포트와 클러스터ip에 대해서도 설명할 수 있다고 하셨습니다.


      모두에게 주어진 과제는 아니었지만 각자 한 번씩 실습해보며 개념을 다지고 가면 좋을 것 같습니다.

      .

      .

      .

      이번에도 좋은 내용을 많이 얻어갈 수 있어 정말 귀중한 시간이었습니다.

      스터디 시간 외에도, 개인적인 질문들도 정말 잘 받아주셔서 항상 즐겁게 배울 수 있는 것 같습니다 :)

      8월 한 달간은 2주 간격으로 스터디가 진행되어 꾸준하게 공부를 해야 다른 분들을 따라잡을 수 있을 듯합니다.

      같이 스터디하는 다른 분들도 모두 화이팅입니다 🥳


      감사합니다 ! 🙇🏻‍♂️

      댓글 0

      DEVOTEE를 활성화 시키면
      지금 작성한 댓글에 AI가 댓글을 달아줍니다.

      강만쥬 님의 최신 블로그

      더보기

      DEVOTEE 추천 블로그

      동영상 기고하기