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로 직접 통신 합니다.
클러스터 내부를 외부에 노출 - 발전 단계
- 파드 생성 : K8S 클러스터 내부에서만 접속
- 서비스(Cluster Type) 연결 : K8S 클러스터 내부에서만 접속
- 동일한 애플리케이션의 다수의 파드의 접속을 용이하게 하기 위한 서비스에 접속
- 서비스(NodePort Type) 연결 : 외부 클라이언트가 서비스를 통해서 클러스터 내부의 파드로 접속
- 서비스(NodePort Type)의 일부 단점을 보완한 서비스(LoadBalancer Type) 도 있습니다!
- 인그레스 컨트롤러 파드를 배치 : 서비스 앞단에 HTTP 고급 라우팅 등 기능 동작을 위한 배치
- 인그레스(정책)이 적용된 인그레스 컨트롤러 파드(예. nginx pod)를 앞단에 배치하여 고급 라우팅 등 기능을 제공
- 인그레스 컨트롤러 파드 이중화 구성 : Active(Leader) - Standby(Follower) 로 Active 파드 장애에 대비
- 인그레스 컨트롤러 파드를 외부에 노출 : 인그레스 컨트롤러 파드를 외부에서 접속하기 위해서 노출(expose)
- 인그레스 컨트롤러 노출 시 서비스(NodePort Type) 보다는 좀 더 많은 기능을 제공하는 서비스(LoadBalancer Type)를 권장합니다 (80/443 포트 오픈 시)
- 인그레스와 파드간 내부 연결의 효율화 방안 : 인그레스 컨트롤러 파드(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 사용 - 링크
# 모니터링
$ 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
마치며
많이 배우고 있지만, 따라가기에 급급하기도 하네요. 다행이도 자료 제공을 해주셔서 나중에 한번 더 봐야겠습니다. :)