Ingress

zuckerfrei·2024년 1월 29일
0

Kubernetes

목록 보기
60/63

my-online-store 인터넷쇼핑몰 예시

우리 인터넷 쇼핑몰은 GCP 클라우드에 인프라를 구축한다.
옷을 판매하는 기능을 wear라는 서비스에서 처리하고, 비디오 스트리밍 기능을 video라는 서비스에서 처리한다고 가정한다.
사용자가 우리 서비스에 접속하기 위해 아래와 같은 작업이 필요하다.
wear서비스와 video서비스에 각각 GCP LB를 붙이고, 이 두 LB를 묶는 상위 LB를 추가로 생성하여 붙인다.
그래서 /apparel url로 들어오는 요청은 wear서비스로, /video url로 들어오는 요청은 video서비스로 리다이렉트 시킨다.

이 모든 것을 k8s 클러스터 내부에서 관리하고 프로비저닝 하며, 다른 애플리케이션 배포 파일과 함께 배포할 수 있다면 어떨까? 이때 Ingress가 등장한다.
ingress는 외부 사용자가 접속 가능한 단일 url로 경로 기반 라우팅기능을 사용하여 클러스터 내 여러 서비스에 접속할 수 있게 한다. (+ssl 포함)

즉, Ingress는 k8s 클러스터에 내장된 Layer 7 계층의 LB라고 보면 된다.
그러나 여전히 ingress도 외부에 서비스를 노출하려면 nodeport 또는 lb를 사용한다.


1. ingress controller

GCE, Nginx, Contour, HAProxy, Traefik, Istio 같이 여러 종류가 있지만, k8s가 지원하고 관리하는 GCE, Nginx로 설명한다.

ingress controller를 배포하려면 최소한 아래와 같은 객체들이 필요하다.


Deployment

ingress controller로써의 nginx는 조금 특이하게 배포된다.
manifest file을 보면 다른 부분은 큰 차이가 없지만, args 항목에 /nginx-ingress-controller라고 있다.
ingress controller로써 nginx가 배포되어야 한다면 이 부분이 반드시 존재해야한다.

# 예시
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ingress-nginx-controller
spec:
  selector:
    matchLabels:
      name: nginx-ingress
  template:
    metadata:
      labels:
        app.kubernetes.io/name: ingress-nginx
    spec:
      containers:
      - args:
        - /nginx-ingress-controller
        - --configmap=$(POD_NAMESPACE)/ingress-nginx-controller
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: LD_PRELOAD
          value: /usr/local/lib/libmimalloc.so
        image: registry.k8s.io/ingress-nginx/controller:v1.8.2@sha256:74834d3d25b336b62cabeb8bf7f1d788706e2cf1cfd64022de4137ade8881ff2
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
          name: http
          protocol: TCP
        - containerPort: 443
          name: https
          protocol: TCP
...

ConfigMap

그리고 nginx 설정 파일은 configMap 객체를 만들어 넘겨줘야 한다.
설정 파일을 수정할 필요는 없고 일단 이름만 넣어서 만들면 된다고 함

apiVersion: v1
kind: ConfigMap
metadata:
  name: ingress-nginx-controller

Service

그리고 ingress를 외부로 노출할 Service도 필요하다.
이 서비스는 nodeport 형식이며 위에서 생성한 deploy와 연결시킨다.

apiVersion: v1
kind: Service
metadata:
  labels:
  name: ingress-nginx-controller-admission
spec:
  ports:
  - name: https
    port: 443
    targetPort: 443
    protocol: TCP
  - name: http
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app.kubernetes.io/name: ingress-nginx
  type: NodePort
---

ServiceAccount

ingress가 클러스터 내에서 발생하는 변화를 감지하기 위해서 충분한 권한을 가진 Role, ClusterRoles, RoleBindings, SerivceAccount도 생성한다.

apiVersion: v1
kind: ServiceAccount
metadata:
  name: ingress-nginx

2. ingress resource

경로 기반으로 라우팅하는 규칙 생성하는 것
manifest file 생성 후 다른 k8s객체처럼 create 명령어로 생성한다.
네임스페이스 구분이 있으므로 주의해서 확인할 것

예시 1

1개의 규칙으로 2개의 경로를 라우팅하는 예시

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-wear-watch
spec:
  rules:
  - http:
      paths:
      - path: /wear
        pathType: Prefix
        backend:
          service:
            name: wear-service
            port:
              number: 80
      - path: /watch
        pathType: Prefix
        backend:
          service:
            name: watch-service
            port:
              number: 80

이렇게 생성된 ingress를 자세히 살펴보면 path항목에 /wear, /watch 2가지가 생성된 것을 확인

www.my-online-store.com/wear → wear 서비스
www.my-online-store.com/watch → watch 서비스
www.my-online-store.com/eat → path 존재하지 않으므로 Default backend 서비스로 이동


예시 2

2개의 규칙으로 각각 1개씩 라우팅하는 예시(서브도메인으로 구분)

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-wear-watch
spec:
  rules:
  - host: wear.my-online-store.com
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: wear-service
            port:
              number: 80
  - host: watch.my-online-store.com
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: watch-service
            port:
              number: 80

host 라는 필드가 추가되었음을 주의할 것
host 필드 없으면, all host (*)를 의미함

# 이렇게도 확인할 수 있음
controlplane ~ ✖ k get ingress -A
NAMESPACE        NAME                 CLASS    HOSTS   ADDRESS        PORTS   AGE
app-space        ingress-wear-watch   <none>   *       10.111.95.12   80      18m
critical-space   ingress-pay          <none>   *                      80      7s

www.wear.my-online-store.com → wear 서비스
www.watch.my-online-store.com → watch 서비스

강의에서는 구버전(왼쪽)으로 설명되었는데, 최신 버전은 오른쪽이라고 한다.


rewrite-target

ingress manifest file 중 rewrite-target 설정이 존재한다.

metadata:
    annotations:
      nginx.ingress.kubernetes.io/rewrite-target: /
...
spec:
    rules:
    - http:
        paths:
        - backend:
            service:
              name: pay-service
              port:
                number: 8282
          path: /pay
          pathType: Prefix

위와 같은 상황에서 사용자가 www.my-store.com/pay 로 접속하면, pay-service의 “/” 경로로 리다이렉트 된다.

이것은 rewrite-target 옵션 덕분인데 이 옵션이 현재 “/”로 설정되어 있어서 /pay로 접속하더라도, 목적지 서비스의 “/”로 이동하라고 경로를 덮어써주는? 것이다.
http://<ingress-service>:<ingress-port>/pay → http://<pay-service>:<port>/

만약 이 파일에서 rewrite-target 옵션이 존재하지 않았다면, www.my-store.com/pay 로 접속한 사용자는 서비스의 “/pay” 경로로 리다이렉트 될 것이다.
http://<ingress-service>:<ingress-port>/pay → http://<pay-service>:<port>/pay

profile
무설탕 음료를 좋아합니다

0개의 댓글