Networking
사전 지식
네크워크 기초
개념 | 설명 |
Network | 서로 연결되어 통신 할수 있는 구조 (예: A와 B를 스위치로 연결해 네트워크 구성) (예 192.168.1.0/24) |
Interface | 네트워크 인터페이스는 장비가 네트워크에 물리적 또는 가상적으로 연결되는 지점 즉 포트 (예: eth0) |
IP Address | 장비 식별자 (예: 192.168.1.10) |
Switch | 같은 네트워크 안에서 데이터 전송 (L2 장비) |
Router | 다른 네트워크와 연결, 패킷 경로 결정 (L3 장비) |
개념 | 설명 |
Gateway | 외부 네트워크(인터넷 포함)로 나가는 출구 IP |
Routing Table | 특정 네트워크로 가기 위한 경로 정의 |
Default Gateway | 모르는 목적지 IP는 이곳으로 보냄 (0.0.0.0/0) |
명령어 | ip route, ip route add, route |
네트워크가 물리적으로 연결 되어 있지만 서로 통신하지 못할때 라우팅 테이블을 설정 하면 통신 할 수 있다
라우팅 테이블은 꼭 라우터에서만 설정하는건 아니다
일반적인 리눅스 서버나 클라이언트 컴퓨터에서도 라우팅 테이블을 설정할 수 있다
라우팅 테이블은 모든 네트워크 장비에 있다
(ip 통신을 하는 모든 시스템에는 자기만의 라우팅 테이블이 존재)
네트워크 확인 명령어 (리눅스 시스템)
명령어 | 설명 |
ip link | 인터페이스 목록 확인 |
ip addr | IP 주소 확인 |
ip addr add | IP 주소 설정 |
ip route / route | 라우팅 테이블 확인 |
ip route add | 라우트 추가 |
DNS
리눅스/유닉스 계열 시스템에서 기본적으로 존재하는 네트워크 관련 설정 파일
1. /etc/hosts 파일
로컬 호스트 이름 해석 방법으로 해당 파일에 특정 IP에 이름(db 등)을 매핑 할 수 있다
이름을 사용해도 해당 파일에 설정된 ip 를 찾아서 통신이 가능하다
다만 모든 노드에 직접 설정해야 하므로 규모가 커지면 유지보수 어렵다.
우선순위: /etc/hosts > DNS 서버
2. /etc/resolv.conf 파일
DNS 서버 주소를 설정하는 곳(내가 이거의 ip는 머지? 이렇게 물어보는곳)
nameserver: 사용할 DNS 서버 IP 주소
ex: 8.8.8.8 (구글이 제공하는 공용 DNS서버) , 192.168.1.100 (이런식으로 회사 내부 자체 DNS 서버일수도 있음)
search: 기본 도메인 붙이기 설정 (ex: search mycompany.com)
ex) ping web → web.mycompany.com으로 해석됨
3. /etc/nsswitch.conf
호스트 이름 -> IP 주소로 변환할때 어디를 먼저 참고할지 해석 순서 설정 파일
ex) hosts: files dns → /etc/hosts 먼저 보고, 없으면 DNS 서버 참조 해라 라는 뜻
순서 바꾸면 DNS 우선으로도 설정 가능
DNS 레코드 타입
도메인 이름을 무언가로 변환하는데 그것에 대한 규칙
타입 | 설명 |
A | 도메인 → IPv4 주소 ex) example.com → 93.184.216.34 |
AAAA | 도메인 → IPv6 주소 ex) example.com → 2606:2800:220:1:248:1893:25c8:1946 |
CNAME | 도메인 → 다른 도메인 (alias) ex) http://www.example.com → example.com → 93.184.216.34 example.com는 별명인거고 example.com 의 A 레코드가 93.184.216.34인것 |
DNS 서버 설정 및 개념
/etc/hosts → 소규모 네트워크에 적합
DNS 서버 → 대규모 환경에서 중앙 관리용
DNS 서버가 외부 도메인 처리 못할 때 → forward 설정으로 Google DNS(8.8.8.8)로 위임 가능
도메인 네임 구성 구조
www.google.com → .(루트) → com(Top Level Domain) → google(도메인) → www(서브도메인)
내부 조직에서도 web.mycompany.com,db.mycompany.com 등 구성 가능
도메인 이름 해석 확인 명령어
명령어 | 설명 |
ping <host> | 호스트 이름이 IP로 해석되는지 간단히 확인 |
nslookup | DNS 서버에 직접 질의 (로컬 /etc/hosts 무시) |
dig | DNS 레코드 자세히 출력 |
CoreDNS
내부 호스트가 많아질수록 /etc/hosts로 관리하기 힘들어짐 -> 그래서 DNS 서버가 필요하다
CoreDNS는 경량 DNS 서버 소프트웨어로 (기본포트 53) /etc/hosts를 기반으로 동작할 수 있는 간단하고 확장 가능한 DNS 서버다.
쿠버네티스에서도 쓰이며, 플러그인 구조를 갖고 있어서 유연하게 설정 가능하다.
Network Namespace
namespace는 서로 격리된 환경을 만들기 위한 리눅스 커널의 기능이다.
컨테이너는 자신의 네임스페이스 내 리소스만 인식하고 호스트나 다른 네임스페이스는 보이지 않는다
각 컨테이너는 독립적인 네트워크 인터페이스, 라우팅등을 가진다
이더넷 페어 (veth pair)
두 네임스페이스 간 연결을 위한 가상 인터페이스
한쪽 끝은 네임스페이스에, 다른 한쪽은 호스트 또는 다른 네임스페이스에 연결
ex) ip link add veth0 type veth peer name veth1
Linux Bridge (가상 스위치)
여러 네임스페이스를 하나의 가상 네트워크로 묶기 위해 사용.
ex)
- ip link add name br0 type bridge: 브릿지 생성
- ip link set <veth> master br0: 브릿지에 인터페이스 연결
외부 네트워크 통신 (라우팅 + NAT)
1. 네임스페이스 → 외부 네트워크 통신을 위해 게이트웨이 라우팅 추가 필요.
2. 호스트에서 NAT(Masquerade) 설정 필요
외부에서 네임스페이스로 접근
외부에서 접속하려면 포트 포워딩(IPTables) 설정 필요
호스트안에 격리된 가상 공간이기 떄문
그래서 호스트가 대신 외부 요청을 받아서 네임스페이스 안의 ip/port전달이 필요하고
이걸 iptables명령어로 설정하는게 포트포워딩
Docker Networking
Docker의 네트워크 옵션
-> 이 네트워크 옵션은 컨테이너 하나하나에 적용하는 설정이다
옵션 | 설명 |
none | 네트워크 없음 (완전 격리) 컨테이너에 아무런 네트워크 설정이 되지 않은것 외부로 나갈수도 내부적으로 통신도 안됨 |
host | 컨테이너가 호스트의 네트워크를 그대로 사용한다 IP도 같고 포트도공유한다 ex) nginx가 80포트열면 호스트의 80포트도 차진한다 |
bridge (기본) | Docker 가 설치될때 자동으로 생성한 브릿지 네트워크 docker0 사용 가상 브리지 (docker0) 를 통해 컨테이너 연결 |
Docker Bridge 네트워크 구조
Docker 설치 시 자동으로 docker0 브릿지가 생성된다
컨테이너 생성 시 개별 IP 할당 , 네임스페이스, 가상 이더넷 쌍 (veth pair) 생성된다
이더넷 쌍은 한쪽은 컨테이너 네임스페이스에, 다른 한쪽은 docker0에 연결
컨테이너 간 통신
같은 브릿지 네트워크 상 컨테이너끼리는 자유롭게 통신 가능
외부에서 접근 (포트 포워딩)
컨테이너는 내부 네트워크이므로 외부 접근 불가
-p 옵션을 사용해 포트 매핑 가능:
ex) docker run -p 8080:80 nginx
host:8080으로 들어온 트래픽은 container:80으로 전달됨
내부적으로 iptables NAT (PREROUTING 체인) 규칙을 자동 생성해서 포트 포워딩 처리
Docker 네트워크
Linux 네임스페이스와 iptables의 조합
Docker는 컨테이너 별 네트워크 네임스페이스를 분리하고, veth pair + bridge 방식으로 연결
외부 접근은 iptables NAT를 통해 이루어진다
CNI (Container Network Interface)
CNI는 컨테이너 네트워킹을 위한 표준 인터페이스이다
컨테이너 런타임들이 네트워크를 연결할때 호출하는 플러그인 규약이다
컨테이너 네트워크는 네임스페이스, 가상 인터페이스, nat 등 복잡한 구성이 필요한데
여러 컨테이너 플랫 폼이 있기 때문에 표준화가 필요했었다
-> CNI가 등장하면서 일관된 플러그인 구조를 제공하게 되었다 (CNI는 네트워크 구성 작업을 처리하는 “실행 파일 집합”)
역할 이해
역할 | 책임 |
컨테이너 런타임 (ex: Kubernetes) | - 컨테이너 네트워크 네임스페이스 생성 - 어떤 네트워크 쓸지 결정 - CNI 플러그인에게 ADD, DEL 명령 전달 |
CNI 플러그인 | - IP 할당 - 가상 인터페이스 생성/연결 - NAT/라우팅 설정 등 네트워크 구성 |
(CNI는 작업을 수행해주는 도구다 , kubernetes가 명령을 내리면 CNI 플러그인이 수행을 하는것)
CNI 구성 요소
/etc/cni/net.d/*.conf 형식 JSON 설정 파일
-> 어떤 네트워크 사용하고, 어떤 플러그인 쓸지 정의
ps. Docker는 CNI를 안 쓴다 자체 표준인 CNN을 사용한다 kubernetes는 docker로 컨테이너를 만들더라도 CNI방식으로 네트워크를 구성 (docker에 --network none 옵션으로 생성후 CNI가 따로 구성)
Cluster Networking
모든 노드(마스터&워커) 는 최소 한개의 네트워크 인터페이스를 필요로하며
각 인터페이스에는 고유한 IP주소가 설정되어야한다
또한 각 노드는 고유한 호스트 명과 고유한 MAC주소를 가져야한다
필수 포트 개방 목록
구성요소 | 노드 종류 | 포트 번호 | 설명 |
Kube API Server | 마스터 | 6443 | 클러스터 모든 구성 요소가 이 포트로 API Server 접근 |
Kubelet | 마스터/워커 | 10250 | 노드 상태 수집 등 |
Scheduler | 마스터 | 10259 | 내부 통신 |
Controller Manager | 마스터 | 10257 | 내부 통신 |
etcd | 마스터 | 2379 | 클러스터 데이터 저장소 |
etcd (클러스터 간 통신) | 멀티마스터 | 2380 | etcd 간 통신 시 필요 |
NodePort 서비스 | 워커 | 30000~32767 | 외부 서비스 접근 시 사용 |
클라우드 환경 또는 방화벽/IP Tables 를 사용하는 경우 위 포트들을 반드시 열어야한다
네트워크 구성 상태 확인 명령어
- ip a : 노드의 네트워크 인터페이스 및 IP 확인 (이거로 현재 구성등 알수 있음)
- 노드가 어떤거 가지고 있는지 볼때 kubectl get node -o wide 로 ip 확인하고 저 명령어로 인터페이스 확인
- ip address show type bridge
- 어떤 bridge 쓰고있는지 나옴
- ip route show default
- 기본 라우트 설정 확인 가능
- 결과 이렇게 나왔다면 default via 169.254.1.1 dev eth0
- 목적지가 없을때 패킷을 169.254.1.1 로 보내겠다 eth0 인터페이스를 통해서
- dev는 device의미
- hostname : 호스트 이름 확인
- netstat -nplt | grep scheduler
- scheduler 가 열어둔 포트를 확인하는것
- netstat는 네트워크 상태 보여주는 명령어
- 명령어 잘 모르겠으면 netstat --help 로 확인
- ss -tuln 또는 netstat -tuln : 현재 열려있는 포트 확인
- kubectl get nodes -o wide : 노드 IP 및 정보 확인
- ip link show eth0
- 현재 node에서 mac address 확인가능
- eth0 이라는 네트워크 인터페이스의 상태를 보는것
Pod Networking
Pod 네트워크의 필요성
Kubernetes 클러스터에는 많은 Pod가 생성됨.
Pod끼리 서로 통신하고, 외부에서 서비스에 접근하려면 Pod 레벨의 네트워크 구성이 필수.
Kubernetes 자체는 네트워크 구현을 제공하지 않음 → 사용자가 구성 필요.
Kubernetes의 Pod 네트워크 요구사항
모든 Pod는 고유한 IP 주소를 가져야 함.
Pod는 동일 노드 내 다른 Pod와 IP로 직접 통신 가능해야 함.
Pod는 다른 노드의 Pod와도 IP로 직접 통신 가능해야 함.
Pod 네트워크 구성 방식
각 노드에 Bridge 네트워크를 생성 (ex: cni0 등).
각 Bridge는 서로 다른 서브넷 사용 (예: 10.244.1.0/24, 10.244.2.0/24).
Pod를 만들면 해당 브릿지 네트워크에 veth pair로 연결하고 IP 할당.
각 노드에 라우팅 테이블 구성 → 다른 노드의 Pod CIDR로 라우팅 설정.
라우팅 구성
예: Node1의 Pod가 Node2의 Pod에 접근하려면,
• Node1에서 10.244.2.0/24 → Node2의 IP (192.168.1.12)로 가는 경로를 라우팅 테이블에 추가.
--> 위와 같은 네트워크 구성 과정을 수동으로 하는건 현실적이지 않다
그래서 쿠버네티스는 CNI 플러그인을 사용한다 CNI는 pod 생성 시 자동으로 IP를 할당하고, veth연결 , 라우팅 구성까지 수행한다
개념 | 설명 |
Pod-to-Pod 통신 | 모든 Pod는 IP를 가지고 있고, 서로 직접 통신 가능해야 함 (노드 간 포함) |
Bridge 네트워크 | 노드 내부에서 Pod 간 통신을 가능하게 하는 가상 스위치 역할 |
CNI 플러그인 | Pod가 생성될 때 네트워크를 자동 구성함. (flannel, calico, cilium 등) |
NAT 없음 | Kubernetes의 Pod 간 통신은 NAT 없이 IP 기반 직접 통신이 원칙 |
라우팅 | 각 노드에 라우팅이 필요하거나, 중앙 라우터를 통해 구성할 수도 있음 |
CNI
Kubernetes, Containerd, CRI-O 같은 컨테이너 런타임들이 CNI를 호출한다
CNI랑 쿠버네티스가 연결 설정
구성요소 | 설명 |
Container Runtime | 컨테이너 생성 책임자. ex) containerd, CRI-O |
/opt/cni/bin | CNI 플러그인들이 설치된 디렉토리 (ex. bridge, flannel) |
/etc/cni/net.d/ | 어떤 플러그인을 어떻게 쓸지 정의하는 CNI 설정 파일 위치 |
plugin config 파일 | 예: 10-mynet.conf → bridge 타입 플러그인을 사용하겠다는 설정 |
동작 흐름
1, Kubernetes → containerd 등 런타임이 컨테이너 생성
2. 런타임 → CNI 플러그인 실행 (/opt/cni/bin)
3. CNI 설정 파일 (/etc/cni/net.d/) 참조하여 네트워크 구성
4. IPAM으로 Pod에 IP 할당, 브릿지 연결, 라우팅/NAT 구성
CNI 설정 파일 구조
{
"cniVersion": "0.3.1",
"name": "mynet",
"type": "bridge",
"bridge": "cni0",
"isGateway": true,
"ipMasq": true,
"ipam": {
"type": "host-local",
"subnet": "10.244.0.0/16",
"routes": [{ "dst": "0.0.0.0/0" }]
}
}
필드 | 설명 |
type | 사용할 CNI 플러그인 이름 (예: bridge, flannel) |
isGateway | 브릿지 인터페이스에 IP 할당할지 여부 |
ipMasq | 외부로 나갈 때 NAT(Masquerade) 적용 여부 |
ipam.type | IP 할당 방식 (host-local, dhcp) |
subnet | Pod에 할당할 IP 주소 대역 |
routes | 기본 라우팅 설정 (0.0.0.0/0 → 전체 외부 가능) |
CNI weave
쿠버네티스는 자체 Pod 네트워크 기능이 없기 때문에 CNI 플러그인이 필요하다
weave는 CNI 플러그인의 하나로 pod간 통신을 위한 가상 네트워크를 자동 구성해준다.
(Weave라는 브릿지 네트워크를 생성한다, pod는 docker0브릿지 외에도 이 브릿지에 연결될 수 있다)
설치
최신 설치 방법 Weave 공식 GitHub 릴리즈의 최신 YAML을 직접 가져오는 방식
kubectl apply -f https://github.com/weaveworks/weave/releases/download/v2.8.1/weave-daemonset-k8s.yaml
설치 후 kube-system 네임스페이스에 weave-net Pod가 뜨면서 Pod 간 통신이 가능해진다
설치 확인
kubectl get pods -n kube-system -o wide | grep weave
동작방식
weave는 택배 회사 처럼 동작한다
각 node마다 weave 에이전트 (pod)가 배치되고
이 에이전트들은 서로 통신하면서 전체 pod ip 정보와 위치를 공유한다
한 pod에서 다른 node의 pod로 패킷을 보내면
weave 에이전트가 캡슐화 해서 전송 이후 목적지 node의 에이전트가 디캡슐화 후
해당 pod로 전달 한다
IP라우팅
pod간 통신을 위한 경로설정은 weave가 자동으로 설정한다
복잡한 수동 routing table 설정이 없다
weave CNI IPAM
기본적으로 10.32.0.0/12 범위의 ip를 파드에 할당한다
(대략 100만개 이상)
해당 범위는 weave agent들이 자동으로 노드에 균등하게 분배 해서 관리
IP Address Management (IPAM)
CNI 플러그인은 Pod에 대한 ip 주소를 할당하는 책임을 진다
쿠버네티스는 어떻게 할당하는지 방식은 신경 쓰지 않는다 단지 중복 없이 제대로만 할당외면 된다
IPAM 동작방식
CNI 플러그인 내부에서 IP 할당 로직을 구현하거나
IPAM 전용 플러그인을 사용한다
host-local : 각 노드에서 로컬로 IP 주소 범위를 관리
dhcp: 외부 dhcp 서버를 통해 ip 할당
IPAM 설정
/etc/cni/net.d/의 CNI 설정 파일에서 ipam 섹션을 통해 설정
어떤 서브넷을 쓸지, 어떤 방식으로 할당할지를 정의한다
Service Networking
Service는 Kubernetes에서 가상 객체로 실제 프로세스나 네임스페이스가 없다
Service 생성시 --service-cluster-ip-range 범위에서 ip가 자동할당되며
kube-proxy가 iptables (또는 IPVS)를 통해 트래픽을 pod로 전달
Kube-proxy
각 노드에는 kube-proxy가 동작하는데 service가 생성/삭제 될때
iptables에 규칙을 추가하고 삭제한다
어떤 설정으로 셋팅된건지 확인
kubectl logs <kube-proxy-pod-name> -n kube-system
포트 범위 및 CIDR 설정
--service-cluster-ip-range → 서비스 IP 대역 (예: 10.96.0.0/12)
--pod-network-cidr → Pod IP 대역 (예: 10.244.0.0/16
# iptables확인
iptables -t nat -L -n -v | grep <svc-name> : iptables 룰 확인
Cluster DNS
쿠버네티스는 기본적으로 내부 DNS 서버 (CoreDNS)를 사용한다
클러스터 내 pods 와 services간의 이름 기반 통신을 지원한다
외부 DNS와는 별개로 클러스터 내부 전용 DNS 시스템이다!
Service 이름 해석
서비스 이름은 아래처럼 계층적 도메인 구조로 해석된다
<service-name>.<namespace>.svc.cluster.local
ex) web-service.apps.svc.cluster.local
- web-service: 서비스 이름
- apps: 네임스페이스
- svc: 모든 서비스가 속한 서브도메인
- cluster.local: 기본 루트 도메인 (변경 가능)
같은 namespace면 service-name만으로도 접근 가능하다
Pod DNS 레코드
기본적으로는 생성되지 않지만 명시적으로 옵션 활성화하면
pod도 dns 이름이 생성된다. pod는 이름 대신 ip주소를 변형한 이름으로 등록된다
ex) 10.244.1.5 → 10-244-1-5.default.pod.cluster.local
nslookup web-service or dig web-service : 이름 해석 확인
kubectl exec -it <pod> -- nslookup <service> : pod 내부에서 확인
CoreDNS 구성
CoreDNS는 kube-system 네임스페이스의 pod로 실행된다
구성은 Corefile( /etc/coredns)를 통해서 설정된다
관련 설정은 configMap으로 관리되어서 동적으로 수정이 가능하다
resolv.conf
Pod 내부의 /etc/resolv.conf에 아래 설정 자동 적용됨:
nameserver 10.96.0.10 (CoreDNS 서비스 IP)
Ingress
외부에서 내부 pod에 접근하기 위해서는
nodeport로 node의 고정 port를 노출 하는 방법
그리고 loadbalancer를 사용하는 방법이 있다
하지만 이렇게 사용하는경우 각각의 서비스 마다 nodeport/loadbalancer구성이 필요하고
여러 포트를 관리하는 문제와 ssl 경로 기반 라우팅을 따로 설정하는 이슈가 있다
-> 이러한 문제점을 해결해주는게 ingress
Ingress란
클러스터 내 서비스를 외부에서 접근 가능한단일 진입점(URL)으로 제공
URL 경로(path) 또는 호스트(host) 기준으로 요청 라우팅 가능하며 SSL(HTTPS) 설정도 지원
구성요소
구성 요소 | 설명 |
Ingress Controller | 실제로 트래픽을 처리하는 Nginx, Traefik 등의 L7 LoadBalancer |
Ingress Resource | 어떤 경로/호스트가 어떤 서비스로 라우팅되는지 정의한 리소스(YAML) |
ingress controller는 쿠버네티스에 기본으로 포함되어있지 않기 때문에 수동으로 설치가 필요하다
ex) nginx, istio 등등
일반적으로 deamonset 또는 deployment로 배포가 된다
필수 구성 요소
- deployment
- service
- serviceAccount + RBAC
- configMap
예시
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-example
spec:
rules:
- host: my-online-store.com
http:
paths:
- path: /wear
pathType: Prefix
backend:
service:
name: wear-service
port:
number: 80
- path: /watch
pathType: Prefix
backend:
service:
name: watch-service
port:
number: 80
Ingress의 URL Rewrite
metadata:
name: minimal-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
Ingress에서 외부 URL 경로를 내부 서비스가 이해할 수 있는 형태로 바꿔주는 기능
ex) 사용자는 /watch로 접속했지만, 내부 서비스는 /에서 동작 → 경로를 /watch → /로 바꿔줘야 함
이런 처리는 Rewrite 처리라고 하는데 내부 서비스는 루트 경로에 대해서만 응답을 주는 구조라서 그렇다고 한다
case1 : 없이 전달되는 경우
/watch → http://watch-service:8080/**watch**
url path 기존거(기존에 호출을통해 들어온 경로 없애기 위함)를 짤라내고 그 뒤에 이제 해당 서비스에 맞춰서 처리해주는거라고 보면된다
case2 : 있는경우
http://<ingress>/watch → http://<watch-service>/**
host가 있는 경우라고 해도
path: / -> 이려면 별도 rewrite 필요없음 (내부 서비스는 / 기반으로 응답을 하니까 )
path: /watch-> 이러면 호스트 있어도 서비스가 /watch로 경로를 받아서 에러난다 (서비스 경로 / 로 받을 수 있도록 설정 필요)
트래픽 분기 방식
방식 | 설명 |
Path 기반 | /wear → wear-service, /watch → watch-service |
Host 기반 | wear.my-online-store.com → wear-service |
Default Backend | 경로 미일치 시 기본 서비스로 전달 (보통 404 페이지 용) |
설정한 모든 path에 일치하는게 없다면
default-service가 처리한다
보통 마지막 faillback용도로 사용한다 (404 페이지 처리 or 잘못된 요청 안내하는데 사용)
// 구버전은 이렇게 지정하는게 있었음
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: example-ingress
spec:
backend: # 👉 default backend
serviceName: default-service
servicePort: 80
// 1.18버전 이상은 아래와같이 / 전체 경로로 했을때 가는곳을 지정
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: default-backend
spec:
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: default-service
port:
number: 80
Nginx Ingress Controller는 자체적으로 --default-backend-service 옵션을 지원한다. (컨트롤러 시작 시)
--default-backend-service=kube-system/default-http-backend 옵션 설정
kubectl get deploy ingress-nginx-controller -n ingress-nginx -o yaml | grep default (이렇게 하면 설정 볼수 있음)
Ingress namespace
ingress는 namespace-scoped이기 때문에
ingress가 바라보는 service도 같은 네임스페이스 안에 있어야지 동작한다
kubectl create ingress ingress-pay -n critical-space --rule="/pay=pay-service:8282"
-> 명령어로도 생성가능
Gateway API
Ingress의 한계를 보완한 Gateway API
Ingress의 한계
- Ingress는 단일 리소스이기 때문에 팀 간 공유가 어렵다 (멀티테넌시 부족)
- 커스텀 설정은 controller-specific annotation에 의존 (ex. NGINX, Traefik용 설정 따로)
- L7 HTTP 트래픽만 지원. TCP/UDP, gRPC 등은 미지원
- 설정이 분산되고 불투명하다 → 유지보수 어려움
Gateway API의 등장
Kubernetes의 Ingress + 서비스 메시 + L4/L7 로드밸런싱을 통합한 차세대 네트워크 API
HTTPS 적용, 트래픽 분할(weight 설정가능), 헤더 조작, gRPC 지원,
카나리 배포, cors 등 설정도 가능
명확한 역할 분리
- GatewayClass: 인프라 관리자가 설정 (어떤 컨트롤러/로드밸런서를 쓸지)
- Gateway: 클러스터 운영자가 설정 (실제 Gateway 인스턴스)
- HTTPRoute, TCPRoute: 개발자가 설정 (어떤 경로로 어떤 서비스에 보낼지)
예시
## 1. GatewayClass 정의
## - 클러스터 전체에 적용되는 "게이트웨이 종류"
## - 어떤 컨트롤러(예: NGINX, Istio, Traefik 등)를 사용할지 지정
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: example-class ## 이 이름을 Gateway에서 참조함
spec:
controllerName: my-gateway-controller.example.com ## 설치된 Gateway 컨트롤러 이름과 일치해야 함
## 2. Gateway 정의
## 수신을 필터링 하는 역할이라고 보면 된다
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: example-gateway
namespace: default
spec:
gatewayClassName: example-class ## 위에서 정의한 GatewayClass 참조
listeners:
- name: http
protocol: HTTP
port: 80
hostname: "my-online-store.com" ## 수신할 호스트명
allowedRoutes:
namespaces:
from: Same ## 같은 네임스페이스의 HTTPRoute만 허용
## 3. HTTPRoute 정의
## - 트래픽 라우팅 규칙을 정의하는 부분
## - 어떤 경로로 들어온 요청을 어떤 백엔드 서비스로 보낼지 결정
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: example-httproute
spec:
parentRefs:
- name: example-gateway ## 어떤 Gateway에 붙을지 지정
hostnames:
- "my-online-store.com" ## 이 요청의 Host 헤더가 일치해야 적용됨
rules:
- matches:
- path:
type: PathPrefix
value: /login ## /login으로 시작하는 요청이 이 룰에 매칭됨
backendRefs:
- name: login-service ## 라우팅될 백엔드 서비스 이름
port: 8080 ## 해당 서비스의 포트
추가 장점
하나의 ALB(Gateway)로 여러 네임스페이스를 분리해서 관리할 수 있고, 각 팀이 독립적으로 라우팅 설정을 할 수 있게 해준다
역할 | 리소스 | 설명 |
인프라 운영자 | GatewayClass, Gateway | ALB 같은 외부 리소스를 하나만 설정 |
애플리케이션 팀 | HTTPRoute | 각 팀이 본인 네임스페이스에서 라우팅 설정 가능 |
# 해당설정을 해두면 다른 네임스페이스에 있는 HTTPRoute들도 이 gateway에 붙을 수 있다
allowedRoutes:
namespaces:
from: All # 또는 Same, Selector 등
실습 정리
## 네트워크 실습 정리
1. ps -aux | grep kubelet | grep --color container-runtime-endpoint
설명
ps -aux : 시스템에서 모든 사용자의 실행중인 프로세스 목록을 보여준다
--color : 뒤에 나와있는 단어 포함된 부분 강조하여서 필터링
--container-runtime-endpoint는
kubelet이 어떤 컨테이너 런타임(containerd, CRI-O등) 과 통신할지 지정하는 엔드포인트 주소
2. CNI binaries는 기본적으로 아래의 위치에 존재한다
/opt/cni/bin
3. ls /etc/cni/net.d/ 명령어를 사용하면 현재 사용중인 cni 플러그인을 알 수 있다
4. ip 주소 범위 보기
ip addr show weave <- weave의 주소 범위 특정해서 볼수있음 ip addr은 전체
(다른 방법은 weave agent에서 log봐도 범위나옴, pod의 ip범윙임)
5. 특정노드에서 gateway 보는거
ssh 로 해당 노드 들어가서 ip route
6. cluster의 ip range 보기
cat /etc/kubernetes/manifests/kube-apiserver.yaml | grep service-cluster-ip-range
서비스의 ip 범위 알아보는 명령어인것 위에가
7. kube-proxy의 설정 확인
kubectl logs <kube-proxy-pod-name> -n kube-system 로 로그확인