이쿠의 슬기로운 개발생활

함께 성장하기 위한 보안 개발자 EverNote 내용 공유

클라우드/Kubernetes

08. Kubernetes Network (Ingress)

이쿠우우 2020. 8. 12. 21:41
반응형

Kubernetes Network ( Ingress )

 


Kubernetes Network 관련 글 이동

1. Kuberentes Network 이론
2. Kubernetes Network (ClusterIP, NodePort)
3. Kubernetes Network (LoadBalancer)
4. Kubernetes Network (Ingress)


Ingress란? (인그레스)

Kubernetes CNI Addon 종류 중 하나.

일반적으로 네트워크 트래픽은 ingress와 egress로 구분됨

ingress : 외부에서 내부로 유입되는 네트워크 트래픽

engress : 내부에서 외부로 나가는 네트워크 트래픽

Kubernetes Ingress는 Cluster 외부에서 내부로 접근하는 요청들을 어떻게 처리할지 정의해둔 규칙들의 모음

Ingress는 외부에서 Kubernetes에서 실행 중인

Deployment와 Service에 접근하기 위한 일종의 관문 (Gateway) 같은 역할을 담당

 

Kubernetes 1.2 version부터 Ingress Addon을 제공.

Ingress를 Service Object의 Type 중 하나 or Controller 종류 중에 하나라고 부르기도 하지만

따지고 보면 Ingress는 Service Object의 Type, Controller 기능 안에 포함되어 있는 것이 아니라

별도의 Object 임.

리소스 Object라고 분류하기도 함

 

Service Object의 NodePort와 LoadBalancer Type은 L4 Layer로 동작하여 TCP 단에서 밸런싱함

하지만 ingress의 경우 L7 Layer에서 요청을 처리할 수 있음

 

Ingress 자체는 이런 규칙들을 정의해둔 자원이고

이런 규칙들을 실제로 동작하게 해 주는 게  Ingress Controller라고 함.

 

Ingress 기능

1. 외부에서 접근 가능한 URL을 사용할 수 있게 해 줌

 

2. 트래픽 로드밸런싱

 

3. SSL 인증서 처리

 

4. path-based routing

도메인 기반으로 가상 호스팅을 제공

즉 ip 가 아닌 이름 기반의 주소 처리

 

5. SSL/TLS termination

TLS란?
브라우저 같은 클라이언트가 공개된 인터넷 망을 통해 웹서버와 커뮤니케이션할 때,
여러 가지 보안 메커니즘을 제공하여
원하는 상대와 안전하게 연결될 수 있도록 도와주는 인터넷 프로토콜

6. virtual hosts

 

 

Ingress와 Ingress Controller

kubernetes에서 Ingress를 사용하기 위해서는 두 가지가 필요.

 

첫 번째 : YAML 파일에서 [kind: Ingress]로 정의되는 Ingress 오브젝트.

두 번째 : Ingress 규칙이 적용될 Ingress Controller 

 

YAML 파일로부터 Ingress를 생성해도 아무 일도 일어나지 않음

Ingress는 단지 Ingress 규칙을 정의하는 선언적인 오브젝트일 뿐,

외부 요청을 받아들이는 실제 서버가 아니기 때문.

Ingress는 Ingress Controller라고 하는 특수한 서버 컨테이너에 적용되어야만

Ingress에 적용된 규칙이 활성화됨

즉, Ingress Controller가 외부로부터 네트워크 요청을 수신했을 때,

Ingress 규칙에 기반해 이 요청을 어떻게 처리할지를 결정.

 

Kubernetes에서 공식적으로 제공하는 Ingress Controller

1. ingress-gce

클라우드 플랫폼에 위임.

GCP의 GKE ( Google Kubernetes Engine )를 사용하면 제공.

 

2. ingress-nginx

직접 Ingress Controller를 구동할 때 사용.

Kubernetes Cluster에 설치해서 사용 가능

 

Ingress와 LoadBalancer의 차이점

