DevOps/K8S

[K8S] 인그레스와 관련 리소스

kyoulho 2024. 10. 8. 21:04

정리

  • 인그레스 컨트롤러의 서비스를 붙여 노드포트로 오픈
  • 인그레스는 인그레스 컨트롤러의 설정 정보
  • 인그레스 컨트롤러가 라우팅 규칙을 따라 서비스들로 라우팅


1. 인그레스

인그레스(Ingress)는 Kubernetes에서 클러스터 외부와 내부 서비스를 연결하는 설정이다. 이는 사용자가 클러스터 내부의 서비스에 접근할 수 있도록 HTTP 요청의 라우팅 규칙을 정의한다. 인그레스는 단순한 설정일 뿐 실제로 요청을 처리하는 것은 인그레스 컨트롤러이다.

1.1 인그레스의 주요 기능

  • HTTP 경로 기반 라우팅: 특정 URL 경로에 대한 요청을 내부 서비스로 라우팅 할 수 있다.
  • 도메인 기반 라우팅: 여러 도메인에 대해 각각의 요청을 다른 서비스로 분산할 수 있다.
  • TLS 종료: HTTPS 요청을 처리하고, TLS 인증서를 관리할 수 있다.
  • 리다이렉션 및 URL 재작성: 요청을 다른 URL로 리다이렉트하거나 URL을 재작성할 수 있다.
  • 인증 및 권한 부여: 기본적인 인증 및 권한 부여 메커니즘을 통해 트래픽을 안전하게 보호할 수 있다.

1.2 인그레스 설정 예시

example-ingress는 example.com의 요청을 my-service로 전달하는 인그레스 설정이다.

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

 

2. 인그레스 클래스

인그레스 클래스(IngressClass)는 Kubernetes에서 다양한 인그레스 컨트롤러를 구분하는 역할을 한다. 여러 인그레스 컨트롤러가 존재할 수 있으며, 인그레스 클래스는 특정 인그레스 리소스가 어떤 인그레스 컨트롤러에 의해 처리될지를 정의한다.

인그레스 클래스를 사용하면 클러스터 내에서 여러 인그레스 컨트롤러를 동시에 운영할 수 있으며, 특정 트래픽에 대해 적합한 컨트롤러를 선택할 수 있어 유연한 관리가 가능하다.

2.1 인그레스 클래스 정의 예시

여기서 controller 필드는 이 인그레스 클래스가 사용하는 인그레스 컨트롤러의 식별자를 나타낸다.

apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  name: example-ingress-class
spec:
  controller: example.com/ingress-controller

 


3. 인그레스 컨트롤러

인그레스 컨트롤러(Ingress Controller)는 인그레스 리소스를 실제로 처리하고 클러스터의 외부 트래픽을 내부 서비스로 라우팅 하는 구성 요소이다. 일반적으로 디플로이먼트(Deployment) 형태로 배포되며, 요청을 처리하기 위해 여러 인그레스 설정을 읽고 적용한다.

3.1 인그레스 컨트롤러 종류

  • NGINX 인그레스 컨트롤러: 가장 많이 사용되며, 다양한 설정과 기능을 제공한다. 클러스터 외부에서 수신한 요청을 NGINX가 처리하여 인그레스 리소스에 정의된 대로 내부 서비스로 라우팅 한다.
  • Traefik: 동적 라우팅과 서비스 발견 기능을 제공하며, 다양한 설정을 자동으로 적용할 수 있다.
  • HAProxy: 로드 밸런싱 및 다양한 프로토콜을 지원하는 고성능 인그레스 컨트롤러이다.
  • Contour: Envoy를 기반으로 하며, 고급 라우팅 기능과 보안 설정을 제공한다.

3.2 NGINX 인그레스 컨트롤러 설치

NGINX 인그레스 컨트롤러를 설치하려면 다음 명령어를 실행한다:

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/cloud/deploy.yaml

이 명령어는 NGINX 인그레스 컨트롤러를 클러스터에 배포하고, 기본 설정으로 트래픽을 처리할 준비를 한다.


4. 인그레스 리소스에 대한 권한 설정 (RBAC)

