ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 쿠버네티스 ① 메인 K8s component (1)
    네트워크 & 인프라 2022. 10. 8. 13:15

     

     

     

     

    인프라 내용을 학습할 때 항상 나오는 쿠버네티스...!

    간단하게나마 알면 도움이 될 것같아 영상을 보고 학습하였다. 💪

    학습 내용의 출처는 모두 아래 두영상이다! 🙌

     

     

     

     

     

     

     

     

    참고한 영상 👇🏼
    • 모든 내용은 윗 영상을 캡쳐 및 정리한 내용입니다! 🙌

     

     

     

     

     

     

    쿠버네티스란?

    • 오픈소스 컨테이너 orchestration tool
      • monolith → msa
    • 구글에 의해 개발됨 (도커 등등)
    • 다른 개발 환경에서의 컨테이너 어플리케이션을 다루는데 도움을 줌

     

     

    왜 사용하는가?
    • monolith → msa
    • 컨테이너의 사용이 증가
    • 많은 컨테이너를 다루는데 어려움이 증가

     

     

     

    orchestration tool 장점
    • 컨테이너 → 용량이 작아 빠른 배포를 위해 사용됨
    • orchestration tool이 컨테이너를 알아서 배치 및 관리
    • 가용성이 높고 중단 시간이 없음
    • no dump time
    • 유저가 빠른 반응을 받을 수 있어 확장성이 높고 성능이 높음
    • 서버가 다운되는 경우 회복이 가능 ( backup and restore )
      • backup data, lateness
      • 루즈 데이터 가능성 작음

     

     

     

     

     

     

    메인 k8s 컴포넌트

    1) Node & Pod

    - Node

     

     

    - Pod

    • 컨테이너 → 1개의 어플리케이션을 담당
    • 쿠버네티스에서는 pod이 컨테이너를 표현하는 K8s API의 최소단위 ⇒ k8s의 가장 작은 단위
    • 보통 pod마다 1개의 어플리케이션을 가지지만 pod에서 하나 또는 여러개의 컨테이너를 포함 가능
    • 오직 쿠버네티스 계층과 소통함
    • 컨테이너를 대상으로 추상화
      • 컨테이너가 교체 가능
    • 각각의 pod은 각각의 ip 주소를 가짐
      • 자신만의 ip 주소를 가지고 서로 상호작용 할 수 있음
        • ex ) internal ip, public ip 등
    • 재생산시 새로운 ip 주소를 가짐
      • ip 주소는 데이터베이서 컨테이너를 잃거나 중단되었을 때 새로운 pod으로 쉽게 교체가능
      • 재할당이 가능

     

     

     

    • 1) single container pod 생성하기
      • run CLI 사용
        • $ kubectl run webserver —image=nginx:1.14
      • pod YAML을 사용
        • $kubectl create -f pod-nginx.yaml

     

     

     

     

     

     

    • 2) multi container pod 생성하기
      • pod 안의 여러개의 컨테이너는 같은 Ip 주소를 사용
      • 실행중인 컨테이너로 들어가기
        • $ kubectl exec [multipod / pod 이름] -it(interactive 하게 sudo 터미널 사용) -c [centos-container / 컨테이너 이름] — / bin / bash(bash shell 실행)
      • $ kubectl logs multipod -c nginx-container

     

     

     

     

     

     

     

    • 3) self-healing pod
      • 지속적으로 pod이 살아있음을 체크하고(kubelet으로 컨테이너 진단) 건강한 컨테이너만을 이용해서 애플리케이션 서비스를 제공함
      • livenessProbe
        • pod이 계속 실행할 수 있음 보장
        • pod의 sepc에 정의
        • 메커니즘
          • 컨테이너를 재시작해도 pod은 그대로 이기 때문에 Ip 주소는 바뀌지 않고 유지 가능
          • httpGet probe
            • 지정한 IP주소, port, path에 HTTP GET요청을 보내 해당 컨테이너가 응답하는지 확인
            • 반환코드가 200이 아닌 값일 경우 오류 발생 → 컨테이너 재시작
          • tcpSocket probe
            • 지정된 포트에 TCP 연결을 시도
            • 연결되지 않으면 컨테이너를 재시작
          • exec probe
            • exec 명령을 전달
            • 명령 종료 코드가 0이 아닌 경우 컨테이너를 재시작
        • 매개 변수
          • periodSeconds
            • health check 반복 실행 시간 (초)
          • initialDelaySeconds
            • pod 실행 후 delay할 시간 (초)
          • timeoutSeconds
            • health check 후 응답을 기다리는 시간 (초)
       

     

     

     

    • 4) init container를 적용한 pod
      • 환경구성, 초기화 세팅을 지원해주는 컨테이너
      • 앱 컨테이너가 실행 전에 미리 동작시킬 컨테이너
      • 초기화 컨테이너가 모두 실행에 성공된 후 앱 컨테이너가 실행됨
      • ex) 로그인을 할 때
        • init 컨테이너에서 로그인할 때 필요한 정보들을 가지고 옴
        • 성공적으로 가지고 왔을 경우에만 메인 컨테이너가 실행이 됨

     

     

     

     

    • 5) infra container(pause)
      • pod이 생성될때 하나씩 생성되고 pod이 제거될때 같이 사라짐
      • pod의 환경을 만들어주는 컨테이너

     

     

     

    • 6) static pod
      • API의 도움없이 kubelet이라는 데몬에 의해서 static pod 디렉토리 안에있는 YAML파일을 저장해두면 알아서 실행
      • ex) 마스터 노드의 4가지 프로세스도 모두 static pod 형식으로 실행된 것
      • 경로는 이미 static Pod path로 정의되어 있음
      • 새로운 static pod 내용을 추가하게 되면 master가 아닌 node 들 중 하나에 배치됨

     

     

     

     

     

     

    • pod에 리소스(cpu, memory) 할당하기
      • pod하나를 사용하더라도 리소스를 어느정도 사용할지 limit해주어야 함 (과사용 방지)
      • 컨테이너 별로 요구조건(request)을 이용하여 최소한의 cpu, 메모리가 남아있는 곳(pod)에 컨테이너를 배치할 수 있도록 설정
      • Pod Resource 요청 및 제한
    • Resource Requests
      • pod를 실행하기 위한 최소 리소스 양을 요청
      • ex) cpu: 200m (1000밀리코어 = 1코어) = 1/5 코어
    • Resource Limits
      • pod가 사용할 수 있는 최대 리소스 양을 제한
      • Memory limit을 초과해서 사용되는 pod는 종료(OOM Kill)되며 재스케줄링됨

     

     

     

     

     

    • pod의 환경변수 설정하기
      • pod내의 컨테이너가 실행될 때 필요로 하는 변수
      • 컨테이너 제작 시 미리 정의
      • specification의 env를 이용하여 pod 실행 시 미리 정의된 컨테이너의 환경변수를 변경 가능

     

     

     

     

     

    • pod 구성 패턴의 종류
      • pod을 구성하고 실행하는 패턴
      • multi-container pod
        • sidecar
          • pod안에 컨테이너가 2개 ⇒ 함께 동작하여 두개가 모두 있어야 동작
          • 하나는 web 서버(로그 생성)
          • 하나는 sidecar 서버(생성된 로그파일을 버킷으로 보냄)
        • adapter
          • 외부의 서비스 정보를 Adapter가 받아서 web 서버(UI정보) 컨테이너에게 전달
          • Adapter는 외부 서비스의 정보를 전달
        • ambassador
          • web 서버가 고객들과 통신하여 생성된 데이터를 Ambassador가 캐시로 저장하여 이용 (로드밸런서 역할, 분배 저장)
          • Ambassador는 웹서버가 받은 정보를 저장

     

     

     

     

     

     

     

     

    2) service 와 Ingress

    - Service

    • 각자의 서비스를 가져 각각의 pod에 영구적인 ip 주소를 지님
    • pod의 라이프사이클과 서비스는 개별
    • 두가지 기능
      • 영구 ip : DNS 안의 이름 (persistent static ip)
      • 로드밸런서 : 요청을 포워딩 (전달)

     

     

     

     

    • 쿠버네티스 네트워크
    • 동일한 서비스를 제공하는 pod 그룹의 단일 진입점(Virtual IP) 제공
    • stable 한 Ip주소를 가짐
      • 각각의 Pod은 개인의 Ip주소를 가지는데 매번 pod이 중단되거나 새로 교체될 때마다 새로운 Ip주소를 가지게 되면 불편
    • 로드밸런싱 기능을 가짐
    • 컴포넌트 끼리의 결합도 감소
    • 클러스터 내 외부와 상호작용

     

     

     

    • service endpoints
      • k8s가 생성
      • 서비스와 이름이 같으면서 어떤 pod이 서비스의 members / endpoints인지 트래킹

     

     

     

     

    • service port VS targetPort
      • service port
        • 임의의 번호
      • targetPort
        • 반드시 컨테이너가 듣고 있는 포트와 동일해야함

     

     

     

     

     

     

    1) ClusterIP services

    • 디폴트 타입 (타입이 specification에 정의되지 않아도 됨)

     

     

     

     

    • MSA 애플리케이션이 배포될 때
      • browser → ingress → service(internalService)의 IP주소와 port로 접근 → pod 이용
    • 디폴트(10.96.0.0/12범위에서 할당)로 타입 설정이 불필요
      • selector의 label이 동일한 pod들의 그룹으로 묶어 pod 그룹의 내부 단일 진입점(Virtual IP) 생성
    • internal Service
    • 클러스터 외부에서는 접근이 어려움 (클러스터 내부에서만 사용가능)

     

     

     

    • 어떤 pod으로 접근할지, 어떤 port로 접근할지 어떻게 아는가?
      • “selector” : 어떤 pod으로 갈지 설정
      • “targetPort” : 포트번호 설정

     

     

     

     

     

     

    +) Multi-Port services

    • 모니터링 측정을 위한 두번째 컨테이너
    • 이름을 정의해주어야 함

     

     

     

     

     

    +) Headless services

    • 사용 시기
      • 클라이언트가 1개의 특정 pod과 소통하려고 할 때
      • ClusterIP가 없는 서비스로 단일 진입점이 필요 없을 때 사용
      • 여러개의 pod이 하나의 특정 pod과 직접적으로 얘기하려고 할 때

     

     

     

     

     

    • 사용 예시
      • stateful 어플리케이션 (ex)databases)
      • pod 복사본이 동일하지 않음 (not identical)
      • 지속적인 데이터 동기화 필요
    • Service와 연결괸 pod의 endpoint로 DNS 레코드가 생성됨
      • pod에 대한 endpoint를 DNS resolving service로 요청이 가능
    • 클라이언트는 개별 pod의 Ip 주소를 알아야 함
      • 방법 1) K8s API서버에게 API 콜
        • K8s API에 너무 의존적임
        • 비효율적
      • 방법 2) DNS Lookup
        • 서비스의 DNS Lookup이 하나의 Ip 주소(ClusterIP)를 반환
        • ClusterIP 를 ”None”으로 설정하면 Pod IP 주소를 대신 반환함

     

     

     

     

     

    2) NodePort services

    • 외부 트래픽이 각각의 worker 노드의 고정 포트로의 접근 권한 보유
      • (기본적으로 클러스터 IP 생성함)클러스터 IP 생성 후 모든 워커 노드에 외부에서 접속가능 한 포트가 예약
      • nodePort 사용시 ClusterIP가 자동으로 생성됨
      • 클러스터 IP 생성 후 NodePort를 예약
    • 외부에서 직접적으로 접근 권한을 갖게 되어 안전하지 않음
    • ClusterIP 서비스 타입의 확장 버전
    • 디폴트 NodePort 범위 → 30000 - 32767
    • 외부 연결을 위한 것은 아님 ⇒ 테스트용으로는 사용할 수 있으나 production 모드에서는 사용하지 않음 (보안)

     

     

     

     

     

     

     

    3) LoadBalancer services

    • 외부에서 public 클라우드 provider의 로드밸런서를 통해서 접근이 가능
      • 로드밸런서를 자동으로 프로비전 하는 기능 지원
    • public cloud(AWS, Azure, GCP등)에서 운영이 가능
    • 로드밸런서를 이용하면 nodePort와 ClusterIP가 자동으로 생성됨
    • NodePort 서비스 타입의 확장 버전
      • NodePort 예약 후 해당 NodePort로 외부 접근을 허용
    • 실제 production 모드에서는 Ingress나 Loadbalancer를 사용

     

     

     

     

     

     

    4) External Name

    • 클러스터 안에서 외부에 접속 시 사용할 도메인을 등록해서 사용
      • 클러스터 내부에서 External(외부)의 도메인을 설정
      • DNS를 지원
    • 클러스터 도메인이 실제 외부 도메인으로 치환되어 동작

     

     

     

     

     

     

     

     

     

    - Ingress

    • 요청을 cluster로 라우팅
      • 웹기반의 서비스를 외부에서 접속이 가능하도록 도와줌
    • HTTP나 HTTPS를 통해 클러스터 내부의 서비스를 외부로 노출
      • Service에 외부 URL을 제공
      • 트래픽을 로드밸런싱
      • SSL 인증서 처리
      • Virtual Hosting을 지정
    • ex) 어플은 브라우저를 통해서 접근이 가능해야 함
      • http://my-app-service-ip:port → external service (o)
        • ex) https://my-app.com → Ingress 가 service로 포워딩 해준다.
      • http://db-service-ip:port → internal service (x)
    • 예시 웹페이지 구현)

    • external service VS Ingress
      • external service
        • ip address : port (마지막 배포 형태가 아님)
      • ingress
        • 도메인 이름 (https://) (ip address and port가 공개되지 않음)
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: dashboard-ingress
      namespace: kubernetes-dashboard
      annotations:
        kubernetes.io/ingress.class: "nginx"
    spec:
    // routing rules 
      rules:
      - host: dashboard.com
        http:
          paths:
          - path: /
            pathType: Exact  
            backend:
            // forward request to the internal service
              service:
                name: kubernetes-dashboard
                port: 
                  number: 80
    • internal service
      • node Port가 없음
      • 로드밸런서 대신에 디폴트 타입 : Cluster IP
    • internal service에서 kubernetes 클러스터에 접근할 때
      • 도메인 주소를 확인 및 검사
      • 도메인 이름을 entry point인 internal service 노드의 ip주소로 매핑

     

     

     

    • ingress controller
      • YAML을 통해서 클러스터 안에 Ingress component를 생성할 때 필요
      • ingress rules 검사 수행
      • redirection을 관리
      • 클러스터에 대한 entry point
      • 많은 third-party implementation
      • ex) k8s nginx ingress controller
    • 클러스터가 운영되는 환경
      • cloud service provider
        • ex) AWS, Google Cloud, Linode
        • k8s의 솔루션 밖에 존재
        • 원하는 구성을 다양하게 할 수 있음
        • 가상화된 로드밸런서를 가짐 (별도이 로드밸런서 주입 필요 X)
      • Bare Metal
        • 몇개의 entry point를 구성해야함
        • 클러스터 내부 혹은 바깥에 서버가 분리됨
        • ex) proxy server
          • 분리된 서버로 public Ip 주소와 열린 posrts를 가짐
          • 클러스터로 가능 entry point
          • 요청이 proxy server로 전달 → proxy server 가 Ingress Controller 로 전달 → Ingress Controller가 Ingress 규칙 체크 → service로 전달

     

     

     

    • Minikube에서 Ingress Controller 동작 확인하기
        1. minikube에 Ingress Controller 설치하기
        • $ minikube addons enable ingress
        • 자동으로 Ingress Controller가 포함된 K8s Nginx를 시작
        • $ kubectl get pod -n kube-system 명령어로 컨트롤러 실행 확인 가능
        1. Ingress rule를 생성 및 적용
        • 호스팅을 이용해서 쿠버네티스 대시보드에 접근하는 것을 가능하게 함
        • dashboard.com으로 요청 → internal 또는 public service인 kubernetes-dashboard로 80번 포트로 요청을 넘김
        • Ingress rule 적용 → Address 할당됨
          • $ kubectl apply -f [YAML 파일]
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: dashboard-ingress
      namespace: kubernetes-dashboard
      annotations:
        kubernetes.io/ingress.class: "nginx"
    spec:
      rules:
      - host: dashboard.com
        http:
          paths:
          - path: /
            pathType: Exact  
            backend:
              service:
                name: kubernetes-dashboard
                port: 
                  number: 80

     

     

     

    • Ingress Default Backend
      • $ kubectl describe ingress [ingress] -n [dashboard]
        • Default Backend 확인 가능
        • 없는 페이지 검색시 Default Backend가 작용하여 의미있는 메세지를 보여주기도 함

     

     

     

     

    • 하나의 호스트에 여러 path를 이용하는 방법
      • ex) Google은 하나의 도메인에 여러 서비스를 가짐

     

     

     

    • 여러 서브 도메인이나 도메인을 갖는 방법

     

     

     

     

    • TLS certificate 구성하기
      • key는 tls.crt 와 tls.key로 구성
      • 값은 파일 경로나 위치가 아닌 file contents로 구성
      • 시크릿 component는 Ingress와 같은 네임 스페이스에 위치 해야함

     

     

     

     

     

    3) configMap 와 secret

    • 환경변수로서 사용하거나 properties 파일 용도로 사용
      • ex) 데이터 베이스 URL은 보통 생성된 어플리케이션 안에 위치하여 rebuild 시에 이를 repo에 푸시하고 다시 pod에 가져오는 방식

     

    - configMap

    • 어플리케이션의 external configuration
      • pod에 연결되어 있으면서 데이터를 받기 위한 용도로 사용됨
      • 따라서 매번 새로운 이미지를 생성하거나 할 필요가 없음
      • ex) database, url 설정 등
    • 컨테이너 구성 정보를 한곳에 모아서 관리
    • 그러나 보안상 credential은 configMap에 넣어선 안된다
    • configMap의 일부분을 적용하기도 가능

    • configMap의 볼륨으로 적용하기도 가능

     

     

     

     

    - secret

    • configMap과 같지만 secret 데이터를 보관하는데 사용됨
      • 컨테이너가 사용하는 password, auth token, ssh key와 같은 중요한 정보를 저장하고 민감한 구성정보를 base64로 인코딩해서 한 곳에 모아서 관리
      • Available Commands 에 따라 들어가는 옵션이 달라짐
    • credentials를 plain text 타입이 아닌 base 64 encoded 타입으로 저장
    • credentials, password, certificate와 같은 비밀 정보를 담음
    • 기본적으로 빌트인 보안 메카니즘은 실행되지 않으므로 배포 이전에 생성되어야 함
    • 데이터 전달 방법

    • ---- 1) Command-line Argument 
    • ---- 2) Environment Variable 

    • ---- 3) Volume Mount 

    • 데이터 용량 제한
      • secret etcd에 암호화 하지 않은 텍스트로 저장되므로 secret value가 커지면 메모리 용량을 많이 사용하게 됨
      • secret의 최대 크기는 1MB

     

     

     

     

     

     

    4) volumes

    • 데이터 저장소
      • 데이터베이스 컨테이너나 pod이 재실행 되는 경우에도 데이터를 일관성이고 신뢰성있게 보관
    • 저장소를 쿠버네티스 클러스터의 pod이 아닌 local machine 또는 remote(k8s 클러스터 바깥에)에 위치
      • 데이터를 영구히 저장 가능
      • local인지 remote 저장소인지에 관계없이 외부 하드 드라이브로서 k8s 클러스터에 연결되어 k8s는 데이터의 영속성을 관리하지 않아도 됨
      • 단 적절한 하드웨어에 데이터가 보관되는지 확인해야 함
    • 쿠버네티스의 pod이 죽거나 중단된다면 ?
      • 미리 여러개의 노드를 통해 모든 것을 복사 해놓음
        • 프로덕션 모드에서도 pod을 재실행하거나 새로운 컨테이너를 짓는 동안 시간이 걸려 서비스가 중단되는 것을 방지
        • 복사본은 같은 서비스에 연결되어있음
    • pod 의 blueprint 를 정의하여 얼마나 많은 pod이 관리되고 운영될 지 결정
    • 쿠버네티스에서 볼륨을 이용한 데이터 영속화
    • 저장소 요구사항
        1. 저장소는 pod 라이프사이클에 의존적이면 안됨
        1. 저장소는 모든 노드에 대해 사용 가능해야함
        • 어떤 pod이 중단될지 모르기 때문에 모든 pod이 회복 가능하도록
        1. 클러스터가 중단되어도 저장소는 영향받지 않아야 함

     

     

     

     

     

    1) Persistent Volume(PV)

    • 클러스터 리소스 (마치 CPU RAM처럼)
    • YAML파일에 의해 생성
      • kind : PersistentVolume
      • spec: 얼마나 큰 저장소인가 (물리 저장소처럼), 어떤 저장소인가 정의
    • 쿠버네티스는 실제 저장소에 대해서는 관여 X
      • 어떤 타입의 저장소를 사용할 건지 생성하고 관리하는 것은 사용자의 몫
    • 네임 스페이스화 되어있지 않음
    • Local, Remote 볼륨 타입
      • 단 Local 볼륨타입의 경우 저장소 요구사항 2, 3 번을 위반함
      • 따라서 항상 Remote 볼륨 타입을 사용
    • 누구에 의해 만들어지는가?
      • k8s admin이 클러스터와 리소스를 관리
      • k8s user가 클러스터에 앱을 배포
      • admin에 의해 저장소가 공급되면 이 저장소 backend에 의해 PersistentVolume이 생성됨

     

     

     

    2) Persistent Volume Claim(PVC)

    • 애플리케이션이 PV를 요구해야 함

    • claim은 다음과 같은 정보를 가짐

    • Volume 추상화 과정 (생성과정)
      • 1) pod이 PVC에게 볼륨을 요구
      • 2) claim이 클러스터에서 볼륨을 찾음
        • 단, 클레임은 반드시 같은 네임스페이스에 존재해야 함
      • 3) 볼륨이 실제 저장소 backend를 가지고 있음
      • 4) 볼륨이 컨테이너에 마운트 됨
      • 5) 볼륨이 pod에 마운트 됨
      • 6) 컨테이너는 이를 이용해 읽고 쓰기 작업 수행 가능
      • 7) 만약 pod이 중단되어도 같은 저장소를 공유하게 되므로 유지가 가능해짐

    • volume에 많은 추상화가 존재하는 이유?
      • 관리자는 볼륨을 배정 → PV
      • 사용자는 볼륨을 생성해달라고 claim → PVC
        • 사용자는 실제 저장소가 어디에 위치하는지 알 필요가 없어짐
        • 사용자는 실제 저장소의 셋업과정을 알 필요가 없음
        • 즉, 사용자는 앱을 배포하는 것에만 집중할 수 있게 됨
    • ConfigMap 과 Secret
      • 둘다 local 저장소
      • PV 나 PVC에의해 생성되지 않음
      • 쿠버네티스에 의해 관리됨
      • 사용
        • ConfigMap 또는 Secret 컴포넌트를 생성
        • pod이나 container에 마운트

     

     

     

     

    3) Storage Class

    • 과정
      • 관리자가 PV 동적으로 배정
      • pod이 PVC를 이용해 PV를 요구 → 자동 생성
      • PVC가 Storage Class에게 저장소를 요구
      • SC가 claim 요구에 만족하는 PV를 생성

     

     

Designed by Tistory.