3. K8s 실전 활용을 위한 10단계

김하영·2021년 11월 10일
0
post-thumbnail
post-custom-banner

'15단계로 배우는 도커와 쿠버네티스' 기반으로 내용 정리하였습니다.

  • 인그레스
    서비스와 연결하여 애플리케이션을 공개

인그레스(Ingress)는 K8s 클러스터 외부에서의 요청을 K8s 클러스터 내부의 애플리케이션에 연결하기 위한 API 오브젝트다.

디플로이먼트 관리하의 애플리케이션을 외부 공개용 URL과 매핑하여 인터넷에 공개하는 데 사용된다.

인그레스는 SSL/TSL 암호화나 세션 어피니티등의 기능을 갖추고 있어,
기존 웹 애플리케이션을 쿠버네티스화하는데 유용한 오브젝트다.

인그레스의 기능과 개요

인그레스의 대표적인 기능으로는 다음과 같은 것들이 있다.
이들 기능은 기존 웹 애플리케이션을 컨테이너화할 때 유용하다.

  • 공개 URL과 애플리케이션 매핑
  • 복수의 도메인 이름을 가지는 가상 호스트 기능
  • 클라이언트의 요청을 여러 파드에 분산
  • SSL/TLS 암호화 통신 HTTPS
  • 세션 어피니티

인그레스를 이용하면 기존의 로드 밸런서나 리버스 프록시를 대체할 수 있다.
공개용 URL의 경로에 애플리케이션을 매핑하여 로드밸런싱, HTTPS 통신 그리고 세션 어피니티를 사용할 수 있기 때문이다.

인그레스 컨트롤러는 다른 컨트롤러와 달리 마스터상의 kube-controller-manager의 일부로 실행되지 않는다.
다양한 인그레스 컨트롤러가 있는데 그 중에서도 NGINX 인그레스 컨트롤러가 대표적이다.
또한, 로드밸런서로 유명한 F5 BIG-IP의 컨트롤러도 있다.
NGINX 인그레스 컨트롤러는 오픈 소스이며, 위에 열거한 기능 이외에도 다양한 기능을 갖추고 있다.

인그레스를 사용하기 위해서는, K8s 클러스터에 인그레스 컨트롤러가 설정되어 있어야 한다.
퍼블릭 클라우드에서는 처음부터 인그레스 컨트롤러가 포함되어 있다.

인그레스를 사용할 때 주의점이 있다.
인그레스 컨트롤러의 구현에 따라 인터넷에 공인 IP를 취득하는 기능이 포함되지 않을 수 있다.
그래서 퍼블릭 클라우드의 K8s 관리 서비스는 클라우드의 기능과 인그레스를 연동하여 공인 IP 주소를 연결한다.

한편, 온프레미스에서 K8s 클러스터를 구축하는 경우에는 공인 IP 주소(이하, VIP)를 노드 간에 공유하는 기능을 추가해야 한다. 이 기능을 위해 kube-keepalived-vip가 깃헙에 공개되어 있다.

공개 URL과 애플리케이션의 매핑

인그레스를 사용하면 공개 URL의 경로 부분에 복수의 애플리케이션을 매핑할 수 있다.
예를 들어, http://abc.sample.com 이란 URL의 reservation과 order라는 경로에 각각의 전용 애플리케이션을
매핑할 수 있다.

그러면 사용자 입장에서는 하나의 URL이지만 내부적으로 애플리케이션이 적절히 분리되어 있어 느슨하게 결합된
애플리케이션의 집합체로 구현할 수 있다.

그러면 마이크로 서비스처럼 애플리케이션을 분할하고 느슨하게 연결함으로써 각 모듈의 변경에 의한 영향을
최소화 할 수 있고 개발 생산성에도 유리하다.

인그레스에는 가상 호스트라는 기능이 있다.

이는 하나의 공인 IP 주소를 공유하여 도메인 이름별로 전송되는 곳을 설정할 수 있다.
브라우저에서 http://xyz.sample.com 으로 접속하는 경우, DNS서버에서 반환되는 IP 주소는 동일하지만
서비스 api-svc#3에 의해 파드 api#3 에 전송된다.

이 기능은 판매 캠페인을 위해 일시적으로 도메인명을 취득하여 특설 사이트를 만드는 경우 등에 사용될 수 있다.

[ 가상 호스트와 서비스를 매핑하는 매니페스트 기술 ]