인그레스 리소스를 효과적으로 관리하고 보안을 유지하기 위해서는 적절한 권한 설정이 필요하다. Kubernetes에서는 RBAC(Role-Based Access Control)을 통해 리소스에 대한 접근 권한을 관리할 수 있다. 인그레스와 인그레스 컨트롤러는 특정 권한을 필요로 하며, 이를 적절히 설정하지 않으면 인그레스가 제대로 동작하지 않을 수 있다.

4.1 RBAC 개요

RBAC는 Kubernetes에서 리소스에 대한 접근 권한을 정의하고 관리하는 메커니즘이다. RBAC는 다음과 같은 구성 요소로 이루어져 있다:

  • Role: 특정 네임스페이스 내에서 리소스에 대한 권한을 정의한다.
  • ClusterRole: 클러스터 전체에서 리소스에 대한 권한을 정의한다.
  • RoleBinding: Role 또는 ClusterRole을 특정 사용자, 그룹, 또는 서비스 어카운트에 바인딩한다.
  • ClusterRoleBinding: ClusterRole을 클러스터 전체에 특정 사용자, 그룹, 또는 서비스 어카운트에 바인딩한다.

4.2 인그레스 컨트롤러를 위한 RBAC 설정

인그레스 컨트롤러는 인그레스 리소스를 감시하고, 이를 기반으로 트래픽을 라우팅 하기 위해 Kubernetes API에 접근해야 한다. 이를 위해 인그레스 컨트롤러에는 적절한 권한이 부여되어야 한다. 일반적으로 인그레스 컨트롤러는 서비스 어카운트를 사용하며, 해당 서비스 어카운트에 필요한 권한을 부여하는 방식으로 RBAC 설정을 구성한다.

4.3 RBAC 설정 예제

다음은 NGINX 인그레스 컨트롤러를 위한 RBAC 설정 예제이다. 이 예제는 ClusterRole, ClusterRoleBinding, Role, RoleBinding을 포함하여 인그레스 컨트롤러가 필요한 권한을 얻도록 구성한다.

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

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: nginx-ingress-clusterrole
rules:
  - apiGroups:
      - ""
    resources:
      - configmaps
      - endpoints
      - nodes
      - pods
      - secrets
    verbs:
      - list
      - watch
  - apiGroups:
      - ""
    resources:
      - services
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - networking.k8s.io
    resources:
      - ingresses
      - ingressclasses
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - networking.k8s.io
    resources:
      - ingressclasses
    verbs:
      - get
      - list
      - watch

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: nginx-ingress-clusterrole-nisa-binding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: nginx-ingress-clusterrole
subjects:
  - kind: ServiceAccount
    name: nginx-ingress-serviceaccount
    namespace: ingress-nginx

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-ingress-controller
  namespace: ingress-nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-ingress
  template:
    metadata:
      labels:
        app: nginx-ingress
    spec:
      serviceAccountName: nginx-ingress-serviceaccount
      containers:
        - name: nginx-ingress-controller
          image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.26.1
          args:
            - /nginx-ingress-controller
            - --configmap=$(POD_NAMESPACE)/nginx-configuration
            - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
            - --udp-services-configmap=$(POD_NAMESPACE)/udp-services
          env:
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
          ports:
            - name: http
              containerPort: 80
            - name: https
              containerPort: 443

위의 예제에서는 다음과 같은 구성을 포함하고 있다:

  1. ServiceAccount: nginx-ingress-serviceaccount는 인그레스 컨트롤러가 사용할 서비스 어카운트이다.
  2. ClusterRole: nginx-ingress-clusterrole은 인그레스 컨트롤러가 접근할 수 있는 리소스와 수행할 수 있는 작업을 정의한다.
  3. ClusterRoleBinding: nginx-ingress-clusterrole-nisa-binding은 ClusterRole을 서비스 어카운트에 바인딩한다.
  4. Deployment: 인그레스 컨트롤러의 디플로이먼트를 정의하며, 해당 디플로이먼트는 앞서 정의한 서비스 어카운트를 사용한다.

이 설정을 적용하려면 다음 명령어를 실행한다:

kubectl apply -f rbac-config.yaml

