1. Ingress
Ingress 란
기본적으로 ingress라는 용어는 네트워크에서 나왔다
네트워크 트래픽에서 외부에서 내부로 들어오는 트래픽을 Ingress, 반대는 egress 라고 한다
쿠버네티스에서의 Ingress 는 외부로부터 접근을 관리하는 API 오브젝트이다
즉, URL을 통해 HTTP 접근 경로를 만들어서 외부 트래픽이 내부의 어디에 도달할 수 있는지에 대해 정의한 규칙 모음이다
추가 : 서비스(Service)
파드들은 각각 클러스터 안에서 새로운 IP를 발급 받고 관리를 하게 된다. 그러나 쿠버네티스에서 파드들은 하나의 노드(마스터, 워크)에 고정으로 존재하지 않고 다른 노드로 옮겨지거나 삭제 될 수 있다
이렇게 변화가 있을 때마다 파드의 IP주소가 변경되기 때문에 파드 간의 통신이나, 다른 노드 또는 외부와 통신을 할 때 파드의 IP 주소를 사용하면 관리가 힘들다
그래서 이러한 통신을 원활하게 할 수 있도록 클러스터 내부에서 고정적인 IP 를 가지는 서비스(Service)를 이용한다
이 서비스(Service)는 파드가 다른 것들과 통신하기 위해 꼭 거쳐야 하는 곳이 되면서 IP 주소의 관리도 원활하게 할 수 있다
- 서비스(Service) 유형 : 노출의 범위에 따라 분류
- ClusterIP : 클러스터 내부에서만 접근 가능한 IP
- NodePort : port 번호를 통해 외부에서 접근
- LoadBalancer : 외부의 Load Balancer 사용
- ExternalName : kube-dns 컴포넌트로 DNS를 이용
더 자세한 내용은 아래의 링크를 참조
https://bumday.tistory.com/165
K8S에서의 Ingress
K8S의 Ingress는 Service의 기능( 네트워크 통신)의 기능을 지원할 뿐만 아니라 아래의 기능도 제공한다
- 하나의 클러스터에 복수의 도메인을 연결하는 가상 호스팅
- 클러스터에 접근하는 트래픽을 URL 별로 서로 다른 서비스에 로드밸런싱
- 클러스터 내에서 구동되는 리소스에 접근할 수 있는 외부 URL을 제공
- HTTPS사용을 위한 SSL 인증서 로직 처리
2. K8S 에서의 통신
K8S에서의 네트워크 통신 종류
내부 pod를 이용한 통신
- 같은 pod 내에서 컨테이너들의 통신
- 서로 다른 pod 에 있는 컨테이너들의 통신
- 내부 pod에서 외부로 통신
spring boot를 이용한 통신(Ingress)
- Service를 이용한 애플리케이션(spring boot) 들의 통신
- Service(ClusterIP, ExternalName) 객체로 서비스명으로 통신 가능
3. K8S 에서의 내부 pod를 이용한 통신
3-1. 같은 pod 내에서 컨테이너들의 통신
환경 : multi container를 설정하여 pod 내의 두 conatiner가 통신 가능한지 확인
container : curl container, nginx container
통신 : curl → nginx
- 설정 파일
apiVersion: v1
kind: Pod
metadata:
name: my-localhost-pod
spec:
containers:
- name: nginx-container
image: nginx
- name: curl-container
image: curlimages/curl
command: ["sh", "-c", "sleep 180"]
spec.containers: 두 개의 컨테이너 생성(curl, nginx)
-name(curl-container),command:
curl은 nginx 처럼 프로세스로 계속 실행되는 것이 아니기에 시작하자 마자 종료가 될 수 있다
그러므로 바로 종료 되어 container가 exited 가 되는 것을 방지하기 위해 sleep을 설정하며 일시 중시 시켜 명령어를 받을 수 있도록 설정한다
- 실행
- pod 설치
kubectl apply -f ex1_my_localhost_pod.yaml
kubectl describe pod my-localhost-pod
⇒ describe 의 결과 중 contianers 부분 발췌
컨테이너 통신
통신을 위한 화면이 없기 때문에 CLI 로 통신(curl → nginx)
kubectl exec my-localhost-pod -c curl-container -- curl localhost:80
- -c : 어떤 컨테이너에 대해 명령을 수행할 것인지 지정하기 위한 옵션
- curl-container : 명령을 수행할 컨테이너
- — : 이후에 실행할 명령어들
중요!! : 두 컨테이너(curl, nginx)가 서로 통신 할 수 있는 이유는?
curl-container
가nginx-container
를 어떻게 인지하는가?
같은 pod안에 있는 컨테이너들은 localhost로 서로 통신이 가능하다kubernetes에서 같은 pod 내 컨테이너들은 네트워크 네임스페이스(컨테이너 이름으로 서로의 IP 주소를 알 수 있는 것) 를 공유하기 때문에 서로를 localhost로 접근 할 수 있다
포트 번호가 80번인 이유
nginx
웹 서버는 기본적으로 80번 포트를 사용한다 HTTP 프로토콜의 기본 포트가 80번이기에 별도로 포트를 지정하지 않는 한, nginx는 자동으로 80번 포트를 열고 HTTP 요청을 처리한다만약,
nginx
가 다른 포트에서 실행 중이라면, 그 포트를 지정해 줘야 하지만, 특별히 설정하지 않는 한, 80번 포트에서 작동한다
위의 명령어의 의미
Pod 내 컨테이너들은 네트워크 네임스페이스를 공유하고 있다. 이런 환경에서
curl-container
에서localhost:80
에curl
명령을 실행하는 것이고,localhost
는 동일한 Pod 내의 모든 컨테이너들을 가리키기 때문에, 사실nginx-container
가 해당 포트(80)를 열고 있으면curl
명령이 자연스럽게 연결이 되는 것이다
3-2. 서로 다른 pod 에 있는 컨테이너들의 통신
K8S 클러스터 내부에 서로 다른 IP로 할당된 상태 : 서로 다른 pod에 있는 컨테이너
설정 환경
Deployment (ReplicaSet)을 이용하여 pod1(nginx-container1), pod2(nginx-container2) 생성
Service( ClusterIP ) 를 이용하여 클러스터 내부에서만 접근 가능 IP를 할당하여 외부 pod에서 내부로 통신하도록 설정
구조
[Client (curl)] | | curl my-service:9080 | [Service (ClusterIP) - my-service] | | 로드 밸런싱 (Round Robin or Random) | ------------------------- | | | [Pod 1] [Pod 2] [Pod 3] (nginx) (nginx) (nginx) 80번 80번 80번 포트 포트 포트
설정 파일
Deployment
apiVersion: apps/v1 kind: Deployment metadata: name: my-nginx-deploy spec: replicas: 3 selector: matchLabels: app: my-nginx template: metadata: labels: app: my-nginx spec: containers: - name: nginx image: nginx
- ReplicaSet을 3으로 설정하여 nginx pod 가 3개가 생성되도록 설정
- Service ( ClusterIP )
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: ClusterIP
selector:
app: my-nginx
ports:
- protocol: TCP
port: 9080
targetPort: 80
metadata.name : 외부에서 이 서비스를 호출 하는 기준 (현재 코드는 my-service 라고 호출)
spec
type: ClusterIP : ClusterIP 는 default 로 생략이 가능하지만 명시적으로 작성하는 것이 좋음
selector : 이 서비스의 대상이 되는 pod 들을 지정한다
이 코드에서 생성한 my-service 가 호출하는 pod 들은 endpointslices 객체가 가지고 있다
- app : 위에서 작성한 deployment의 pod들이 대상이 되므로 deployment의 selector 와 동일한 selector를 지정한다
ports : nginx container 의 내부 80 port(기본 설정) 가 my-service의 9080 port로 매핑이 된다
- protocol : TCP : 기본 설정
- port : 9080 : Service는 9080 port를 호출하도록 지정
- targetPort : 80 : Deployment의 pod 들은 nginx 이므로 80 port를 지정한다
실행
- Deployment 생성
kubectl apply -f ex2-1_my_nginx_deploy.yaml
kubectl get pods
- Service 생성
kubectl apply -f .\ex2-2_my_service.yaml
kubectl get service
- 생성된 pod 들의 IP 확인
kubectl get endpointslices
kubectl get pods
kubectl describe pod my-nginx-deploy-'자동 생성된pod 해쉬코드 이름'
my-service에 연결된 endpoint 3개를 확인한다
pod들의 전체 이름을 확인한다
제일 마지막 pod의 정보를 조회해 보았을 때 IP가 10.244.0.8로 조회되었다
다른 pod 들도 조회를 하면 연결된 IP 들과 같은 IP 들로 되어 있다
- pod 간의 컨테이너 호출
kubectl exec my-localhost-pod -c nginx-container -- curl my-service:9080
통신 순서
my-localhost-pod(nginx) -> my-service:9080 -> my-nginx-deploy(nginx)
3-3. 내부 pod 가 외부와 통신
k8s 클러스터 내부에서 외부로 접근하는 방법
- Service
apiVersion: v1
kind: Service
metadata:
name: google-service
spec:
type: ExternalName
externalName: www.google.com
외부 (구글) 과 통신하기
실행
kubectl apply -f .\ex3_my_google_service.yaml
kubectl exec my-localhost-pod -c nginx-container -- curl --header "Host:www.google.com" google-service
통신 순서
my-localhost-pod(nginx) : K8S 내부 -> google-service -> www.google.com : K8S 외부
'BackEnd' 카테고리의 다른 글
CI/CD - 기초 (0) | 2024.12.25 |
---|---|
도커와 쿠버네티스 -K8S(spring boot 의 통신 with Ingress) (0) | 2024.12.02 |
도커와 쿠버네티스 -K8S(스토리지 볼륨) (0) | 2024.11.20 |
도커와 쿠버네티스 -K8S(환경 변수) (0) | 2024.11.17 |
도커와 쿠버네티스 -K8S (Deployment) (0) | 2024.11.14 |