Search
Duplicate
📒

[Kubernetes Infra] 03-5. Ingress - Treefik, Nginx

상태
완료
수업
Kubernetes Infra
주제
4 more properties
참고

Ingress

NOTE
Ingress는 외부로부터의 요청에 대해 TLS 설정 관리 및 라우팅 관리를 하는 리소스를 의미한다!
Ingress를 사용하지 않는경우 (각 URL의 보안이나 설정을 따로 해줘야함)
NodePort 또는 LoadBalancer 타입의 서비스를 사용해도 위의 기능을 구현할수는 있다. 그러면 왜 Ingress를 사용하는가?
각 서비스별로 URL에 따로 접근해야하며 설정을 제각각 해줘야한다. (NodePort)
각 도메인 공통 설정을 해줄 수 없다. (LoadBalancer)
Ingress를 사용하는 경우 ( 각각의 URL이 아닌, 하나의 URL만 존재하며 내부 Path로 구분되어 처리된다.)
LoadBalancer의 경우, 포트번호 찾아가는 반면 Ingress는 도메인에 붙는 /path로 찾아간다.
Ingress Controller는 규칙들을 실제로 구현하는 컴포넌트이며 대표적으로 Nginx, HAProxy가 있다. Ingress는 다음과 같은 기능을 제공한다.
1.
트래픽 로드밸런싱
2.
서비스에 외부 URL을 제공한다. (/apple, /apple/red와 같이 특정 경로에 대한 라우팅)
3.
SSL 인증서 처리
4.
도메인 기반 가상 호스팅을 제공한다.

인그레스 사용예시

NOTE
Ingress를 사용하기 위해서는 다음의 순서를 따라야 한다.
kubectl create ingress [이름] \ -n ing-internal \ --class=default \ # ingress 리소스(ex nginx, alb, default) --rule="/hello=hello:5678"
Bash
복사
명령형 방식
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ping spec: rules: - http: paths: - path: /hello # 라우팅 규칙 pathType: Prefix # Prefix(/hello/* 의미), Exact(/hello 의미) .. backend: service: # 서비스 설정 name: hello port: number: 5678
YAML
복사
선언적 방식
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: humancat annotations: alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}]' alb.ingress.kubernetes.io/scheme: internet-facing alb.ingress.kubernetes.io/target-type: ip spec: ingressClassName: alb rules: - http: paths: - path: / backend: service: name: humancat-frontend-svc port: number: 80 pathType: Prefix
YAML
복사
AWS - ALB를 활용하는 Ingress
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: online-store-ingress spec: rules: - http: paths: - path: /shop # /shop은 frontend-service 80port로 간다. pathType: Prefix backend: service: name: frontend-service port: number: 80 - path: /api # /api는 backend-service 80port로 간다 pathType: Prefix backend: service: name: backend-service port: number: 80
YAML
복사
특정 경로 요청라우팅
# 프론트엔드 서비스 apiVersion: v1 kind: Service metadata: name: frontend-service spec: selector: app: frontend-app # 이 레이블은 프론트엔드 포드에 매치되어야 합니다. ports: - protocol: TCP port: 80 targetPort: 3000 # 프론트엔드 포드가 리스닝하는 포트 --- # 백엔드 서비스 apiVersion: v1 kind: Service metadata: name: backend-service spec: selector: app: backend-app # 이 레이블은 백엔드 포드에 매치되어야 합니다. ports: - protocol: TCP port: 80 targetPort: 8080 # 백엔드 포드가 리스닝하는 포트
YAML
복사
예시코드

Ingress Controller

NOTE
Ingress Controller는 Ingress 리소스에 정의된 라우팅 규칙을 실제로 실행하는 컴포넌트 이다!
인그레스 트래픽 흐름도
Ingress 리소스가 라우팅 규칙을 정의한다면, Ingress Controller는 그 규칙에 따라 들어오는 외부 요청을 적절한 서비스로 전달하는 역할을 해준다. Ingress Controller는 클러스터에 별도로 설치해야 하며 여러 종류가 있다.
Nginx Ingress Controller: 가장 널리 사용되며, Nginx를 기반으로 한다.
Traefik: 동적 라우팅 규칙과 HTTPS 인증서 갱신(Let’s Encrypt)등의 기능을 제공한다.
HAProxy Ingress: HAProxy를 기반으로 한다

Traefik - 설치

