• Home
  • About
    • lahuman photo

      lahuman

      열심히 사는 아저씨

    • Learn More
    • Facebook
    • LinkedIn
    • Github
  • Posts
    • All Posts
    • All Tags
  • Projects

#6 Ingress

23 Feb 2022

Reading time ~5 minutes

Ingress

벌써 6주차 입니다. 이번 시간에는 Ingress에 대하여 진행하였습니다. 앞으로 2주 + 1주(9주차는 마무리라고 들었습니다.) 남았네요. 남은 시간 열심히 해야겠습니다.

참고 자료로 이전에 정리한 kubernetes의 각 항목을 살펴보자. 가 있습니다. Kuernetes를 잘 모르신다면 먼저 읽고 오시길 추천 드립니다.

실습 환경

실습 환경은 K8S v1.22.6 , 노드 OS(Ubuntu 20.04.3) , CNI(Calico v3.21, Direct mode) , IPTABLES proxy mode

  • 컨테이너 런타임(CRI)은 containerd 를 사용합니다.
  • 실습 편의를 위해 ‘모든 VM’ 에 kubectl, calicoctl 설정을 추가하였습니다.
# K8S 배포에 사용할 폴더(디렉터리)를 생성 후 사용해주세요
# vagrant 파일 다운로드
$ curl -O https://raw.githubusercontent.com/gasida/KANS/main/6/Vagrantfile

# 배포
$ vagrant up

# 배포 확인 : k8s-m, k8s-w1, k8s-w2, (k8s-w3), k8s-pc
$ vagrant status

# 마스터노드 접속
$ vagrant ssh k8s-m

# 마스터노드에서 CONTAINER-RUNTIME 확인 (containerd)
$ kubectl get node -owide
NAME     STATUS   ROLES                  AGE     VERSION   INTERNAL-IP      EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION     CONTAINER-RUNTIME
k8s-m    Ready    control-plane,master   4m20s   v1.22.6   192.168.10.10    <none>        Ubuntu 20.04.3 LTS   5.4.0-89-generic   containerd://1.4.12
k8s-w1   Ready    <none>                 2m31s   v1.22.6   192.168.10.101   <none>        Ubuntu 20.04.3 LTS   5.4.0-89-generic   containerd://1.4.12
...

# 도커 컨테이너가 설치가 되어 있지 않다!
$ docker ps

# 마스터노드에서 Calico 확인 (Direct mode)
$ calicoctl get ippool -o wide

Ingress 요약

인그레스(Ingress) 를 통한 통신 흐름

Nginx 인그레스 컨트롤러 경우 : 외부에서 인그레스로 접속 시 Nginx 인그레스 컨트롤러 파드로 인입되고, 이후 애플리케이션 파드의 IP로 직접 통신 합니다.

클러스터 내부를 외부에 노출 - 발전 단계

  1. 파드 생성 : K8S 클러스터 내부에서만 접속

  1. 서비스(Cluster Type) 연결 : K8S 클러스터 내부에서만 접속
    • 동일한 애플리케이션의 다수의 파드의 접속을 용이하게 하기 위한 서비스에 접속

  1. 서비스(NodePort Type) 연결 : 외부 클라이언트가 서비스를 통해서 클러스터 내부의 파드로 접속
    • 서비스(NodePort Type)의 일부 단점을 보완한 서비스(LoadBalancer Type) 도 있습니다!

  1. 인그레스 컨트롤러 파드를 배치 : 서비스 앞단에 HTTP 고급 라우팅 등 기능 동작을 위한 배치
    • 인그레스(정책)이 적용된 인그레스 컨트롤러 파드(예. nginx pod)를 앞단에 배치하여 고급 라우팅 등 기능을 제공

  1. 인그레스 컨트롤러 파드 이중화 구성 : Active(Leader) - Standby(Follower) 로 Active 파드 장애에 대비

  1. 인그레스 컨트롤러 파드를 외부에 노출 : 인그레스 컨트롤러 파드를 외부에서 접속하기 위해서 노출(expose)
    • 인그레스 컨트롤러 노출 시 서비스(NodePort Type) 보다는 좀 더 많은 기능을 제공하는 서비스(LoadBalancer Type)를 권장합니다 (80/443 포트 오픈 시)

  1. 인그레스와 파드간 내부 연결의 효율화 방안 : 인그레스 컨트롤러 파드(Layer7 동작)에서 서비스 파드의 IP로 직접 연결
    • 인그레스 컨트롤러 파드는 K8S API서버로부터 서비스의 엔드포인트 정보(파드 IP)를 획득 후 바로 파드의 IP로 연결 - 링크
    • 지원되는 인그레스 컨트롤러 : Nginx, Traefix 등 현재 대부분의 인그레스 컨트롤러가 지원함

인그레스의 주요 동작에 대한 내용은 생략하였고, 인그레스를 통한 통신 흐름에 집중하여 설명을 하였음을 미리 알려드립니다.

인그레스 소개 : 클러스터 내부의 서비스(ClusterIP, NodePort, Loadbalancer)를 외부로 노출(HTTP/HTTPS) - Web Proxy 역할

  • 인그레스 기능 : HTTP(서비스) 부하분산 , 카나리 업그레이드
  • 인그레스 + 인그레스 컨트롤러(Nginx) 기능 : HTTP(서비스) 부하분산 , 카나리 업그레이드 , HTTPS 처리(TLS 종료)
  • Ingress 비교 - 링크

Nginx 인그레스 컨트롤러 설치

인그레스(Ingress) 소개 : 클러스터 내부의 HTTP/HTTPS 서비스를 외부로 노출(expose) - 링크

