kubenet : 노드에 대한 pod ip가 물리적으로 private ip를 갖지 않는다.

NATing 되어서 별도의 네트워크를 가지고 있다고 생각하면 된다.

https://docs.microsoft.com/ko-kr/azure/aks/configure-kubenet

그래서 각각의 pod끼리 통신을 하거나, Azure 네트워크 내에서 통신, 혹은 외부 인터넷과 통신을 할 때

노드의 NAT 테이블을 통해 라우팅 되어서 통신을 하게 된다.

 

kubenet의 제한 사항 & 고려 사항

  • Kubenet 디자인에는 추가 홉이 필요하며 이는 Pod 통신에 약간의 대기 시간을 추가합니다.
  • kubenet을 사용하려면 경로 테이블 및 사용자 정의 경로가 필요하며 이는 작업에 복잡성을 더합니다.
  • Kubenet 디자인으로 인해 kubenet에 직접 Pod 주소 지정은 지원되지 않습니다.ㄴ 따라서 통신을 할 때는 로드 밸런서를 통하거나 노드를 통해서 통신이 된다.
  • Azure CNI 클러스터와 달리 여러 kubenet 클러스터는 서브넷을 공유할 수 없습니다.ㄴ Peering이 불가능해서 Azure의 다른 서비스와 통신하는 것이 쉽지 않다.
  • AKS는 서브넷에 NSG(네트워크 보안 그룹)를 적용하지 않으며 해당 서브넷과 연결된 NSG를 수정하지 않습니다. 고유한 서브넷을 제공하고 해당 서브넷과 연결된 NSG를 추가하는 경우 NSG의 보안 규칙이 노드와 Pod CIDR 간의 트래픽을 허용하는지 확인해야 합니다. 자세한 내용은 네트워크 보안 그룹을 참조하세요.
  • kubenet에서 지원되지 않는 기능은 다음과 같습니다.

https://docs.microsoft.com/ko-kr/azure/aks/configure-kubenet

그러면 kubenet이 왜 필요해?

그냥 Azure CNI 쓰면 되는거 아니야?

 

Azure CNI의 단점

: IP가 상당히 많이 필요하다. IP를 미리 만들어서 pre-allocate하는 구조로 되어 있기 때문에, 

엔터프라이즈를 운영하거나 서비스를 운영할 때 IP 대역대의 여유가 많지 않으면 kubenet을 사용하는게 훨씬 좋을 수 있다.

Azure CNI는 IP가 여유로울 때 사용하는 것이 좋다.

 

 

Azure CNI

대개 Azure CNI를 사용한다. kubenet은 개발할 때나 다른 서비스와 커뮤니케이션하는 일이 적을 때 많이 사용한다.

Azure CNI는 좀 더 복잡하다. 대신 Peering이 가능하고, On-Prem 환경과 커뮤니케이션도 가능하다.

 

Azure CNI는 설정해야하는 부분이 5가지가 더 늘어난다.

 

Virtual Network : pod가 실질적으로 사용하고 있는 네트워크 구간. Node처럼 Pod도 ip가 있고, 각각 ip대로 동작한다.

그래서 Azure CNI를 사용하면 IP를 많이 사용하는 것이고, 그래서 다른 애플리케이션과 통신을 할 수 있다.

 

구버전에서는 클러스터 서브넷이 있어서 node 1에는 1서브넷, node 2에는 2서브넷 이렇게 ip 대역 정할 수 있었는데 없어졌다.

 

Kubernetes service address range : 쿠버네티스 안에는 서비스가 있고, 서비스는 파드를 매핑해주는 역할을 한다.

이건 논리적인 layer라서 Azure상에서 확인이 불가능하다.

 

Docker Bridge address : 쿠버네티스는 기본적으로 도커를 사용하기 때문에, 도커의 브릿지 주소를 설정해줘야 한다.

 

address space와 subnet을 할당해보자

 이렇게 IP 주소 범위를 제한하는 것이 좋다.

 

그리고 LB의 경우 default로 Kubernetes cluster를 만들면 Standard LB가 만들어지고

Basic이나 다른 종류의 LB를 만들고 싶으면 CLI로 만들 수 있다

 

그리고 Private Cluster를 사용하고 싶으면, 프라이빗 클러스터 사용 메뉴 체크한다.

그럼 Control Plane조차 public ip를 통해서 접근하는 것이 아니라, private ip를 통해서 접근하게 되어 보안이 강화된다.

설령 Private cluster를 사용하지 않는다고 하더라도, Authorized IP 설정을 통해 인가된 사용자만 API 서버에 접근하도록 만들 수 있다.

 

Network Policy는 없음/Calico/Azure 셋 중 하나 사용할 수 있다.

 

---

첫 번째 리소스를 확인해보자

 