NOTE
helm repo add traefik https://helm.traefik.io/traefik helm repo update helm pull traefik/traefik --untar # 설치 k create ns traefik k ns traefik helm install traefik -f my-values.yaml .
Bash
복사
# 이중화 deployment: replicas: 2 # 관리자 페이지 접속 허가 ports: traefik: expose: true # 같은 노드에 Traefik 파드가 추가되지 않도록 설정 affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app.kubernetes.io/name operator: In values: - traefik # - {{ template "traefik.name" . }} topologyKey: kubernetes.io/hostname
YAML
복사
my-values.yaml
실제 화면
k ns default k apply -f cafe-svc-deploy.yml k run busybox --image=busybox:1.28 --restart=Never -- sleep 1d k exec -it busybox -- sh -c "wget -O- coffee-svc" k exec -it busybox -- sh -c "wget -O- water-svc"
Bash
복사

Traefik - CRD를 통한 인그레스 설정

NOTE
apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: coffee-ingressroute namespace: default spec: entryPoints: - web routes: - match: Host(`coffee.myweb.com`) kind: Rule services: - name: coffee-svc port: 80 --- apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: tea-ingressroutetls namespace: default spec: entryPoints: - websecure routes: - match: Host(`tea.myweb.com`) kind: Rule services: - name: tea-svc port: 80 tls: certResolver: myresolver --- apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: juice-ingressroutetls namespace: default spec: entryPoints: - websecure routes: - match: Host(`www.myweb.com`) && PathPrefix(`/juice`) kind: Rule services: - name: juice-svc port: 80 tls: certResolver: myresolver --- apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: water-ingressroutetls namespace: default spec: entryPoints: - websecure routes: - match: Host(`www.myweb.com`) && PathPrefix(`/water`) kind: Rule services: - name: water-svc port: 80 tls: certResolver: myresolver
YAML
복사
CRD인 IngressRoute를 통해서 더 세밀한 제어를 할 수 있다!
k apply -f cafe-crd-ingressroute.yml k get ingressroute curl http://coffee.myweb.com curl http://tea.myweb.com -k curl https://www.myweb.com/water -k curl https://www.myweb.com/juice -k
Bash
복사

Traefik - SSL/TLS 인증서 적용

NOTE
Traefik는 인그레스 사용자 정의 SSL/TLS 인증서 설치를 지원한다.
사용자는 인증서를 여러 웹 서버 설정에서 별도로 등록하지 않고 단일 Traefik 설정 파일에서 관리할 수 있습니다. 쿠버네티스는 애플리케이션과 네트워크에 관한 설정을 분리하여 배포할 수 있습니다.
# 자가 서명된 인증서를 생성합니다. 인증서는 365일 동안 유효하며, RSA 2048비트 키를 사용합니다. # 이 과정에서 생성된 키 파일은 myweb01.key 이며, 인증서 파일은 myweb.crt 입니다. sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout myweb01.key -out myweb.crt \ -subj "/CN=www.myweb.com" # 새로운 개인 키(myweb01.key)와 # CSR(Certificate Signing Request, myweb01.csr)을 생성합니다. sudo openssl req -new -newkey rsa:2048 -nodes -keyout myweb01.key -out myweb01.csr \ -subj "/CN=www.myweb.com" # CSR을 사용하여 자가 서명된 인증서(www.myweb.com.crt)를 생성합니다. # 인증서는 365일 동안 유효합니다. sudo openssl x509 -req -days 365 -signkey myweb01.key -in myweb01.csr -out www.myweb.com.crt # 생성된 개인 키 파일의 권한을 변경하여, 읽기 권한을 추가합니다. sudo chmod 644 myweb01.key # 쿠버네티스 시크릿을 생성합니다. 이 시크릿은 myweb-tls 라는 이름으로 저장되며, # 위에서 생성한 키 파일(myweb01.key)과 인증서 파일(www.myweb.com.crt)을 포함합니다. kubectl create secret tls myweb-tls --key myweb01.key --cert www.myweb.com.crt
Bash
복사
--- apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: juice-ingressroutetls namespace: default spec: entryPoints: - websecure routes: - match: Host(`www.myweb.com`) && PathPrefix(`/juice`) kind: Rule services: - name: juice-svc port: 80 tls: secretName: myweb-tls --- apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: water-ingressroutetls namespace: default spec: entryPoints: - websecure routes: - match: Host(`www.myweb.com`) && PathPrefix(`/water`) kind: Rule services: - name: water-svc port: 80 tls: secretName: myweb-tls
YAML
복사
설정성공