Service Object 의 LoadBalancer Type

외부 사용자들이 단지 한 개의 Service Object(backend 서비스)에 접근 가능하도록 해주는 일을 담당.

 

Ingress

Ingress를 이용하면 한개의 LoadBalancer로

여러 개의 Service Object(backend 서비스)들을 연결할 수 있게 만들어 줌.

즉 여러개의 Service 가 한 개 LoadBalancer를 통해 유연한 설정을 할 수 있게 해 줌.

 

 


 

 

 

참고) 실습환경

 

[Master Node server]

OS = CentOS 7

IP :  192.168.64.150

리눅스 커널 버전 : Linux 3.10.0-1062.el7.x86_64

docker version : 1.13.1

docker api verison : 1.26

 

[Worker Node server]

OS = CentOS 7

IP : 192.168.64.149

리눅스 커널 버전 : Linux 3.10.0-1062.el7.x86_64

docker version : 1.13.1

docker api verison : 1.26

 

[Kubernetes version]

1.18

 

[예제 환경]

Deployment 

  • replicaset : 3

  • 1개의 Pod 안에 Tomcat Container 1개 포함

Service 1

  • Deployment에Deployment에 연결된 clusterIP Type service

Ingress

  • "Service 1" 을 바라보는 Ingress

 

 


 

 

 

1. Ingress Controller 설치

Ingress Controller 는 매우 다양한 종류가 있지만

kubernetes에서 공식적으로 지원하는 ingress controller는

현재 GCP 의 GCE와 Nginx 가 있음

haproxy ingress controller 도 존재하지만 kubernetes 가 공식적으로 지원하진 않음

 

Ingress Controller 종류 참고 : https://kubernetes.io/ko/docs/concepts/services-networking/ingress-controllers/

 

1.1. ingress-nginx 설치 명령어

[명령어]

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/cloud/deploy.yaml

 

상위 명령어 참고 :  https://kubernetes.github.io/ingress-nginx/deploy/

해당 링크의  Kubernetes is available in Docker for Mac (from version 18.06.0-ce) 부분 확인

 

참고) : 다양한 종류의 Ingress Controller가 있지만 예제에서는 Nginx 사용

 

1.2. 결과

ingress-nginx라는 Namespace 생성,

ingress 구현체인 ingress-nginx 에 대한 리소스들이 생성됨

 

1.3. 생성 확인 명령어

kubectl get namespace

 

kubectl get all -n ingress-nginx

kubernetes cluster 에 ingress-nginx 라이는 namespace 가 생성되고

해당 namespace 에 ingress에서 사용하는 각종 자원들이 생성됨

그중 service/ingress-nginx-controller를 확인해야 함

ingress는 default로 LoadBalancer 가 생성이 되는데 service/ingress-nginx-controller 가 이에 해당함

service/ingress-nginx-controller는

Public Cloud 환경 (AWS, GCP, Azure)인 경우 해당 Cloud의 LoadBalancer와 연동되고

On-Premise 환경의 경우 MetalLB Addon의 LoadBalancer 와 연동이 되는데

상위 실험에서는 MetalLB을 사용했으므로 MetalLB의 LoadBalaner와 연동되어 있는 상태로 진행

 

On-Premise 란?
기업의 서버를 클라우드 같은 원격 환경에서 운영하는 방식이 아닌,
자체적으로 보유한 전산실 서버에 직접 설치해 운영하는 방식
Private Cloud와 동일한 뜻

 

1.4. MetalLB (kubernetes Addon) - LoadBalancer 환경의 Ingress

Ingress 요청을 처리하기 위한 Service Object는

일반적으로 클라우드 플랫폼에서 제공되는 Load Balancer 타입의 Service를 사용.

하지만 On-Premise환경(Private Cloud)에서 운영하고 있는 서버에 Ingress를 직접 구축하게 된다면,  

Service의 Type으로서 NodePort, ExternalIP, 또는 

