본문 바로가기
Framework and Tool/Kubernetes

Kubernetes - ingress

by ocwokocw 2022. 10. 30.

- 출처: Kubernetes in action

- 인그레스 리소스

인그레스(ingress)란 들어가거나 들어가는 행위, 들어갈 수단, 장소, 진입로라는 의미를 갖고 있다.
 
인그레스 리소스를 사용하면 외부로 서비스를 노출할 수 있다. 이미 외부에 서비스를 노출하기 위한 유형으로 노드포트와 그의 확장형인 로드 밸런서를 살펴보았다. 그렇다면 인그레스라는 리소스는 왜 필요할까?
 
로드 밸런서는 자신의 공용 IP를 가진 로드 밸런서가 필요하다. 반면 인그레스는 한 IP 주소로 수십개의 서비스에 접근이 가능하다. 또한 네트워크 스택의 애플리케이션 계층(HTTP)에서 작동 하므로 서비스가 할 수 없는 쿠키기반 세션 어피니티와 같은 기능을 제공할 수 있다.
 
인그레스 리소스를 사용하려면 클러스터에 인그레스 컨트롤러를 실행해야 한다. 예를 들어 구글 쿠버네티스 엔진의 경우 구글 클라우드 플랫폼의 고유한 HTTP 로드 밸런싱 기능으로 인그레스 기능을 제공하고 있다. 우리가 사용하는 minikube의 경우 인그레스를 애드온 형태로 제공하고 있다.
 
 
 
"minikube addons list" 명령어를 수행하면 목록이 나오는데 그중 ingress 항목을 확인할 수 있다. "minikube addons enable ingress"로 활성화 시켜준다.
 
 
 
애드온이 활성화되었다면 "kubectl get po --all-namespaces" 명령어를 통해 파드를 조회한다. ingress 관련 파드가 실행되는지 확인하자.
 
 

- 인그레스 리소스 생성과 접근

인그레스 컨트롤러가 작동중인것을 확인했다면 인그레스 리소스를 생성할 수 있다. "kubia-ingress.yaml" 파일을 작성한다.
 
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: kubia
spec:
  rules:
  - host: kubia.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: kubia-nodeport
            port:
              number: 80
 
책과는 좀 다른 부분이 있지만 공식문서(https://kubernetes.io/docs/concepts/services-networking/ingress/)를 참조하면 설정하지 못할 수준은 아니다. 위의 yaml 매니페스트 파일로 ingress를 생성하고 조회해보자.
 
 
 
원래 가이드에서는 인그레스의 ADDRESS 필드에서 알려주는 IP와  kubia.example.com를 /etc/hosts 파일에 등록하면 된다고 알려주고 있다. 하지만 minikube를 사용하는 경우 좀 다르게 해주어야 한다. 127.0.0.1 kubia.example.com 을 추가해준다.
 
 
 
그 후 minikube tunnel 을 수행해준다. 
 
 
 
여기서 터미널은 foreground로 실행한 채 새로운 터미널을 오픈하여 curl 을 요청한다.
 
 

- 인그레스 동작방식

가장 먼저 kubia.example.com curl 요청을 하면 DNS 조회를 하게 되고, DNS 서버가 해당 IP를 반환한다.(로컬의 경우 hosts 파일에서 설정한 IP가 반환된다.)
 
그 후 헤더에 도메인을 지정하여 HTTP 요청을 인그레스 컨트롤러로 전송하게 된다. 컨트롤러는 헤더정보를 살펴본 후 접근하려는 서비스를 결정 하여 엔드포인트 오브젝트로부터 파드 IP를 조회하고 해당 파드로 요청을 전달한다.
 
분명히 할점은 요청이 전달되는 경로가 인그레스 -> 서비스 -> 파드가 아니라는점이다. 우선 인그레스 -> 서비스 -> 엔드포인트 오브젝트로 파드 IP를 조회하고, 인그레스 컨트롤러가 파드로 요청을 전달한다.
 

- 여러 서비스 호출

인그레스 yaml 파일에서 spec의 rules는 배열이므로 여러 호스트 경로를 여러 서비스에 맵핑할 수 있다.
 
우선 같은 호스트에서 다른 경로의 요청을 다른 서비스로 맵핑하는 경우를 살펴보자.
 
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: kubia
  annotations:
spec:
  rules:
  - host: kubia.example.com
    http:
      paths:
      - pathType: Prefix
        path: /kubia
        backend:
          service:
            name: kubia-nodeport
            port:
              number: 80
      - pathType: Prefix
        path: /bar
        backend:
          service:
            name: bar
            port:
              number: 80
 
paths 하위로 여러 path 들을 기입해주면 되므로 별로 어려운점은 없을것이다. 위의 예제와 같이 경로에 의한 맵핑이 아닌 host에 의한 서비스 맵핑을 설정할수도 있다.
 
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: kubia
  annotations:
spec:
  rules:
  - host: kubia.example.com
    http:
      paths:
      - pathType: Prefix
        path: /kubia
        backend:
          service:
            name: kubia-nodeport
            port:
              number: 80
  - host: foo.example.com
    http:
      paths:
        - pathType: Prefix
          path: /foo
          backend:
            service:
              name: foo
              port:
                number: 80
 

- TLS 구성

TLS를 지원하도록 인그레스를 구성할 수 있다.
 
클라이언트가 인그레스 컨트롤러에 TLS 연결을 하면 컨트롤러는 TLS 연결을 종료한다. 클라이언트에서 컨트롤러까지는 암호화가 되어야 하지만 컨트롤러이후 백엔드는 암호화가 되지 않는다. 인그레스가 TLS와 관련된 모든것을 처리하고 파드는 HTTP만 처리하면 된다.
 
이를 위해 인증서와 개인키를 인그레스에 첨부해야 한다. 인증서, 개인키는 시크릿 시소스에 저장하며 인그레스 매니페스트에서 참조한다. 지금은 시크릿의 세부사항 보다는 TLS를 구성하는 방법에 집중하도록 하자.
 
일단 openssl 을 통해 개인키와 인증서를 생성한다.
 
 
 
생성했다면 두 파일로 시크릿을 만든다.
 
 
 
개인키와 인증서가 tls-secret 이라는 시크릿에 저장된다. 기존 yaml 파일에 tls 정보를 추가해보자.
 
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: kubia
  annotations:
spec:
  tls:
  - hosts:
      - kubia.example.com
    secretName: tls-secret
  rules:
  - host: kubia.example.com
    http:
      paths:
      - pathType: Prefix
        path: /kubia
        backend:
          service:
            name: kubia-nodeport
            port:
              number: 80
 
 
 
우리가 생성한 인증서는 개인 인증서이기 때문에 curl 테스트시 k 옵션을 반드시 설정해야 한다.
 
 

'Framework and Tool > Kubernetes' 카테고리의 다른 글

Kubernetes - Volume  (0) 2022.11.12
Kubernetes - readness probe, headless service  (0) 2022.10.30
Kubernetes - External service, Service export  (0) 2022.10.24
Kubernetes - Service intro  (0) 2022.10.21
Kubernetes - job and cron job  (0) 2022.10.21

댓글