새롭게 만들어진 k8s RG를 들어가보면, Kubernetes Cluster와 vNet 이렇게 2가지가 있다.

AKS 클러스터 만들 때 vNet 같이 만들었기 때문에 같은 RG에 있다.

만약 vNet을 따로 떼서 설정하고 싶으면, 일단 vNet을 따로 떼서 다른 리소스 그룹에 집어넣고

CLI 명령어를 통해서 Integration이 되는 vNet을 설정해서 사용이 가능하다.

 

중요한 점은 vNet을 설정해서 사용할 때, 아무래도 같은 리소스 그룹이 아니라 다른 리소스 그룹에 있는 것이기 때문에

다른 리소스 그룹에 있는 리소스에 엑세스, Read, Write 할 수 있는 권한을 줘야한다.

 

주의) vNet이 다른 리소스 그룹에 있다면, AKS 클러스터가 접근할 수 있도록 Contributor에 해당하는 role mapping을 해줘야 한다.

 

vNet의 Connected Devices를 들어가보면 ip가 엄청나게 많이 할당되어있어.

 

뭐지? 나는 아무것도 안했는데??

 

한 노드에 최대 생성 가능한 Pod의 수를 10-250까지 정할 수 있었잖아.

default는 110개로 정해져있었지. (Compute 심화 게시글 참조)

노드마다 110개의 IP를 이미 만들어둔거야.

 

그래서 Node가 아직 Pod를 사용하지 않는다고 하더라도 많은 ip가 이미 생성되어 있는거지.

 

글고 생각해보면 노드에도 ip가 할당되잖아.

만약 노드가 3개라고 하면 ip도 3개가 만들어졌겠지?

 

10.240.0.0, 1,2,3에 해당하는 부분은 AKS의 Control Plane이나 Gateway에서 사용하고 있고

10.240.0.4에 해당하는 첫 번째 노드가 VM1에 해당하고

5부터 114까지가 pod의 IP가 되는거야. (110개)

그리고 115가 VM2에 해당하는 두 번째 노드, 116~225까지가 pod의 IP (110개)

 

즉, 10.X.0.4부터 노드 IP, Pod IP, 노드 IP, Pod IP 번갈아가면서 나오게 되어있다.

 

그럼 만약에 Pod의 IP가 10.240.0.8이다? -> 어느 노드에 있는지 알 수 있다. (VM1)

-> 다시 말해서, Pod의 IP만 보고도 어느 VM에 만들어져있는지 파악이 가능하다.


그래서 서브넷을 결정하고 AKS 클러스터의 vNet을 할당하는게 상당히 중요하다.

 

 

이번에는 두 번째 리소스를 확인해보자.

 

MC-xxx RG에 들어가보면

크게 VMSS, LB (default로 하나가 만들어진다.), NSG, PIP가 만들어져 있다.

 

nsg에 들어가보면 기본적인 rule들이 있고

 

network interfaces를 보면

각 노드의 PIP를 알 수 있다. 그리고 아까 예측한 값과 똑같다.

 

잘 보면 PIP가 하나 있다. 이건 LB에 붙어있는 공용 IP임.

 

왜 우리가 따로 설정 하지도 않았는데 pip가 붙어있는거야?

이건 outbound rule이다.

그러니까... aks 내부에서 repository에서 image를 가져오려면 외부와 통신을 해야 하잖아?

그때 필요해서 자동으로 달려있는거야.

 

 

의문) NodePort나 LB처럼 서비스가 없어도 내부에서 외부로 통신이 가능한가?

외부에서 내부로 통신은 당연히 불가능할거같은데 라고 하기에는 생각해보니까

Pod과 Node에도 각각 IP가 생기잖아? 그럼 통신 되는거 아니야?

직접 통신하면?

결국 NodePort나 LB가 로드밸런싱을 위한거라고 생각하면, 서비스와 상관없이 통신 될 것 같은데?

 

지금 서비스 설치 안하고, Azure CNI만 설정한 순정 상태다.

이때 외부와 통신이 잘 된다.

생각해보니까 aks를 설치하면 default로 lb가 깔리잖아.

 

잠깐..

그런데 온프렘 k8s에서 서비스 모두 삭제 했는데도 클러스터 내부 pod에서 외부로 ping이 가.

뭐지? (참고. aks에서는 ping 안간다. 단 인터넷은 됨.. ㅋㅋ)

 

책을 보니까, 서비스는 그냥 pod이 자꾸 생성되고 삭제되니까 그걸 label로 select 해서

변하지 않는 고정 ip로 연결해주는 것. 그 이상도 그 이하도 아니다.

방화벽의 느낌도 아니고, 그냥 애초에 pod은 host가 인터넷에 연결되어있으면 자유롭게 통신 가능.