kubernetes Addon 종류 중에 하나인 MetalLB 등을 대신 사용할 수 있음

 

1.4.1. MetalLB 설치

[명령어] 

kubectl apply -f https://raw.githubusercontent.com/google/metallb/v0.8.3/manifests/metallb.yaml

 

[결과 확인]

명령어 : kubectl get namespace

설치하면 namespace에 Metallb 이 추가됨

 

1.4.2. MetalLB 설정 (ConfigMap 배포)

예제 yaml 파일 작성

파일 이름 :  metallb_test.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
    - name: my-ip-space
      protocol: layer2
      addresses:
      - 10.0.2.10-10.0.2.200 

[명령어]

kubectl apply -f config.yaml

 

 

1.5. MetalLB을 통해 LoadBalancer EXTERNAL-IP를 할당 받음

1.3 단계에서 LoadBalancer의 EXTERNAL-IP가 <pending> 상태였지만

metalLB을 구성하고 일정 시간이 지난 뒤에

위와 같이 IP를 할당받아서 LoadBalancer를 통해 외부에서 Ingress로 접근할 수 있음

 

[참고] 

1.3에 있는 그림과 상위 그림이 Cluster-IP와 Port 정보가 다른데 

external-ip 설명을 위해 pending 상태 캡처를 넣기 위해 다른 환경의 ingress-controller를 캡처해서 정보가 다름

1.3 그림 정보는 참고용 일뿐

앞으로 설명은 1.4 그림의 정보 기준으로 하겠음

 

 

1.6. 해당 과정까지 그림 정리

 

 

1.7. ingress-controller 삭제 명령어 참고)

[명령어]

kubectl delete namespace ingress-nginx

kubectl delete clusterrole ingress-nginx

kubectl delete clusterrole nginx-ingress-clusterrole

kubectl delete clusterrole ingress-nginx-admission

kubectl delete clusterrolebinding ingress-nginx

kubectl delete clusterrolebinding ingress-nginx-admission

kubectl delete validatingwebhookconfiguration ingress-nginx-admission

 

 

 


 

 

2. On-Premise 환경에서의 Ingress 

 

2.1. 예제 deployment 생성 

 

예제 deployment  yaml 파일 작성

참고 : Service의 경우 type을 설정하지 않으면 default로 cluster ip로 설정됨

apiVersion: apps/v1

kind: Deployment

metadata:

  name: iksoon-deployment

  labels:

    app: iksoon-tomcat

spec:

  replicas: 2

  selector:

    matchLabels:

      app: iksoon-pod

  template:

    metadata:

      labels:

        app: iksoon-pod

    spec:

      containers:

      - name: iksoon-tomcat

        image: peksoon/iksoon_tomcat:1.0.3

        ports:

        - containerPort: 8080

---

apiVersion: v1

kind: Service

metadata:

  name: iksoon-service

spec:

  ports:

  - port: 8080

    targetPort: 8080

  selector:

    app: iksoon-pod

[명령어]

kubectl apply -f deployment.yaml

 

 

 

2.2. 해당 과정까지의 그림 정리

 

 

 

 

2.3. 예제 ingress 설정 생성 

2.3.1. 예제 ingress yaml 파일 작성

apiVersion: extensions/v1beta1

kind: Ingress

metadata:

  name: iksoon-ingress-nginx

  namespace: default

  annotations:

    nginx.ingress.kubernetes.io/rewrite-target: /$2

spec:

  rules:

  - host: iksoon.test.com # host 명을 명시하지 않으면 ip로 연결

    http:

      paths:     #각 path는 backend와 연결됨

      - path: /app1(/|$)(.*)  # 상위 nginx의 rewrie-target 설정에 따라서 동작

        backend:

          serviceName: iksoon-service

          servicePort: 8080

2.3.1. ingress yaml 파일 설명

---[metadata.annotations 설정 설명]---

ingress의 어떤 ingress controller 종류를 사용하는지 명시하고

그 종류에 따른 설정을 명시함

