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
ingress annotation 설명
kubernetes 네트워크 nodeport, loadbalancer, ingress 차이점 한방 정리
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 > 네트워크' 카테고리의 다른 글
Pod의 veth (Virtual Ethernet Interface) 장치 찾기 (0) | 2020.11.07 |
---|---|
Kubernetes Network Policy (0) | 2020.11.07 |
Kubernetes Network (LoadBalancer) (3) | 2020.08.09 |
Kubernetes Network (ClusterIP, NodePort) (0) | 2020.08.09 |
Kuberentes Network 이론 (2) | 2020.08.09 |