(= 잠깐,,, default 말고 다른 ns에 lb 만들어진거 아냐? 라고 생각했는데 아니었어.

확인해봤는데 없어!)

 

기본적으로 트래픽이 클러스터 내부에서 외부로 가는건 가능해.

그런데~ 외부에서 클러스터 내부의 pod으로 트래픽을 보내는건 불가능해.

왜? 네트워크 대역이 달라.

 

클러스터 내부에서 외부로 갈 때는 가상 스위치/라우터들이 알아서 스위칭/라우팅 해주는데

외부에서 내부로 들어올 때는 그게 자동으로 안되지.

그래서 서비스를 통해서 셀렉터로 label 맵핑을 해주잖아.

 

진짜 로컬 pc의 ip 대역은 172.30.3.34/255.255.252.0인데 

Control Plane의 ip 대역은 10.0.2.15, 192.168.56.11, 192.168.134.0이야.

네트워크 대역이 다른데 어떻게 통신이 되는거지?

먼가 라우터가 역할을 해줘야할 것 같다.

-> 아마 kube-proxy가 iptables를 이용해 routing을 해주지 않을까 싶음

pod 내부에서 파일을 받을 때는 정상적으로 되는건 내부에서 외부로 나갈 때 iptables에 라우팅 path가 적히고

외부에서 들어올 때도 그거 보고 그대로 들어오는게 아닌가 싶음.그런데 완전히 생짜로 외부에서 내부로 들어오려면, 그런 routing path가 기록이 안되어있으니까 그냥 막히는거지.그래서 그럴 때는 대신 routing을 해줄 수 있게 서비스(lb 등)를 타고 들어노는거고.(확인 필요)

 

 

aks 상의 pod 내부에서 외부로 ping이 안가는 것이 확인된다.

 

---

이번엔 LB에 대해서 자세히 보자.

 

Backend pools에는 이미 들어가있지만, Load balancing rules나 Health probes에는 아무 것도 안들어가있다.

이 상황에서 서비스 타입 하나 만들었을 때 LB가 어떻게 변화하는지 지켜보자

 

질문)

Backend pool에 aksOutboundPool은 그래 뭐 바깥으로 나갈 때 쓰는거 알겠어

이건 aksOutboundRule 말하는거였네 --

근데 kubernetes는 또 뭐야?

잠깐... 원래 만들어져있는 LB는 kubernetes거든. 근데 aksOutboundPool은 모지..

 

아~ 이해 했다.

그냥 여러 백앤드 풀에 동일한 vmss를 넣어둔거네.

그리고 이 백앤드 풀마다 load balancing rules, inbound NAt rules, outbound rules 정할 수 있나봐

 

질문) 그럼 만약에 두 백앤드 풀에 상충되는 rule을 걸어두면 어떻게 되는거야?

 

 

pending이니까 뭘 하나 보려고 describe를 했어

LB에 ensuring이라는걸 했고
External IP가 생겼어

 

프론트엔드에 20.124.50.145의 아이피가 새로 생겼지. 

 

참고)

AKS에 생기는 모든 물리적 자원은 MC 내에 생긴다.

 

LoadBalancer를 만드니까 MC RG내에 아래와 같은 pip가 생겼어

ㄴ 이게 20.124.50.145임

 

 

pip가 어떤식으로 동작하고 있는지 연결되어있는 LB에서 확인을 해보자.

이건 원래 있었던 프론트엔드 ip임. outbound rule이 연결되어있어.
TCP 80이다. 왜? expose port를 80으로 했으니까...래. 얘가 80에 해당하는 inbound rule을 하나 만들어준거래. 아~~~ 그럼 이건 inbound rule이고 위에 있는건 outbound rule인가보다!!!!!!

 

질문)

온프렘에서는 기본적으로 서비스가 안만들어지는데, 왜 aks는 내가 만들지도 않았는데 하나가 만들어져?

안 만들어져. 

이제 이해갔다.

이해가긴 뭐가 이해가.. 처음부터 만들어지는게 맞는데.

원래 이렇게 kubernetes라는 서비스가 만들어져있어. 이건 ClusterIP야. 

이건 아마 내부적으로 apiserver를 위해 필요한건가봐 정확하겐 모르겠지만.

(= 이건 aks 말고 온프렘에서도 원래부터 존재하는거야!)

 

맨처음에 OutBoundRule이 그냥 기본적으로 있는거야.

이걸 들어가보면

내가 생각하는 NSG 개념의 rule이 아닌데? 

https://docs.microsoft.com/ko-kr/azure/aks/load-balancer-standard

 

aksOutboundRule : 

NSG rule이 아니고, 워커 노드의 갯수에 따라 사용할 수 있는 포트의 수를 정해주기 위한거다.

