[구름 k8s] TIL 3-2-4

Peppie·2022년 10월 14일
0

1. 서비스

서비스 오브젝트

참고
Pod들을 통해 실행되고 있는 어플리케이션을 네트워크에 노출(expose) 시키는 가상의 컴포넌트

  • Pod : 구동중인 상태를 유지하기 위해 동원되는 일회성 자원, 언제든 다른 노드(워커 노드)로 옮겨지거나 삭제 가능
  • Pod는 생성될 때마다 새로운 내부 IP 부여받음; 클러스터 내/외부 통신 지속적 유지 어려움

서비스는 Pod가 외부와 통신 가능하도록 클러스터 내부에서 고정적인 IP를 갖도록 하는 역할

서비스는 Deployment나 Stateful set과 같은 어플리케이션을 구동하도록 구성된 여러 Pod들에게 단일 네트워크 진입점 부여 역할

서비스 정의하고 생성할 때는 sepc.ports 속성 아래에 연결하고자 하는 항목별로 2개씩의 포트 지정

  • targetPort
    • Pod의 어플리케이션 쪽에서 열려있는 포트
    • 서비스로 들어온 트래픽은 해당 Pod의 <클러스터 내부 IP>:<타겟 포트>로 넘어감
  • port
    • 서비스 쪽에서 해당 Pod를 향해 열려있는 포트

쿠버네티스 네트워크 구조

도커 네트워크 구조

도커는 브리지 타입의 네트워크 구조

  • docker 0 : 호스트 네트워크 네임스페이스 (디폴트 네트워크 네임스페이스)
  • vethxxx (Virtual Ethernet) : 컨테이너 네트워크 인터페이스

쿠버네티스 Pod 네트워킹 - 기본 네트워킹

  • 쿠버네티스 클러스터 상에서 Pod에 개별 IP주소 부여
  • 쿠버네티스는 Pod 단위로 컨테이너 관리, Pod에는 여러 개의 컨테이너 동작 가능 및 Pod에 부여된 IP 주소를 컨테이너가 공유
  • Pod가 생성되면 Pause container의 네트워크 네임스페이스를 갖게 되고, Pod 내의 컨테이너 간 127.0.0.1로 포트를 구분하여 통신 가능

하나의 노드 (워커 노드)의 Pod to Pod 통신

네트워크 인터페이스 (쿠버네티스 또는 CNI)를 통하여 Pod에 할당되어 있는 고유 IP로 통신

  • 쿠버네티스는 기본적으로 kubelet이라는 네트워크 플러그인 제공
    : kubelet은 크로스 노드 네트워킹이나 네트워크 정책결정 등의 네트워크 고급 기능 구현 X
  • CNI 스펙을 준수하는 네트워크 플러그인을 따로 사용

여러 노드 (워커 노드) 간의 Pod to Pod 통신

오버레이 네트워크 기능을 구현하기 위해 CNI를 설치하고 라우터를 경유하여 통신

Pod0 -> veth0 -> CNI -> eth0 -> 라우터 (VPC) -> eth1 -> CNI -> veth1 -> Pod1

서비스 유형

Cluster IP (default)

Pod들이 클러스터 내부의 다른 리소스들과 통신할 수 있도록 해주는 가상 클러스터 전용 IP,
클러스터 내부에서만 접근 가능

  • spec.selector에서 지정된 라벨로 여러 Pod들이 존재할 경우 서비스는 그 Pod들의 외부 요청 (request)을 전달할 엔드포인트 선택 후 트래픽 분재 (LoadBalancing)
  • 엔드포인트를 수동으로 직접 지정할 때는 Endpoints 객체를 이용하여 서비스 및 매핑
    주의) 엔드포인트를 명시할 IP는 loopback이면 안됨
apiVersion: v1
kind: Service
metadata:  
  name: my-internal-service
spec:
  selector:         # 서비스가 적용될 Pod 정보
    app: my-app
  type: ClusterIP   # 생략 가능
  ports:  
  - name: http
    port: 80        # 서비스를 노출하는 포트
    targetPort: 80  # Pod (어플리케이션)을 노출하는 포트
    protocol: TCP
apiVersion: v1
kind: Service
metadata:
  name: myapp-service
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376
---
apiVersion: v1
kind: Endpoints
metadata:
  name: myapp-service # 연결할 서비스와 동일한 name을 메타데이터로 입력
subsets:              # 해당 서비스로 가리킬 endpoint를 명시
  - addresses:
      - ip: 192.0.2.42
    ports:
      - port: 9376

NordPort

외부에서 노드 IP의 특정 포트( <노드 IP>:<노드 포트> )로 들어오는 요청을 감지하여 해당 포트와 연결된 Pod로 트래픽 전달

  • sepc.portsnodePort를 추가로 지정
    • nodePort : 외부에서 노드 안의 특정 서비스로 접근할 수 있도록 지정된 노드의 특정 포트,
      범위는 30000 ~ 32767, 미지정시 임의의 포트 부여
  • spec.selector에 해당하는 모든 Pod들에 NordPort에 의한 동일한 로드밸런싱 적용

apiVersion: v1
kind: Service
metadata: 
 name: my-nodeport-service
spec:
 selector:   
   app: my-app
 type: NodePort
 ports: 
 - name: http
   port: 80         # Service에 노출되는 Port
   targetPort: 80   # Pod(애플리케이션)을 노출하는 Port
   nodePort: 30036  # 외부 사용자가 애플리케이션에 접근하기 위한 Port
   protocol: TCP

LoadBalancer

