K8S - Ingress

반영환·2023년 8월 27일
0

k8s

목록 보기
7/14
post-thumbnail

K8S Ingress

K8S의 Ingress Resource는 외부에서 클러스터 내부로 들어오는 Ingress 트래픽을 어떻게 처리할지 정의한다.

GateWay 역할과 유사하다.

Ingress 를 사용하지 않을 때 외부 트래픽에 클러스터를 노출시킬 방법은 NodePort, LB등이 있지만 이런 것들은 일반적으로 Layer4 (TCP, UDP) 에서의 요청을 처리하며 한계가 존재한다.

Ingress는 Layer7의 요청을 처리할 수 있다.

외부로부터 들어오는 요청에 대한 로드 밸런싱, TLS/SSL 인증서 처리, 특정 HTTP 경로의 라우팅등을 Ingress를 통해 자세하게 정의할 수있다.

Ingress를 통해 위와 같은 요구사항을 정의하고, 이를 Ingress Controlle라고 부르는 특별한 웹서버에 적용해 추상화된 단계에서의 서비스 처리 로직을 정의할 수 있다.

Ingress VS Ingress Controller

Ingress 는 외부 요청을 어떻게 처리할 것인지를 정의하는 집합이고, Ingress Controller는 실제 해당 요청을 처리하는 서버이다.

Nginx를 이용한 LB

vi /etc/yum.repos.d/nginx.repo

[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1
#ubuntu
sudo install nginx 

#centos
yum install -y nginx

vi /etc/nginx/conf.d/default.conf

# Load Balancing
upstream backend {
   server 10.0.0.156:30123 max_fails=3 fail_timeout=10s;
   server 10.0.0.154:30123 max_fails=3 fail_timeout=10s;
}
server {
    listen 80;
    server_name 18.117.187.145; # 서비스할 도메인으로 변경
    # 기본값으로 설정
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $http_host;
    location / {
      proxy_pass http://backend;        
    }
}

요청이 / 로 들어오면 upstream backend로 정의한 두개의 서버로 트래픽을 분산시킨다.

Ingress Controller

구성

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.6.4/deploy/static/provider/baremetal/deploy.yaml

# 생성된 서비스와 POD 정보 확인
kubectl get pod -n ingress-nginx

# Ingress Controller 버전 확인
kubectl exec -n ingress-nginx ingress-nginx-controller- 84cb46fccd-r2lqt -- /nginx-ingress-controller --version

# Ingress controller가 실행하고 있는 서비스 포트 정보 확인
kubectl get svc -n ingress-nginx

Switch Namespace

# kubeconfig 파일을 사용하고 있는 병합된 구성 정보를 확인한다. 
kubectl config current-context

# kubeconfig 파일에 ingress-nginx 네임스페이스를 영구적으로 저장한다.
# ingress-nginx를 실행을 위한 context를 추가한다.
kubectl config set-context ingress-nginx --namespace=ingress- nginx --cluster=kubernetes --user=kubernetes-admin

# 앞서 생성한 ingress context가 잘 저장 되어있는지 확인한다. 
kubectl config view

# namespace를 default 대신 ingress-nginx로 변경한다
kubectl config use-context ingress-nginx

kubectl config current-context

Ingress Resource

Ingress Controller가 클러스터에서 실행중이라면 리소스를 생성하자.

특정 URL로 들어온 요청을 지정한 Node host 인 k8s003으로 보내고 싶을 때

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
 name: ing-svc
spec:
 rules:
 - host: k8s003
   http: 
     paths:
     - path: /
       backend:
         serviceName: app-service
         servicePort: 8080

들어온 요청을 특정 Node에 국한되지 않고 트래픽을 라우팅하고 싶을 때

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ing-svc
spec:
  defaultBackend: # 정의한 url이 아닌 다른 url은 모두 여기로 모임.
    service:
      name: default-backend-service # 디폴트 백엔드 서비스 이름으로 수정
      port:
        number: 8080
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: app-service-a
            port:
              number: 8080
      - path: /dev
        pathType: Prefix
        backend:
          service:
            name: app-service-b
            port:
              number: 8080

EKS 환경

EKS 환경에서는 단순 Ingress Controller를 설치한다고 되는 것이 아니라 public vpc에 Ingress Controller를 배포해야 외부로 서비스를 노출시킬 수 있다.

따라서 Public VPC를 사용할 Node에는 public 이라는 라벨을 붙이고, 노드 셀렉터를 이용해 배포한다.

ingress-controller

apiVersion: apps/v1
kind: Deployment
metadata:
  name: ingress-nginx-controller
  namespace: kube-system # 네임스페이스를 구분해서 사용하자.
spec:
  replicas: 1
  selector:
    matchLabels:
      app: ingress-nginx
  template:
    metadata:
      labels:
        app: ingress-nginx
    spec:
      nodeSelector:  
        node-group: public  # public node group label
      containers:
        - name: ingress-nginx-controller
          image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:latest
          args:
            - /nginx-ingress-controller
            - --configmap=$(POD_NAMESPACE)/ingress-nginx-controller
          env:
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
          ports:
            - name: http
              containerPort: 80
            - name: https
              containerPort: 443

이외 ingress 및 service

spec:
  template:
    spec:
      nodeSelector:
        node-group: private

위 옵션으로 private node-group에만 배포한다.

청사진

profile
최고의 오늘을 꿈꾸는 개발자

0개의 댓글