학습일지/kubernetes
Kubernetes Deep Dive - (6). Network
inspirit941
2021. 10. 2. 14:14
반응형
K8s Network
- pod끼리 통신은 어떻게 할 것인가? 에 관련된 문제들.
- Network Implementation으로 여러 종류가 있지만, kubeadm을 사용한다면 Calico가 가장 적절함.
기본적인 규칙
- 모든 pod는 Network Address Translation (NAT) 없이 다른 Pod과 통신이 가능해야 한다. (어느 node에서 동작하건 상관없이)
- IP / DNS 또는 localhost로 접근이 가능해야 함
같은 Single Cluster 내부에 있다면, 어느 노드에 있는 pod이라 해도 IP주소나 local DNS로 서로 통신이 가능하다.
CNI Plugins
- k8s의 Network Implementation을 제공하는 여러 plugin 중 하나.
- k8s 공식문서에서 cluster networking 검색하면 수많은 implementation을 찾을 수 있음.
- 설치방법은 각 implementation별로 조금씩 다름
- 네트워크 플러그인 세팅이 되어 있지 않으면 Pod의 상태는 NotReady가 되며, Pod 실행이 불가능하다.
k8s DNS
- 보통 클러스터를 생성할 때 Network 세팅도 같이 이루어지는 경우가 많고,
- k8s에서 제공하는 virtual Network는 DNS를 사용해서 pod와 Service의 통신을 지원한다.
전제조건
- k8s cluster의 Namespace중 하나인 kube-system에 아래 두 개의 Object가 있어야 한다.
- core-dns Pod
- core-dns Service
아래 두 개의 Pod를 생성한다.
apiVersion: v1
kind: Pod
metadata:
name: nginx-nodename
spec:
containers:
- name: nginx
image: nginx
---
apiVersion: v1
kind: Pod
metadata:
name: frontend-app
spec:
containers:
- name: app
image: alpine
command:
- sleep
- '3600'
kubectl get pods -o wide
로 확인한 IP주소로 요청을 시도하면, 정상적으로 nginx 서버에 요청을 보낼 수 있다.- 단, k8s에서 제공하는 DNS로는 연결할 수 없다. k8s의 DNS는 Cluster 내부에서 pod끼리 통신할 용도로 쓰이기 때문.
kubectl exec -it
로 pod에 직접 접근한 뒤 DNS에 curl로 연결을 시도하면 정상적으로 연결되는 걸 확인할 수 있다.
Network Policy & Pod Selector
![스크린샷 2021-09-17 오후 2 54 25](https://user-images.githubusercontent.com/26548454/133731658-cb620f3d-56be-4bd9-a842-7cebfac264f0.png)
- Network Policy 자체도 Object로 취급됨. 따라서 template으로 생성한다.
- pod은 크게 세 가지 규칙으로 통신할 수 있다.
- Pod 단위로 허용
- Namespace 단위로 허용
- IP Block. ip range based로 통신 범위를 규정할 수 있음
![스크린샷 2021-09-17 오후 2 55 52](https://user-images.githubusercontent.com/26548454/133731851-89183fa1-d1ff-4077-b35c-faa793ba4cfd.png)
기본적으로 pod는 non-isolated. 어느 Pod과도 통신이 가능하다.
![스크린샷 2021-09-17 오후 2 57 42](https://user-images.githubusercontent.com/26548454/133731985-05f62d80-0c32-4d93-b2d9-4b44faff42b4.png)
PodSelector
- 특정 label이 붙어 있는 pod과 통신이 가능하도록 설정.
- 예시의 경우 front-end label이 붙어 있는 Pod들은 sample-net-policy라는 이름의 NetworkPolicy의 영향을 받게 됨.
![스크린샷 2021-09-17 오후 3 00 19](https://user-images.githubusercontent.com/26548454/133732232-8cc87804-3184-4460-9f19-284d741d22c8.png)
- ingress - pod로 들어오는 트래픽
- egress - pod에서 나가는 트래픽
network policy는 기본적으로 ingress / egress에 모두 적용된다. policy를 설정할 때 ingress / egress Customize가 가능하다.
![스크린샷 2021-09-17 오후 3 02 54](https://user-images.githubusercontent.com/26548454/133732465-cb71fca3-0594-4b0b-a8c1-2c8cd830bf07.png)
- fromSelector: Ingress traffic
- toSelector: Egress traffic
![스크린샷 2021-09-17 오후 3 03 27](https://user-images.githubusercontent.com/26548454/133732512-aac03d17-de78-49b2-9a50-1f52dedba789.png)
- podSelector와 마찬가지로 namespaceSelector를 설정할 수 있다.
- ipBlock의 경우 cidr로 접근할 수 있는 ip범위를 설정한다. 예시의 경우 /16이므로 172.17.0.0 ~ 172.17.255.255 주소까지를 허용한다는 뜻.
![스크린샷 2021-09-17 오후 3 06 28](https://user-images.githubusercontent.com/26548454/133732836-2512670b-6e1f-47ce-803b-26459ad332e6.png)
Port로도 network policy를 붙일 수 있다.
- 예시의 경우 ingress는 tcp + 80 포트로 들어오는 트래픽만 허용하며, egress는 tcp + port 범위는 32000 ~ 32768까지를 허용한다.
cf. minikube의 경우 setup policy is not compatible with Network policy.
network-policy가 클러스터에 있어야 한다. 혹시 없다면
kubectl create ns network-policy
kubectl label namespace network-policy role=test-network-policy
로 namespace와 label를 설정해준다. namespace Selector를 사용하려면 label 설정이 되어 있어야 하기 때문.
![스크린샷 2021-09-17 오후 3 17 14](https://user-images.githubusercontent.com/26548454/133733860-51227c41-783d-4c05-98d5-631ed50e7768.png)
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
namespace: network-policy
labels:
app: frontend
spec:
containers:
- name: nginx
image: nginx
---
apiVersion: v1
kind: Pod
metadata:
name: busybox-pod
namespace: network-policy
labels:
app: client
spec:
containers:
- name: busybox
image: radial/busyboxplus:curl
command:
- sleep
- '3600'
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: sample-network-policy
namespace: network-policy # 어느 namespace에 적용할 것인지 설정
spec:
podSelector:
matchLabels:
app: frontend
policyTypes:
- Ingress
- Egress # 만약 여기까지만 정의하고 아래의 내용을 쓰지 않는다면, ingress / egress 트래픽 어느 것도 frontend Label이 붙은 pod에 접근할 수 없다는 뜻.
ingress: # ingressPolicy
- from:
- namespaceSelector:
matchLabels:
role: test-network-policy # namespace를 선택하기 위해서 matchLabel 사용.
ports:
- protocol: TCP
port: 80
반응형