출처 : https://kubernetes.io/ko/docs/concepts/services-networking/ingress/

출처 :https://k8s.networkop.co.uk/ingress/ingress/

인그레스 컨트롤러 : 인그레스의 실제 동작 구현은 인그레스 컨트롤러(Nginx, Kong 등)가 처리 - 링크

  • 쿠버네티스는 Ingress API 만 정의하고 실제 구현은 add-on 에 맡김
  • Nginx 인그레스 컨트롤러 - 링크 ⇒ 간편한 테스트를 위해서 NodePort 타입(externalTrafficPolicy: Local) 설정

출처 : https://github.com/kubernetes/ingress-nginx/blob/master/docs/deploy/baremetal.md

  • 다양한 Nginx 인그레스 컨트롤러 인입 방법 : MetalLB 사용, Via the host network 사용, Using a self-provisioned edge 사용, External IPs 사용 - 링크

  • Nginx 인그레스 컨트롤러 생성 - 링크 release

# 모니터링
$ watch kubectl get all -n ingress-nginx

# nginx ingress controller v1.1.1 설치 (마스터 노드에 설치)
# https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.1/deploy/static/provider/cloud/deploy.yaml
$ kubectl apply -f https://raw.githubusercontent.com/gasida/KANS/main/6/nginx-ingress.yaml

# 네임스페이스 확인
$ kubectl get namespaces

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

# ingress-nginx-controller NodePort(HTTP 접속용) 변수 지정
$ export IngHttp=$(kubectl get service -n ingress-nginx ingress-nginx-controller -o jsonpath='{.spec.ports[0].nodePort}')
$ echo $IngHttp
31080

# ingress-nginx-controller NodePort(HTTPS 접속용) 변수 지정
$ export IngHttps=$(kubectl get service -n ingress-nginx ingress-nginx-controller -o jsonpath='{.spec.ports[1].nodePort}')
$ echo $IngHttps
30836

인그레스(Ingress) 실습 및 통신 흐름 확인

실습 구성도

  • 마스터 노드에 인그레스 컨트롤러(Nginx) 파드를 생성, NodePort 로 외부에 노출
  • 인그레스 정책 설정 : Host/Path routing, 실습의 편리를 위해서 도메인 없이 IP로 접속 설정 가능

3.1 디플로이먼트와 서비스를 생성

  • svc1-pod.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
    name: deploy1-websrv
spec:
    replicas: 1
    selector:
    matchLabels:
        app: websrv
    template:
    metadata:
        labels:
        app: websrv
    spec:
        containers:
        - name: pod-web
        image: nginx
---
apiVersion: v1
kind: Service
metadata:
    name: svc1-web
spec:
    ports:
    - name: web-port
        port: 9001
        targetPort: 80
    selector:
    app: websrv
    type: ClusterIP
  • svc2-pod.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
    name: deploy2-guestsrv
spec:
    replicas: 2
    selector:
    matchLabels:
        app: guestsrv
    template:
    metadata:
        labels:
        app: guestsrv
    spec:
        containers:
        - name: pod-guest
        image: gcr.io/google-samples/kubernetes-bootcamp:v1
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
    name: svc2-guest
spec:
    ports:
    - name: guest-port
        port: 9002
        targetPort: 8080
    selector:
    app: guestsrv
    type: NodePort
  • svc3-pod.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
    name: deploy3-adminsrv
spec:
    replicas: 3
    selector:
    matchLabels:
        app: adminsrv
    template:
    metadata:
        labels:
        app: adminsrv
    spec:
        containers:
        - name: pod-admin
        image: k8s.gcr.io/echoserver:1.5
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
    name: svc3-admin
spec:
    ports:
    - name: admin-port
        port: 9003
        targetPort: 8080
    selector:
    app: adminsrv
  • 생성 및 확인
# 모니터링
$ watch -d 'kubectl get ingress,svc,ep;echo; calicoctl get wep'

# 생성
$ 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

# 확인 : svc1, svc3 은 ClusterIP 로 클러스터 외부에서는 접속할 수 없다 >> Ingress 는 연결 가능!
$ kubectl get pod,svc,ep

3.2 인그레스(정책) 생성 - 링크

  • ingress1.yaml
$ 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
  • 인그레스 생성 및 확인
# 모니터링
$ watch -d 'kubectl get ingresses,svc,ep;echo; calicoctl get wep'

# 생성
$ kubectl apply -f ingress1.yaml

# 확인
$ kubectl get ingress
$ kubectl describe ingress ingress-1

3.3 인그레스를 통한 내부 접속

  • Nginx 인그레스 컨트롤러를 통한 접속(HTTP 인입) 경로 : 인그레스 컨트롤러 파드에서 서비스 파드의 IP로 직접 연결 (아래 오른쪽 그림)

인그레스 접속 경로 : Ingress → 애플리케이션 서비스(Service) → 애플리케이션(Deploy, Pod 등)

인그레스 접속 경로(서비스 Bypass) : Ingress → 애플리케이션(Deploy, Pod 등)

Gateway API 소개

Gateway API 소개 : 기존의 Ingress 에 좀 더 기능을 추가

  • 서비스 메시(istio)에서 제공하는 Rich 한 기능 중 일부 기능들과 혹은 운영 관리에 필요한 기능들을 추가
  • 추가 기능 : 헤더 기반 라우팅, 헤더 변조, 트래픽 미러링(쉽게 트래픽 복제), 역할 기반

https://youtu.be/GiFQNevrxYA?t=172

마치며

많이 배우고 있지만, 따라가기에 급급하기도 하네요. 다행이도 자료 제공을 해주셔서 나중에 한번 더 봐야겠습니다. :)



kangingress Share Tweet +1