6주차 - Ingress

0. 목적성

  • Ingress의 통신흐름을 확인하고 Ingress-Nginx Controller 정책을 설정합니다.

  • 실제 패킷을 확인해서 추가된 헤더들을 확인하고 OSI 7 Layer에서 로드밸런싱이 되는 것을 확인합니다.

  • host 기반 라우팅과 HTTPS 처리가 어떻게 되는지 확인합니다.

1. Ingress

  • ClusterIP 는 노드를 통해 pod을대상으로트래픽을 라우팅하는 서비스타입입니다.

  • LoadBalancer 서비스 타입은 기능에 제약성이 많습니다.

    • layer 3 를 기반으로 작동하고 있어서

      • tls termination, virtual host, path-base routing 이 안된다.

      • layer3는 service들이 healthy한지 모르게 됩니다. 노드가 없어지면 라우팅 테이블에 오랫동안 무제가 생긴다.

      • LoadBalncer는 한개의 내부 서비스를 외부 사용자들에게 접근 가능하게함

  • 이 때문에 Ingress 라는 서비스 타입이 생겼습니다.

    • 여러 서비스들에 대해서 한개의 로드밸런서로 유연한 설정을 할 수 있습니다.

  • ClusterIP 나 NodePort는

1.1 Ingress 소개

  • Ingress는 클러스터 내부의 서비스(ClusterIP, NodePort, Loadbalancer)를 외부로 노출(HTTP/HTTPS) - Web Proxy 역할을 합니다.

  • oad balancing, SSL termination and name-based virtual hosting. 의 기능들을 모두 지원합니다.

  • 여기서 중요한 부분은 여러개의 노드/서비스들에 대해서 LB가 가능합니다.

1.2 Ingress 네트워크 흐름

1.2.1 서비스에 NODEPORT 서비스를 생성합니다.

1.2.2 Ingress Controller Pod를 배치합니다.

1.2.3 해당 Ingress Controller Pod를 LoadBalancer로 분산부하를 실행합니다.

1.2.4 LAYER 7에서 파드의 IP 로 바로 트래픽을 전달합니다.

1.3 [실습] nginx Ingress Controller 설치 및 k3 환경 구성

- k3 환경 구성

curl -O https://s3.ap-northeast-2.amazonaws.com/cloudformation.cloudneta.net/kans/kans-6w.yaml
aws cloudformation deploy --template-file kans-6w.yaml --stack-name mylab --parameter-overrides KeyName=kp-gasida SgIngressSshCidr=$(curl -s ipinfo.io/ip)/32 --region ap-northeast-2

# 노드 확인
kubectl get node -owide
# 파드 확인
kubectl get pod -n kube-system

// 인그레스의 실제 동작 구현은 인그레스 컨트롤러
# Ingress-Nginx 컨트롤러 생성
cat <<EOT> ingress-nginx-values.yaml
controller:
  service:
    type: NodePort
    nodePorts:
      http: 30080
      https: 30443
  nodeSelector:
    kubernetes.io/hostname: "k3s-s"
  metrics:
    enabled: true
  serviceMonitor:
      enabled: true
EOT

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update

kubectl create ns ingress
helm install ingress-nginx ingress-nginx/ingress-nginx -f ingress-nginx-values.yaml --namespace ingress --version 4.11.2

# 확인
kubectl get all -n ingress
kc describe svc -n ingress ingress-nginx-controller

# externalTrafficPolicy 설정
kubectl patch svc -n ingress ingress-nginx-controller -p '{"spec":{"externalTrafficPolicy": "Local"}}'

# 기본 nginx conf 파일 확인
kc describe cm -n ingress ingress-nginx-controller
kubectl exec deploy/ingress-nginx-controller -n ingress -it -- cat /etc/nginx/nginx.conf

# 관련된 정보 확인 : 포드(Nginx 서버), 서비스, 디플로이먼트, 리플리카셋, 컨피그맵, 롤, 클러스터롤, 서비스 어카운트 등
kubectl get all,sa,cm,secret,roles -n ingress
kc describe clusterroles ingress-nginx
kubectl get pod,svc,ep -n ingress -o wide -l app.kubernetes.io/component=controller

# 버전 정보 확인
POD_NAMESPACE=ingress
POD_NAME=$(kubectl get pods -n $POD_NAMESPACE -l app.kubernetes.io/name=ingress-nginx --field-selector=status.phase=Running -o name)
kubectl exec $POD_NAME -n $POD_NAMESPACE -- /nginx-ingress-controller --version

  • 다양한 Nginx 인그레스 컨트롤러 인입 방법이 있습니다

    • metalb, host network 사용, provisioned edge, external Ips

1.4 [실습] ingress 정책설정 및 통신 흐름 확인

  • INGRESS NGINX 파드를 생성해서 NODE PORT로 외부 노출합니다.

  • 인그레스 정책 설정으로 EXTERNAL POLICY를 LOCAL로 설정하고

// Some code
  • 3.1 디플로이먼트와 서비스를 생성합니다.

# 생성
kubectl taint nodes k3s-s role=controlplane:NoSchedule
curl -s -O https://raw.githubusercontent.com/gasida/NDKS/main/7/svc1-pod.yaml
curl -s -O https://raw.githubusercontent.com/gasida/NDKS/main/7/svc2-pod.yaml
curl -s -O https://raw.githubusercontent.com/gasida/NDKS/main/7/svc3-pod.yaml
kubectl apply -f svc1-pod.yaml,svc2-pod.yaml,svc3-pod.yaml

Ingress Nginx 로 backend pod IP 바로 접근 가능하다.

  • 3.2 인그레스 정책 생성합니다.

cat <<EOT> ingress1.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-1
  annotations:
    #nginx.ingress.kubernetes.io/upstream-hash-by: "true"
spec:
  ingressClassName: nginx
  rules:  # 각각 분기하는 로직을 보여줍니다.
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: svc1-web
            port:
              number: 80
      - path: /guest
        pathType: Prefix
        backend:
          service:
            name: svc2-guest
            port:
              number: 8080
      - path: /admin
        pathType: Prefix
        backend:
          service:
            name: svc3-admin
            port:
              number: 8080
EOT

kubectl apply -f ingress1.yaml
kubectl exec deploy/ingress-nginx-controller -n ingress -it -- cat /etc/nginx/nginx.conf | grep 'location /' -A5
  • 3.3 인그레스 접속 분산 확인

  • 3.4 패킷 XFF 확인

xff 가 해당 나의 ip가 찍히는것을 볼 수 있습니다.

1.5 [실습] hostbased 라우팅

  • 인그레스 를 통한 접속 까지 확인했습니다!~

Last updated