kubernetes.io/ingress.class: "nginx"
어떤 ingress controller를 사용할 것인지 설정
해당 설정이 없으면 설치되어있는 ingress controller 중 
임의로 선정해서 동작함
예) 
Nginx : "nginx"
AWS EKS : "alb"
GCP GKE : "gce"
nginx.ingress.kubernetes.io/rewrite-target: /
rule의 path에 지정된 경로를 해당 주석에 설정된 경로로 Redirect 함
nginx.ingress.kubernetes.io/force-ssl-redirect : 
http로 접속했을 때 강제로 https로 Redirect 함

위의 예제 3개 이외에 매우 다양한 anootation 설정이 존재함

 

 

---[spec.rules.http.path 설정 참고]---

rule의 path에 지정된 경로를 해당 주석에 설정된 경로로 Redirect 한다.

예) nginx.ingress.kubernetes.io/rewrite-target: /$2 설정 시

rewrite.bar.com/something rewrites to rewrite.bar.com/

rewrite.bar.com/something/ rewrites to rewrite.bar.com/

rewrite.bar.com/something/new rewrites to rewrite.bar.com/new

 

 

 

2.3.3. ingress yaml 설정 적용

[명령어]

kubectl apply -f Service.yaml

 

[오류 참고]

오류 메시지 : Internal error occurred: failed calling webhook "validate.nginx.ingress.kubernetes.io"

[해결법]

인증과 관련된 ingress 설정을 제거.

최근(2020.03월) ingress 가 update 가 되고 발생하는 오류인데 

정확한 해결법이 정리되어있지 않음

개인적으로 알아낸 해결법 : kubectl delete validatingwebhookconfiguration ingress-nginx-admission

 

 

2.3.4. ingress 생성 후 확인 참고 명령어

[명령어]

kubectl get ingress 

 

해당 명령 후 ADDRESS에 IP가 정상적으로 할당되야함

[명령어]

kubectl get svc -n ingress-nginx

 

name 이 ingress-nginx-controller 인 service object를 확인, EXTERNAL-IP 확인

 

 

2.3.5. hosts 파일 수정

[명령어]

vi /etc/hosts 

 

상위에서 확인한 EXTERNAL-IP와 HOSTS 이름을 매칭 시켜서 추가해야 함

 

2.3.6.  ingress를 통해 접속해보기

해당 과정까지 완료한 후

curl http://iksoon.test.com/iksoon_test/iksoon_home.jsp

명령 시 page html 이 나오면 ingress 연동 성공

참고) 도메인이 아닌 IP로 접근 시도 시 404 error.

 

 

2.3.6. 해당 과정까지의 정리

 

 

 

 


 

 

3. ingress 동작원리를 알기 위해 ingress pod에 접속하여 nginx 설정을 확인

먼저 동작중인 ingress-controller Pod를 확인

[명령어]

kubectl get all -n ingress-nginx

 

Pod로 접속

[명령어]

kubectl -n ingress-nginx exec -it  pod/ingress-nginx-controller-8f7b9d799-89pdf -- /bin/bash

nginx 설정 확인 명령어 : vi /etc/nginx/nginx.conf

해당 파일에서 ingress nginx 설정을 확인할 수 있음

server {} 항목을 확인해 보면 ingress.yaml 파일로 설정한

"- host" 부분이 nginx.conf의 server 부분에 명시되어 있는 것을 확인할 수 있고

"set $service_name   "iksoon-service" 설정 부분으로 보아

ingress는 kubernetes의 service와 연결되어 있는 것을 확인할 수 있음

 

이 결과로

External Network 사용자가 LoadBalancer IP로 접속하면

Ingress Controller Pod로 연결되고 

해당 Ingress Controller Pod가 ingress에 설정되어있는 domain주소로 service object와 연결하게 되는 것을

확인할 수 있음

 

 

[용도 1 : external network에서 ingress 통해 pod로 접근 ( 도메인 )]

