CloudNetaStudy - Kubernets Networtk 3기 실습 스터디 게시글입니다.
Ingress - 링크
클러스터 내부의 서비스(ClusterIP, NodePort, Loadbalancer)를 외부로 노출(HTTP/HTTPS) - Web Proxy 역할
- HTTP/HTTPS 요청 트래픽을 부하분산
- 카나리 배포 지원
출처 - 김태민 기술 블로그 https://kubetm.github.io/k8s/08-intermediate-controller/ingress/ - 경로 기반, 호스트 기반 라우팅 지원
- SSL/TLS 종료를 지원
- 외부 → 인그레스 컨트롤러 : https 접속
- 인그레스 컨트롤러 파드 → (내부망)목적지 파드 : http 통신
전제 조건
- 인그레스 컨트롤러가 있어야 인그레스를 충족할 수 있다. 인그레스 리소스만 생성한다면 효과가 없다.
- ingress-nginx와 같은 인그레스 컨트롤러를 배포해야 할 수 있다.
- 인그레스 컨트롤러는 참조 사양이 맞아야 한다. 실제로, 다양한 인그레스 컨트롤러는 조금 다르게 작동한다.
- 인그레스 컨트롤러 : 인그레스의 실제 동작 구현은 인그레스 컨트롤러(Nginx, Kong 등)가 담당
[ 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 등 현재 대부분의 인그레스 컨트롤러가 지원함.
Nginx 인그레스 컨트롤러 설치
인그레스 컨트롤러 : 인그레스의 실제 동작 구현은 인그레스 컨트롤러(Nginx, Kong 등)가 처리 - 링크
- 쿠버네티스는 Ingress API 만 정의하고 실제 구현은 add-on 에 맡김
- Ingress-Nginx Controller - 링크 ⇒ 간편한 테스트를 위해서 NodePort 타입(externalTrafficPolicy: Local) 설정
- 다양한 Nginx 인그레스 컨트롤러 인입 방법
- MetalLB 사용, Via the host network 사용, Using a self-provisioned edge 사용, External IPs 사용 - 링크
- Ingress NGINX Controller for Kubernetes - Home , Github
- Ingress-Nginx 컨트롤러 생성 - ArtifactHub release
# 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
- (옵션) kubectl krew 설치 - 링크 & ingress-nginx plugin 설치 - 링크
# (참고) 운영체제 확인 : linux OS="$(uname | tr '[:upper:]' '[:lower:]')" # (참고) CPU 아키텍처 확인 : amd64 ARCH="$(uname -m | sed -e 's/x86_64/amd64/' -e 's/\(arm\)\(64\)\?.*/\1\2/' -e 's/aarch64$/arm64/')" # (참고) KREW 지정 : krew-linux_amd64 KREW="krew-${OS}_${ARCH}" # kubectl krew 설치 # curl -fsSLO "https://github.com/kubernetes-sigs/krew/releases/latest/download/${KREW}.tar.gz" curl -fsSLO "https://github.com/kubernetes-sigs/krew/releases/latest/download/krew-linux_amd64.tar.gz" && tar zxvf krew-linux_amd64.tar.gz && ./krew-linux_amd64 install krew export PATH="${KREW_ROOT:-$HOME/.krew}/bin:$PATH" # 플러그인 정보 업데이트 후 확인 - 링크 kubectl krew update kubectl krew search # ingress-nginx 플러그인 설치 kubectl krew install ingress-nginx # ingress-nginx 플러그인 명령어 실행(도움말 출력) kubectl ingress-nginx # nginx ctrl 의 backends 설정 정보 출력 kubectl ingress-nginx backends -n ingress-nginx --list kubectl ingress-nginx backends -n ingress-nginx # conf 출력 kubectl ingress-nginx conf -n ingress-nginx ## 특정 호스트(도메인) 설정 확인 kubectl ingress-nginx conf -n ingress-nginx --host gasida.cndk.link kubectl ingress-nginx conf -n ingress-nginx --host nasida.cndk.link # 정보 보기 편함! kubectl ingress-nginx ingresses kubectl ingress-nginx ingresses --all-namespaces
인그레스(Ingress) 실습 및 통신 흐름 확인
[ 실습 구성도 ]
- 컨트롤플레인 노드에 인그레스 컨트롤러(Nginx) 파드를 생성, NodePort 로 외부에 노출
- 인그레스 정책 설정 : Host/Path routing, 실습의 편리를 위해서 도메인 없이 IP로 접속 설정 가능
https://kschoi728.tistory.com/266 스터디 실습 기본 환경 참고
[ 디플로이먼트와 서비스를 생성 ]
- 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,pod -owide' # 생성 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 # 확인 : svc1, svc3 은 ClusterIP 로 클러스터 외부에서는 접속할 수 없다 >> Ingress 는 연결 가능! kubectl get pod,svc,ep
[ 인그레스(정책) 생성 - 링크 ]
- ingress1.yaml
https://kschoi728.tistory.com/266 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 ingress,svc,ep,pod -owide' # 생성 kubectl apply -f ingress1.yaml # 확인 kubectl get ingress kc describe ingress ingress-1 ... Rules: Host Path Backends ---- ---- -------- * / svc1-web:80 () /guest svc2-guest:8080 () /admin svc3-admin:8080 () ... # 설정이 반영된 nginx conf 파일 확인 kubectl exec deploy/ingress-nginx-controller -n ingress -it -- cat /etc/nginx/nginx.conf kubectl exec deploy/ingress-nginx-controller -n ingress -it -- cat /etc/nginx/nginx.conf | grep 'location /' -A5 location /guest/ { set $namespace "default"; set $ingress_name "ingress-1"; set $service_name "svc2-guest"; set $service_port "8080"; -- location /admin/ { set $namespace "default"; set $ingress_name "ingress-1"; set $service_name "svc3-admin"; set $service_port "8080"; -- location / { set $namespace "default"; set $ingress_name "ingress-1"; set $service_name "svc1-web"; set $service_port "80"; -- ...
- rule:
* : 어떤 서비스든 OK. prefix 경로에 따라 뒤에 label selecting 된 pod로 traffic 분기
- rule:
[ 인그레스를 통한 내부 접속 ]
- Nginx 인그레스 컨트롤러를 통한 접속(HTTP 인입) 경로 : 인그레스 컨트롤러 파드에서 서비스 파드의 IP로 직접 연결 (아래 오른쪽 그림)
1. 인그레스 접속 경로 : Ingress → 애플리케이션 서비스(Service) → 애플리케이션(Deploy, Pod 등) 2. 인그레스 접속 경로(서비스 Bypass) : Ingress → 애플리케이션(Deploy, Pod 등) - 인그레스(Nginx 인그레스 컨트롤러)를 통한 접속(HTTP 인입) 확인*** : HTTP 부하분산 & PATH 기반 라우팅, 애플리케이션 파드에 연결된 서비스는 Bypass
'Kubernetes' 카테고리의 다른 글
[ Kans 3 Study - 6w ] 4. HTTPS 처리(TLS 종료) (0) | 2024.10.13 |
---|---|
[ Kans 3 Study - 6w ] 3. Host 기반 라우팅 / 카나리 업그레이드 (0) | 2024.10.13 |
[ Kans 3 Study - 6w ] 1.실습환경 구성 (6) | 2024.10.12 |
[ Kans 3 Study - 5w ] 3. External IP / IPVS Proxy 모드 (2) | 2024.10.05 |
[ Kans 3 Study - 5w ] 2. MetalLB (2) | 2024.10.05 |