인그레스의 매니페스트에서는 메타데이터(metadata)와 어노테이션(annotation)이 중요한 역할을 수행한다.
어노테이션에 키와 값을 기재하여, 인그레스 컨트롤러에 명령을 전달한다고 볼 수 있다.

아래와 같이 두 가지 어노테이션이 사용되었다.

  • kubernetes.io/ingress.class:'nginx'
    여러 인그레스 컨트롤러가 K8s 클러스터에서 동작 중인 경우에는 이 어노테이션을 명시적으로 지정할 필요가 있다.
  • nginx.ingress.kubernetes.io/rewrite-target
    URL 경로를 바꾸도록 하는 어노테이션이다. 이 설정이 없으면 클라이언트로부터의 요청 경로를 파드에게 그대로 전송하여 File NotFound 에러로 연결될 수 있다.

[ 컨피그맵 ]

컨피그맵(ConfigMap)이란 설정 파일을 네임스페이스에 저장하는 오브젝트다.
파드는 컨피그맵을 디스크처럼 마운트할 수 있다.
예를 들면, 미들웨어의 설정 파일을 컨피그맵으로 지정하면 파드가 네임스페이스에서 읽어 들일 수 있다.


apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: hoya-com-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$1 # 트래픽을 리디렉션 해야하는 대상 URI
spec:
  tls:
  - secretName: hoya-com-secret
  rules:
  - host: www.hoya.com
    http:
      paths:
        - path: /
          backend:
            serviceName: web
            servicePort: 8080
        - path: /v2/*
          backend:
            serviceName: web2
            servicePort: 8080

[ 인그레스 API ]

  • apiVersion : extensions/v1beta1 설정
  • kind : ingress 설정
  • metadata.name : 인그레스 오브젝트 이름
  • metadata.annotations : 인그레스 컨트롤러 설정에 사용
  • spec

[ 인그레스의 사양 ]

  • rules : DNS명과 백엔드 서비스를 대응시키는 규칙 목록
    이 규칙에 맞지 않는 요청은 디폴트 백엔드라는 파드에 전송됨
  • tls

[ 인그레스 규칙 ]

  • host : FQDN(Fully Qualified Domain Name) 설정
  • http

[ URL 경로와 백엔드 서비스의 대응 배열 ]

  • paths : URL 의 경로와 백엔드 서비스를 대응시키는 목록을 기술

[ URL 경로와 백엔드 서비스의 대응 ]

  • path : URL 주소의 경로 부분을 기재
  • backend : 요청이 전달될 서비스와 포트번호 기재

[ 전송될 서비스의 이름과 포트번호 ]

  • serviceName : 서비스 이름
  • servicePort : 서비스의 포트번호

[ TLS 인증서와 도메인 ]

  • hosts : 도메인명 목록
  • secretName : 서버 인증서 시크릿의 이름.
    시크릿은 네임스페이스 내에 보안이 필요한 데이터를 보존하는 오브젝트로 컨테이너에서 볼륨으로 마운트 가능

인그레스 적용

  1. 애플리케이션 1 배포
    cd step13/url-mapping
    kubectl apply -f application1.yml

  2. 애플리케이션 2 배포
    kubectl apply -f application2.yml

  3. 애플리케이션 3 배포
    kubectl apply -f application3.yml

  4. 인그레스 설정
    kubectl apply -f ingress.yml

  5. 서비스와 디플로이먼트 확인
    kubectl get svc,deploy

  6. 인그레스 확인
    kubectl get ing

인그레스를 통해 각 도메인 마다 지정된 서비스를 호출할 수 있다.

  • abc.sample.com/api > application1
  • abc.sample.com/api2 > application2
  • abc.sample.com/api3 > application3

인그래스 SSL/TLS 암호화

인그레스에 SSL/TSL 암호화를 설정하면 브라우저로부터 HTTPS를 사용하여 접속할 수 있다.
그러면 파드에는 SSL/TSL 암호 설정을 하지 않아도 된다.

그러나 이 방법은 인그레스 컨트롤러에 부하가 집중되기 때문에, 정식 운영 서비스에 적용할 때는
성능의 병목 현상이 발생하지 않도록 주의해야 한다.

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: my-ingress
  namespace: test-namespace
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    kubernetes.io/ingress.class: "nginx"
spec:
  tls:
    - hosts:
        - test.storyparks.com
      secretName: tls-secret
  rules:
    - host: test.storyparks.com
      http:
        paths:
          - path: /test
            backend:
              serviceName: test-service
              servicePort: 80

모더니제이션 과제

  • 모더니 제이션

결함을 줄이고 성능을 높이고 효율성있게 요청을 처리하는 걸 의미하나??

기존의 웹 애플리케이션에서는 로드밸런서의 세션 어피니티를 사용하는 것이 일반적이었다.
여기서 세션이란, 사용자가 브라우저에서 행한 활동들을 기억하고 관리하는 매커니즘이다.

한편, 브라우저에서 사용하는 HTTP는 무상태 프로토콜이어서 서버와 클라이언트 간의 통신을 유지할 수 없다.
그래서 브라우저가 URL에 접속하고 화면이 표시되면 TCP/IP 통신이 종료된다.

따라서 애플리케이션은 브라우저를 식별하기 위한 쿠키를 HTTP 프로토콜의 헤더에 포함시켜서 전송한다.
그러나 서버가 여러 대 존재하고 그 앞에 로드밸런서를 두는 경우에는 또 다른 문제가 발생한다.

로드밸런서가 세션정보를 가지고 있지 않은 서버에 요청을 전달해 버리면, 올바른 처리를 수행할 수 없다.
(갑자기 로그아웃..?)

이 문제를 해결하는 위한 기능으로 [1]로드밸런서에는 세션 어피니티가 있다.
이 기능은 같은 브라우저에서의 요청을 언제나 동일한 서버의 프로세스에 전달한다.
즉, 세션 정보를 가지고 있는 애플리케이션 프로세스에 전송해 주는 것이다.

한편, 클라우드 네이티브 애플리케이션 개발의 바이블이라 할 수 있는 The Twelve Factor Apps에서는
세션 정보를 [2]외부 캐시에 보관하는 것을 추천한다.

하지만 다행히도 [3]인그레스에 세션 어피니티 기능이 있다.
이를 사용하면 기존 웹 애플리케이션의 코드 수정을 최소화하면서 쿠버네티스를 사용할 수 있다.

쿠버네티스를 도입할 때 기존 애플리케이션을 수정하거나 테스트하는데 발생하는 비용을 억제하기 위해서는
인그레스가 크게 도움이 될 것이다.

[ 서비스의 부하분산 기능 ]

서비스의 로드밸런싱 기능은 레이어 3에 해당하며 클라이언트 IP 주소에 따라 전송할 파드를 고정할 수 있다.
하지만 쿠키를 기반으로 세션 정보를 가지고 있는 파드에 전송하는 러에어 7의 기능은 없다.
( 로드밸런싱만 서비스 부하분산이 가능하다는 말인가...? )

세션 어피니티 기능 사용

  annotations:
    nginx.ingress.kubernetes.io/affinity: 'cookie'

kube-keepalived-vip 에 의한 VIP 획득과 HA 구성

NGINX 인그레스 컨트롤러는 Virtual IP를 노드 간 공유하는 기능을 가지고 있지 않다.
그래서 복수의 노드로 구성된 경우, keepalived를 사용해야 한다.

kube-keepalived-vip 파드는 VRRP( Virtual Router Redundancy Protocol)에 따라
멤버의 존재를 확인하고 멤버 중 한 노드에게 VIP를 부여한다.

이 VIP를 받은 노드가 요청을 받아서 인그레스 컨트롤러에 전달한다.

[ 고가용성 인그레스 환경 구축 ]

  1. 전용 네임스페이스 작성
  2. 인그레스 컨피그맵 작성
  3. 인그레스의 서비스 어카운트 작성과 RBAC 설정
  4. 인그레스의 디폴트 백엔드 배포
  5. 인그레스의 컨트롤러 배포
  6. kube-keepalived-vip의 컨피그맵 작성
  7. kube-keepalived-vip의 서비스 어카운트 작성과 RBAC 설정
  8. kube-keepalived-vip의 데몬셋 배포

마무리

  • 안그레스를 사용하기 위해서는 K8s 클러스터 상에 인그레스 컨트롤러가 동작하고 있어야 한다.
  • 인그레스는 URL의 경로와 애플리케이션을 매핑해주는 리버시 프록시다.
  • 서버 인증서를 등록하면 SSL/TLS 암호화, 즉 HTTPS를 통한 접속이 가능해진다.
  • 인그레스의 세션 어피니티 기능은 로드밸러서에 의존하는 레거시 웹 애플리케이션을 쿠버네티스에서
    돌릴 때 유용하게 사용될 수 있다.
  • NGINX 인그레스 컨트롤러와 kube-keepalived-vip를 사용하면 VIP를 공유하는 노드로 HA 구성이 가능하다.
profile
Back-end Developer
post-custom-banner

0개의 댓글