만약 iksoon.test.com 이란 도메인이 실제 구입한 도메인이라면 

외부 네트워크에서도 접근이 가능

혹은 hosts 파일에 설정한 도메인과 loadbalancer ip를 설정하면 

외부 네트워크에서 접근 가능

참고) Windows 의경우 hosts 파일 경로 : C:\Windows\System32\drivers\etc

 

[용도 2 : external network에서 ingress 통해 pod로 접근 ( IP )]

구입한 도메인이 없다면 ingress 설정 중 spec > roles 하위의 hosts 설정을 하지 않으면

ingress exteral ip로 할당받은 주소로 외부에서 내부로 접근 가능

 

[용도 3. : cluster 내부 자원 간의 통신 역할]

하지만 구입한 도메인이 아니라면 Cluster 내부의 자원 간에 

설정한 도메인으로 통신하는 용도로 사용

 

 

 


 

 

4. NodePort (Service Object Type) 환경의 Ingress

 

상위 1. Ingress Controller 설치 과정을 통해 ingress Controller 가 설치되면 

기본적으로 LoadBalancer Type의 service/ingress-nginx-controller 가 생성되는데

NodePort 환경의 Ingress를 구성하기 위해서는

해당 service/ingress-nginx-controller 를 NodePort Type의 Service로 변경해주면 됨

 

 

4.1. NodePort Ingress를 사용하는 환경

Bare Metal Server 환경의 Cloud에서 주로 사용됨.

 

4.1.1. Bare Metal Server란?

어떠한 소프트웨어도 담겨있지 않은 하드웨어.

On-Premise 환경의 Cloud 크게 호스트형 가상화 방식, Bare Metal 방식 2가지로 분류됨.

 

호스트 가상화 방식이란?
하드웨어 위에 하이퍼바이저 OS를 설치하고 그 위에 가상 서버를 구현하는 방식.
하이퍼바이저에 설치된 OS 간에 하드웨어의 리소스를 공유하는 방식.
Bare Metal 방식이란?
하드웨어 위에 하이퍼바이저 OS 설치 없이 
직접 하드웨어 위에 OS가 설치되는 방식.
한 개의 OS가 하드웨어의 모든 성능을 사용할 수 있는 방식.
즉 단독 물리 서버를 제공하는 방식.

이렇게 다수의 Bare Metal Server로 구성된 

Bare Metal Cloud 환경에서는 LoadBalancer를 사용하기보다 

각 Bare Metal Server에 NodePort를 부여해서 Port로 접근하는 방식을 선호한다고 함.

그래서 NodePort ingress를 사용함.

 

 

 

4.2. ingress-nginx-controller service NodePort Type 변경

 

4.2.1. 현재 ingress-nginx-controller service type 확인

 

[명령어]

kubectl get svc -n ingress-nginx

 

현재 ingress-nginx-controller Service의 Type은 LoadBalancer 임을 확인할 수 있음

 

 

4.2.2. ingress-nginx-controller service type 변경

ingress-nginx-controller Service 의 LoadBalancer Type을 NodePort로 변경

[명령어]

kubectl -n ingress-nginx edit service/ingress-nginx-controller

상위 type 부분을 NodePort로 변경

:wq 저장 후 나감

 

 

4.2.3. ingress-nginx-controller service type 변경 결과 확인

Type이 정상적으로 변경됐음을 확인할 수 있고

80 Port 로 매칭 되는 NodePort는 31863 임을 확인할 수 있음

 

 

4.3. ingress-nginx 설정

4.3.1. 기존 ingress 삭제 후 ingress 재생성

 

삭제

 

재생성

기존의 ingress 설정과 동일하지만 host 이름만

iksoon.test2.com 으로 변경 (기존 ingress 그대로 재생성해도 됨, 그냥 구분하기 위해 변경함..)

apiVersion: extensions/v1beta1

kind: Ingress