rbac-config.yaml 파일에 위의 내용을 저장한 후 실행하면, 인그레스 컨트롤러에 필요한 권한이 부여된다.


5. 인그레스 리소스 생성

인그레스 리소스를 생성하기 위해서는 아래와 같은 YAML 파일을 사용한다. 이 파일은 인그레스 리소스의 구성을 정의하며, 다양한 설정을 포함할 수 있다.

5.1 인그레스 리소스 YAML 예제

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /service1
        pathType: Prefix
        backend:
          service:
            name: service1
            port:
              number: 80
      - path: /service2
        pathType: Prefix
        backend:
          service:
            name: service2
            port:
              number: 80

위 예제는 example.com 도메인에 대해 /service1과 /service2 경로로 들어오는 요청을 각각 service1과 service2로 라우팅 하는 설정이다.

5.2 인그레스 리소스의 동작 원리

  1. 사용자가 브라우저에서 example.com/service1 URL로 요청을 보낸다.
  2. 인그레스 컨트롤러(NGINX 등)가 요청을 수신하고, 인그레스 리소스에 정의된 규칙을 참조하여 라우팅을 결정한다.
  3. 요청은 정의된 서비스로 전달된다.


6. 인그레스 보안

인그레스는 HTTPS 요청을 처리하고 TLS를 사용하여 보안을 강화할 수 있다.

6.1 TLS 설정 예시

spec:
  tls:
  - hosts:
    - example.com
    secretName: example-tls

secretName은 TLS 인증서를 포함하는 Kubernetes 시크릿의 이름이다. TLS 인증서는 다음 명령어로 생성할 수 있다:

kubectl create secret tls example-tls --cert=path/to/tls.crt --key=path/to/tls.key

6.2 인증서 자동 갱신

Let’s Encrypt와 같은 서비스를 사용하면 인증서를 자동으로 갱신할 수 있다. Cert-Manager와 같은 도구를 사용하면 이 과정을 자동화할 수 있다. Cert-Manager는 Kubernetes 네이티브 인증서 관리 도구로, 자동으로 인증서를 발급하고 갱신해 준다.

# Cert-Manager 설치
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.10.0/cert-manager.yaml

설치 후, ClusterIssuer 또는 Issuer 리소스를 정의하여 Let’s Encrypt와 연동할 수 있다.


7. 고급 기능

인그레스는 기본적인 라우팅 외에도 여러 고급 기능을 제공한다.

7.1 리다이렉션

HTTP 요청을 HTTPS로 리다이렉트 하려면 인그레스에 다음과 같은 어노테이션을 추가한다:

metadata:
  annotations:
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"

7.2 기본 인증

기본 인증을 통해 요청을 보호할 수 있다. 이를 위해 인증 정보를 포함하는 시크릿을 생성하고 인그레스에 추가한다.

# htpasswd 파일 생성:
htpasswd -c auth user1
# 시크릿 생성:
kubectl create secret generic basic-auth --from-file=auth
# 인그레스에 어노테이션 추가:
metadata:
  annotations:
    nginx.ingress.kubernetes.io/auth-type: "basic"
    nginx.ingress.kubernetes.io/auth-secret: "basic-auth"
    nginx.ingress.kubernetes.io/auth-realm: "Authentication Required"

7.3 Rate Limiting

트래픽을 제한하여 서비스의 안정성을 높일 수 있다. NGINX 인그레스 컨트롤러에서 다음과 같은 어노테이션을 사용하여 설정할 수 있다:

metadata:
  annotations:
    nginx.ingress.kubernetes.io/limit-connections: "10"
    nginx.ingress.kubernetes.io/limit-rpm: "60"

이 설정은 하나의 클라이언트가 동시에 열 수 있는 연결 수를 10으로 제한하고, 분당 요청 수를 60으로 제한한다.

728x90

'DevOps > K8S' 카테고리의 다른 글

[K8S] Metric Server  (0) 2024.10.10
[K8S] MetalLB  (1) 2024.10.10
[k8s] DNS  (1) 2024.09.02
[k8s] Volume  (0) 2024.09.02
[k8s] 클러스터의 주요 구성 요소와 문제 발생 시 영향  (2) 2024.08.29