Kubernetes 에서 네임스페이스 네트워크 격리 및 특정 포트 허용하기 (Calico)
Kubernetes 에서 네임스페이스 내의 Pod 끼리 통신을 허용하고 모든 외부의 접근은 차단 시킬 수 있습니다. 또한 특정 서비스 접근이 필요한 경우 포트를 허용하여 접근하게 할 수 있습니다.
아래 웹페이지 내용을 참고하여 재작성하였습니다.
- 출처 : https://www.qovery.com/blog/basic-network-isolation-in-kubernetes/
1. 애플리케이션 생성
애플리케이션을 배포하고 외부에서 접근하기 위한 네트워크 설정 예제 입니다.
애플리케이션에 도메인 연결 필요시 다른 포스팅을 참고해 주세요.
(https://sysdocu.tistory.com/1851 , '5) Ingress 생성' 부분)
1) Namespace
애플리케이션을 생성하고 배포할 작업공간을 생성합니다.
# vi namespace.yaml
apiVersion: v1 kind: Namespace metadata: name: sysdocu labels: role: sysdocu |
# kubectl apply -f namespace.yaml
2) Deployment 생성
Deployment 를 사용하면 Pod 생성 및 여러가지 옵션을 추가하여 다양한 구성이 가능합니다.
Deployment yaml 파일을 작성합니다.
# vi deployment.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment namespace: sysdocu spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 |
작성한 yaml 파일을 적용하여 생성합니다.
# kubectl apply -f deployment.yaml
3) Service 생성
네트워크 접근이 가능하도록 Service 를 생성해 줍니다.
테스트 목적이긴 하지만 외부 네트워크에서 접근이 되도록 해보겠습니다.
Service yaml 파일을 작성합니다.
# vi service.yaml
apiVersion: v1 kind: Service metadata: name: nginx namespace: sysdocu spec: selector: app: nginx type: NodePort ports: - protocol: TCP nodePort: 30080 # 외부 트래픽이 접근하는 노드의 포트 (범위 : 30000~32767) port: 80 # 클러스터 내에서 서비스가 노출되는 서비스 포트 targetPort: 80 # Pod 의 컨테이너가 리스닝하는 포트 |
* 참고
Service 에서 생성할 type 은 ClusterIP, NodePort, LoadBalancer 가 있습니다.
- ClusterIP : 클러스터 내부 통신만 가능한 IP
- NodePort : worker 노드의 IP 와 지정한 포트 (30000~32767 로 제한) 를 이용해 Pod 에 연결 가능
- LoadBalancer : 별도의 공인 IP 가 할당되고, 포트를 마음대로 사용 가능 (베어메탈 환경에서는 MetalLB 를 설치 필요)
작성한 yaml 파일을 적용하여 생성합니다.
# kubectl apply -f service.yaml
외부 네트워크에서 애플리케이션에 접근되는지 확인합니다.
접근할 IP 는 Pod 가 위치하는 worker 노드인데, 아래 명령으로 확인 가능합니다.
# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-694db9fb84-b5h2r 1/1 Running 0 7m22s 10.101.1.66 worker2 <none> <none>
worker2 노드인것을 확인하였으며, 외부에서 worker2 노드의 공인 IP 와 위에서 설정한 포트 30080 으로 접근시 nginx 초기페이지가 출력되는것이 확인됩니다. 예제에서는 worker2 노드의 공인 IP 로 연결하였지만 실제로는 꼭 worker2 노드의 공인 IP 로 할 필요는 없습니다. NodePort 의 경우 master 또는 어떤 worker 노드로 연결하던 설정한 Pod 로 연결됩니다.
# curl 115.68.142.4:30080
2. 네트워크 정책 설정
Kubernetes 는 네트워크 방화벽처럼 작동하는 네트워크 트래픽을 허용/거부할 수 있는 네트워크 정책 (NetworkPolicy) 이라는 리소스를 제공합니다. 기본적으로 이 리소스를 사용하려면 먼저 이를 구현하는 Kubernetes Networking 플러그인 (Calico) 을 추가해야 합니다. 아래 URL 을 참고하세요.
(https://sysdocu.tistory.com/1851 , '4. Calico 설치' 부분)
아래 예제에서는 sysdocu 네임스페이스를 다른 모든 네임스페이스와 분리하되, sysdocu 네임스페이스 내에 배포된 모든 Pod 가 서로 연결 할 수 있도록 구성합니다.
1) 들어오는 모든 트래픽 차단
sysdocu 네임스페이스에 들어오는 트래픽을 차단하는 것은 다음과 같습니다.
# vi drop.yaml
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: no-inbound-traffic namespace: sysdocu spec: policyTypes: - Ingress podSelector: matchLabels: {} |
policyTypes : Ingress 는 들어오는 트래픽만 선택합니다. 참고로 나가는 트래픽 제어는 Egress 으로 변경하거나 추가하면 됩니다.
podSelector/matchLabels : 내용을 비우면 네임스페이스 내의 모든 Pod 에 규칙을 적용합니다. 입력 규칙이 정의되지 않았으므로 모든 것이 차단됩니다.
# kubectl apply -f drop.yaml
2) 동일한 네임스페이스 내의 Pod 간 트래픽 허용
sysdocu 네임스페이스 내의 모든 Pod 가 서로 통신할 수 있도록 하려면 네트워크 정책 규칙을 추가합니다.
# vi same.yaml
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-same-namespace-traffic namespace: sysdocu spec: policyTypes: - Ingress podSelector: matchLabels: {} ingress: - from: - namespaceSelector: matchLabels: role: sysdocu |
# kubectl apply -f same.yaml
3) 외부에서 들어오는 특정 포트 트래픽 허용
위에서 미리 만들어 둔 웹 애플리케이션 nginx 가 Pod 에서 80 포트로 서비스 되고 있습니다. 이를 공개적으로 액세스할 수 있도록 하려면 다음과 같은 규칙을 하나 더 추가해야 합니다.
# vi allow.yaml
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-port-80 namespace: sysdocu spec: policyTypes: - Ingress podSelector: matchLabels: app: nginx ingress: - ports: - port: 80 |
# kubectl apply -f allow.yaml
주의할 것은, 노드의 포트 (30080) 가 아니고, Pod 의 포트 (80) 입니다.
이렇게 모든 Pod 를 선택하는 대신, sysdocu 네임스페이스의 레이블 app: nginx 가 있는 Pod 만 선택합니다. 그런 다음 규칙을 적용하면 누구나 웹 애플리케이션의 포트 80 번에 연결할 수 있습니다.
물론 외부에서 접근하기 때문에 NodePort 30080 으로 접근해야 합니다.
외부 네트워크 PC 에서 테스트 하는 방법입니다.
# curl 115.68.142.4:30080
4) 나가는 트래픽 모두 차단 (선택 사항)
네트워크 정책을 사용하여 트래픽이 나가는 것을 방지할 수도 있습니다.
차단 전에 테스트를 위해 telnet 패키지를 먼저 설치합니다.
Pod 이름은 먼저 확인해 주세요.
# kubectl exec -it nginx-deployment-7c79c4bf97-7wj9r -n sysdocu -- apt -y install telnet
구글 DNS 를 제외하고 모든 트래픽을 차단하는 설정입니다.
# vi drop.yaml
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: disable-outbound-traffic namespace: sysdocu spec: policyTypes: - Egress podSelector: matchLabels: {} egress: - to: - ipBlock: cidr: 8.8.8.8/32 - ipBlock: cidr: 8.8.4.4/32 ports: - protocol: UDP port: 53 - protocol: TCP port: 53 |
# kubectl apply -f allow.yaml
Pod 쉘에 로그인하여 명령을 통해 확인해보면 됩니다.
# kubectl exec -it nginx-deployment-7c79c4bf97-7wj9r -n sysdocu -- bash
# telnet 164.124.101.2 53
# telnet 8.8.8.8 53
# apt update
'리눅스 > DaaS' 카테고리의 다른 글
Proxmox 에서 Ubuntu VM 싱글모드 진입, root 패스워드 초기화 (0) | 2024.08.27 |
---|---|
Proxmox VM IP 설정 방법 (Private, NAT, VXLAN) (0) | 2024.08.06 |
Incus (LXC 리눅스 컨테이너 관리자) 설치 및 설정 (0) | 2024.08.02 |
Proxmox 에서 SDN (영역 및 VNets) 설정하여 네트워크 분리하기 (0) | 2024.07.31 |
Kubernetes Namespace 또는 Pod 의 리소스 및 볼륨 백업하기 (Velero) (0) | 2024.07.22 |