metadata:

  name: iksoon-ingress-nginx

  namespace: default

  annotations:

    nginx.ingress.kubernetes.io/rewrite-target: /$2

spec:

  rules:

  - host: iksoon.test2.com

    http:

      paths:

      - path: /app1(/|$)(.*)

        backend:

          serviceName: iksoon-service

          servicePort: 8080

 

4.3.2. hosts 파일 설정도 추가

[명령어]

vi /etc/hosts

 

10.0.2.4 = worker Node의 IP

 

NodePort Type 이므로

Master Node or 연결된 모든 Worker Node IP로 접근이 가능

 

4.3.3. ingress 생성 확인

[명령어]

kubectl get ing

 

일정 시간이 지난 후 Address 할당받을 수 있는데

할당받은 10.104.2.255는

ingress-nginx-controller service의 Cluster ip임을 확인할 수 있음

 

4.3.4. 결과 확인

curl http://iksoon.test2.com:31863/app1/iksoon_test/iksoon_home.jsp

참고 NodePort Type 이므로

도메인 주소 옆에 NodePort의 Port 번호를 넣어줘야 정상적으로 접근할 수 있음

결과 : 정상

 

 

4.4. 해당 과정까지의 정리

 

 

 

 

 

 


제 글을 복사할 시 출처를 명시해주세요.
글에 오타, 오류가 있다면 댓글로 알려주세요! 바로 수정하겠습니다!


 

 

 

 

 

 

참고

ingress nginx 공식 문서

https://kubernetes.github.io/ingress-nginx/deploy/

 

ingress 개념 정리

https://www.joyfulbikeshedding.com/blog/2018-03-26-studying-the-kubernetes-ingress-system.html

 

private 환경에서의 ingress 

https://blog.naver.com/PostView.nhn?blogId=alice_k106&logNo=221502890249

 

ingress 동영상 설명

https://www.youtube.com/watch?v=l42GttmnnZ4

2:22:45 부분이 ingress 설명 부분

 

naver ncloud 예제 문서

https://docs.ncloud.com/ko/nks/nks-1-4.html

 

ibm cloud 문서

https://cloud.ibm.com/docs/containers?topic=containers-ingress

 

loadBalancer MatalLB

https://honggg0801.tistory.com/48

https://boying-blog.tistory.com/16

https://ssup2.github.io/record/Kubernetes_MetalLB_%EC%84%A4%EC%B9%98_Ubuntu_18.04/

https://teamsmiley.github.io/2018/12/19/kubernetes/

https://kubernetes.github.io/ingress-nginx/deploy/baremetal/

 

on-premise 환경의 ingress

https://zgundam.tistory.com/178

https://medium.com/@futuredon/kubernetes-on-prem-demo-using-gns3-kubespray-nginx-ingress-frr-and-metallb-part-2-4f11ace36c00

https://bryan.wiki/288

 

ingress annotation 설명

https://m.blog.naver.com/PostView.nhn?blogId=alice_k106&logNo=221503924911&proxyReferer=https:%2F%2Fwww.google.com%2F

 

kubernetes 네트워크 nodeport, loadbalancer, ingress 차이점 한방 정리

https://matthewpalmer.net/kubernetes-app-developer/articles/kubernetes-ingress-guide-nginx-example.html

 

nginx.ingress.kubernetes.io/rewrite-target 설정 설명 (address 뒤에 추가로 붙는경우)

https://kubernetes.github.io/ingress-nginx/examples/rewrite/

 

ingress controller 종류 모음

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

 

nginx ingress 의 annotation :

https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/

 

 

 

반응형

'클라우드 > Kubernetes' 카테고리의 다른 글

10. Kubernetes ConfigMap  (0) 2020.08.17
09. Kubernetes Volume 개념  (0) 2020.08.17
07. Kubernetes Network (LoadBalancer)  (3) 2020.08.09
06. Kubernetes Network (ClusterIP, NodePort)  (0) 2020.08.09
05. Kuberentes Network 이론  (2) 2020.08.09