64,000 ports per IP / <outbound ports per node> * <number of outbound IPs> = <maximum number of nodes in the cluster>

 

자동으로도 되고, 수동으로도 되고

이런 방식으로.

 

그래서 새로 생긴 LB의 속성을 보면

Azure의 LB를 직접 만들지 않았음에도 불구하고 LB가 만들어졌다. 라고 azure 엔지니어가 말했는데 본인이 만든거같음 -ㅅ-

kubectl expose deploy nginx --type=LoadBalancer --port 80

이거 온프렘에서 치니까 LB 만들어지더라고?

 

어쨌든,, 엔지니어 왈:

애져 쿠버네티스 리소스 그룹 안에 있는 LB, NSG, 혹은 기타 정보들을 수동으로 설정해서 진행하려는 부분이 있는데

(애져 포탈에서 수동으로 만드는거 말하는듯. NSG를 수동으로 만들어서 붙인다든가..)

이건 지양해야 한다. 나중에 이슈가 있거나 문제가 있을 수 있음.

yaml 파일을 통해서 만들든 아니면 Azure CLI를 통해서 만들어야됨.

 

참고)

 

 

Azure의 Internal LB를 만들 때는, 별도의 internal LB를 만드는게 아니라 annotations을 true로 해주면 된대.

잠깐... 근데 온프렘 쿠버네티스에는 internal LB가 없는거같은데? 클라우드에서만 있는거같음???

이거 혹시 클러스터를 Private하게 쓸 때 필요한건가?

 

External-IP가 10 대역으로 잡혔어

Internal LB가 생긴걸 알 수 있어.

 

internal LB의 ip가 10.240.0.226이잖아?

 

 

MC말고 test-aks-rg 들어가면 vnet이 있는데

 

ip 대역을 확인해보면 10.0.0.0/8대역으로 internal LB가 포함돼.

그러니까 이 vnet안에서만 private하게 운영하고 싶을 때 쓰는거네 internal LB는...!

 

필수적으로 명심!!!

 

모든 리소스에 대한 configure은 Azure Portal에서 수동으로 하는게 아니라 (nsg 만들거나 vmss만드는 등 직접 건드리는건 전혀 없는거야!)

yaml 혹은 AZ 명령 혹은 kubectl을 통해서 진행한다!

 

kubectl delete -f int-lb.yaml

kubectl delete svc nginx 하니까 다 삭제됐다.

짜잔.

 

그래서 결국 aksOutboundRule의 ip(52.226.201.229)만 남았어.

 

잠깐만....

그럼 이 말인 즉슨, 클러스터 내부로 들어갈 때의 ip와 클러스터 외부로 나올 때의 ip가 다르다는 소리야?

다르네!! 왜 다르지??????

굳이 왜 나눠놨을까????

 

추정상 한 ip에서 가능한 port 갯수가 한정되어 있어서 그런 것 같은데..

inbound/outbound ip를 나눠놓지 않으면, 포트를 절반씩 나눠서 써야되잖아. inbound traffic이랑 outbound traffic이랑..

 

일반적인 공유기의 SNAT를 생각해보면 외부에서 내부로 들어올 때는 포트가 필요하지만

내부에서 외부로 나갈 때는 포트가 필요 없단 말이지?

근데 얘는 왜 필요할까? 왜 밖으로 나갈 때조차 포트로 구분을 해야하지?

아니다 잘못 생각했다.

외부로 나갈 때도 당연히 port가 필요하지. random으로 os가 할당하는거라 내가 신경을 안쓸 뿐이지.

 

오개념)

SNAT : 내부 -> 외부

DNAT : 외부 -> 내부

 

aks는 클러스터다보니까 수천 수만 대의 pod을 동시에 운영할 수도 있는거고

걔네가 동시에 클러스터 외부에 있는 서버에 접속하면 아웃 바운드의 port가 고갈될 수 있는거야

그리고 한 클러스터마다 클러스터에 할당되는 port의 갯수가 정해져있나봐.

예를 들어서 outbound public ip가 하나야. 그러면 한 노드당 포트를 1024개 쓸 수 있어 (왜그런진 모르겠는데 노드 48개 있으면 각 노드당 1024포트 갖는다고 예시가 들어져있음)

 

그런데 노드가 늘어나면 쓸 수 있는 포트는 더 줄어드는거야. 나눠쓰는거니까.

 

생각보다 port와 ip를 충분하게 갖는게 엄청 중요한가봐. 빅 클러스터일 경우에는.

surge node (갑자기 노드의 갯수가 치솟는 것)을 대비해서 충분한 outbound port capacity를 가지라네.

 

네트워크 부분이 aks에서 제일 중요하다고 하심!

https://www.youtube.com/watch?v=7PoJMbwOr-0 

 

  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기