공부하고 기록하는, 경제학과 출신 개발자의 노트

학습일지/kubernetes

Kubernetes Deep Dive - (6). Network

inspirit941 2021. 10. 2. 14:14
반응형

K8s Network

스크린샷 2021-09-15 오전 10 18 14

  • pod끼리 통신은 어떻게 할 것인가? 에 관련된 문제들.
  • Network Implementation으로 여러 종류가 있지만, kubeadm을 사용한다면 Calico가 가장 적절함.

스크린샷 2021-09-15 오전 10 21 17

기본적인 규칙

  • 모든 pod는 Network Address Translation (NAT) 없이 다른 Pod과 통신이 가능해야 한다. (어느 node에서 동작하건 상관없이)
  • IP / DNS 또는 localhost로 접근이 가능해야 함

스크린샷 2021-09-15 오전 10 22 40

같은 Single Cluster 내부에 있다면, 어느 노드에 있는 pod이라 해도 IP주소나 local DNS로 서로 통신이 가능하다.

CNI Plugins

스크린샷 2021-09-15 오전 10 44 13

  • k8s의 Network Implementation을 제공하는 여러 plugin 중 하나.
  • k8s 공식문서에서 cluster networking 검색하면 수많은 implementation을 찾을 수 있음.

스크린샷 2021-09-15 오전 10 49 16

스크린샷 2021-09-15 오전 10 49 37

  • 설치방법은 각 implementation별로 조금씩 다름
  • 네트워크 플러그인 세팅이 되어 있지 않으면 Pod의 상태는 NotReady가 되며, Pod 실행이 불가능하다.

k8s DNS

스크린샷 2021-09-15 오전 10 53 22

스크린샷 2021-09-15 오전 10 53 45

  • 보통 클러스터를 생성할 때 Network 세팅도 같이 이루어지는 경우가 많고,
  • k8s에서 제공하는 virtual Network는 DNS를 사용해서 pod와 Service의 통신을 지원한다.

스크린샷 2021-09-15 오후 8 44 27

전제조건

  • 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'

스크린샷 2021-09-15 오후 8 48 19

  • kubectl get pods -o wide 로 확인한 IP주소로 요청을 시도하면, 정상적으로 nginx 서버에 요청을 보낼 수 있다.
  • 단, k8s에서 제공하는 DNS로는 연결할 수 없다. k8s의 DNS는 Cluster 내부에서 pod끼리 통신할 용도로 쓰이기 때문.

스크린샷 2021-09-15 오후 8 49 15

kubectl exec -it로 pod에 직접 접근한 뒤 DNS에 curl로 연결을 시도하면 정상적으로 연결되는 걸 확인할 수 있다.

Network Policy & Pod Selector

스크린샷 2021-09-17 오후 2 54 25
  • Network Policy 자체도 Object로 취급됨. 따라서 template으로 생성한다.
  • pod은 크게 세 가지 규칙으로 통신할 수 있다.
    • Pod 단위로 허용
    • Namespace 단위로 허용
    • IP Block. ip range based로 통신 범위를 규정할 수 있음
스크린샷 2021-09-17 오후 2 55 52

기본적으로 pod는 non-isolated. 어느 Pod과도 통신이 가능하다.

스크린샷 2021-09-17 오후 2 57 42

PodSelector

  • 특정 label이 붙어 있는 pod과 통신이 가능하도록 설정.
  • 예시의 경우 front-end label이 붙어 있는 Pod들은 sample-net-policy라는 이름의 NetworkPolicy의 영향을 받게 됨.
스크린샷 2021-09-17 오후 3 00 19
  • ingress - pod로 들어오는 트래픽
  • egress - pod에서 나가는 트래픽

network policy는 기본적으로 ingress / egress에 모두 적용된다. policy를 설정할 때 ingress / egress Customize가 가능하다.

스크린샷 2021-09-17 오후 3 02 54
  • fromSelector: Ingress traffic
  • toSelector: Egress traffic
스크린샷 2021-09-17 오후 3 03 27
  • podSelector와 마찬가지로 namespaceSelector를 설정할 수 있다.
  • ipBlock의 경우 cidr로 접근할 수 있는 ip범위를 설정한다. 예시의 경우 /16이므로 172.17.0.0 ~ 172.17.255.255 주소까지를 허용한다는 뜻.
스크린샷 2021-09-17 오후 3 06 28

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
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
반응형