별도 외부 LoadBalancer를 제공하는 클라우드 (AWS, GCP, Azure 등) 환경을 고려하여 해당 로드밸런서를 클러스터의 서비스로 프로비저닝할 대 사용

  • 서비스를 클라우드 제공자 측의 자체 로드밸런서로 노출, 필요 NordPort & 클러스터 IP는 자동생성
  • 프로비저닝된 로드밸런서 정보는 서비스의 status.loadBalancer 속성에 기재
apiVersion: v1
kind: Service
metadata:
  name: myapp-service
spec:
  type: LoadBalancer
  ports:
    - protocol: TCP
      port: 80            # 서비스를 노출하는 포트
      targetPort: 80        # 애플리케이션(파드)를 노출하는 포트
  clusterIP: 10.0.171.239    # 클러스터 IP
  selector:
    app: myapp
    type: frontend
status:
  loadBalancer:            # 프로비저닝된 로드 밸런서 정보
    ingress:
      - ip: 192.0.2.127
  • 외부 로드밸런서를 통해 들어온 트래픽이 서버 설정값을 따라 해당되는 Pod로 연결,
    트래픽이 어떻게 로드밸런싱 될지는 클라우드 제공자의 설정에 따라 다름
  • 로드밸런서 프로비저닝 지원 X 환경에서 이 유형은 NordPort와 동일 방식으로 동작

ExternalName

서비스에 selector 대신 name 직접 명시할 때 사용

  • spec.externalName 속성에 필요한 DNS 주소를 기입하면 클러스터의 DNS 서비스가 해당 주소에 대한 CNAME 레코드 반환
apiVersion: v1
kind: Service
metadata:
  name: myapp-service
  namespace: prod
spec:
  type: ExternalName
    externalName: my.database.example.com

CLI 명령어로 Pod에 서비스 적용하기

kubectl create service <서비스 유형>

  • kubectl run custom-nginx --image=nginx --port=8080 && kubectl expose pod custom-nginx
  • kubectl create service clusterip redis --tcp=6379:6379

kubectl expose pod

kubectl expose pod redis --port=6379 --name redis-service

외부 IP주소 노출로 클러스터 어플리케이션 접속 예제

https://kubernetes.io/ko/docs/tutorials/stateless-application/expose-external-ip-address/



서비스 오브젝트를 외부에서 클러스터 내로 진입할 때 항상 포트 번호를 지정해야 함

  • curl http://<외부 IP>:<포트>

2. Ingress

Ingress

쿠버네티스 클러스터 외부에서 내부로 들어오는 트래픽에 대해 어떻게 처리할지 정의하는 규칙

  • Ingress Object : 외부에서 쿠버네티스 클러스터에서 실행중인 Deployment와 서비스에 접근하기 위한 일종의 Gateway 같은 역할 담당

Service Object vs Ingress Object

  • 서비스 오브젝트를 이용하여 클러스터 외부와 연결하는 방식은 4계층 (전송 계층) 기반 사용
    -> 실제 어플리케이션 작성시 직접적 처리 적용해야
  • 인그레스 오브젝트를 이용하여 클러스터 외부와 연결하는 방식은 7계층 (어플리케이션 계층) 기반
    -> 어플리케이션 계층의 다양한 프로토콜 적용 가능

Ingress & Ingress Controller

Ingress

참고

YAML 파일을 통해 ingress (inbound) 규칙 정의

Ingress object를 생성하더라도 실질적인 동작 X

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-ingress
spec:
  backend:
    serviceName: other
    servicePort: 8080
  rules:
  - host: foo.mydomain.com
    http:
      paths:
      - backend:
          serviceName: foo
          servicePort: 8080
  - host: mydomain.com
    http:
      paths:
      - path: /bar/*
        backend:
          serviceName: bar
          servicePort: 8080

Ingress controller


Ingress에 의해 정해진 규칙에 따라 실제 외부 요청을 실질적으로 처리하는 특수 서버 컨테이너

kubectl을 통한 Ingress 배포 예제

https://guide.ncloud-docs.com/docs/k8s-k8sexamples-ingress

3. Amazon EKS

Amazon EKS (Elastic Kubernetes Service)

직접 쿠버네티스의 control plane과 node 구성 X, AWS 환경에서 쿠버네티스 클러스터 구성 가능한 완전 관리형 서비스

  • 여러 AWS 가용 영역에 걸쳐 쿠버네티스 control plane 실행 및 크기 조정으로 높은 가용성 보장

  • 하중에 따라 제어 영역 인스턴스 크기 자동 조정 및 비정상 제어 영역 인스턴스 감지/교체 및 자동화된 버전 업데이트 및 패치 제공

  • 여러 AWS 서비스와 통합되어 다음 어플리케이션(및 그 외)에 대한 확장성 & 보안 제공

    • 컨테이너 이미지에 대한 Amazon ECR
    • 로드 분산을 위한 Elastic Load Balancing
    • 인증용 IAM
    • 격리를 위한 Amazon VPC

EKS를 통한 쿠버네티스 클러스터 클라이언트 구성 및 클러스터 구성

Amazon EKS로 구성된 클러스터 제어용 호스트

AWS CLI 설치

설치 과정 참조

eksctl 설치

eksctl : Amazon EKS 클러스터 구성을 위한 CLI 명령
설치 과정 참조

kubectl 설치

설치 과정 참조

Amazon EKS를 이용한 클러스터 구성

eksctl 명령으로 EKS를 이용한 클러스터 구성

eksctl create cluster \
 --name k8s-demo \
 --region ap-northeast-2 \
 --with-oidc \
 --ssh-access \
 --ssh-public-key [awskey 이름] \
 --nodes 3 \
 --node-type t3.medium \
 --node-volume-size=20 \
 --managed

0개의 댓글