티스토리 뷰
What is Ingress?
Kubernetes Ingress는 kubernetes cluster 내부에 존재하는 여러 service들을 cluster 외부의 client에게 HTTP, HTTPS로 노출하도록 도와준다.
Ingress는 cluster 내부의 여러 service들을 하나의 virtual IP address에 매핑하고, service에 접근하고자 하는 client들은 이 virtual IP address를 통해 service에 access할 수 있게 된다. Kubernetes Ingress를 통해 service에 접근하는 flow를 그림으로 나타내면 아래와 같다.
Ingress는 또한 Load Balancing, SSL 인증서 관리, Cache, 방화벽 설정 등의 기능을 제공하여 Client가 Service에 Access할 때, 성능과 보안을 향상시킨다. 이러한 기능들은 Kubernetes cluster 내부의 서비스를 외부에 노출할 때 발생할 수 있는 문제를 최소화하고, 서비스의 안정성과 확장성을 향상시키는데 도움을 준다.
Ingress와 다른 Service의 차이점
특정 service를 외부에 노출하는 방법으로 ingress만 있는 것은 아니다. 간략하게 이들의 특징을 비교해보면 아래와 같다.
1. NodePort
- NodePort Service는 각 cluster node 자체의 port를 열고 해당 port로 트래픽을 전달한다.
- NodePort Service는 Internal Cluster IP와 Port로 액세스할 수 있을 뿐만 아니라, 모든 노드의 전용 port로도 액세스를 할 수 있다.
2. LoadBalancer
- LoadBalancer 기법은 kubernetes가 실행중인 cloud에서 제공하는 전용 LoadBalancer로 Service에 액세스하는 방법이다.
- 트래픽을 모든 node의 nodeport로 전달한다.
- 비용이 많이 든다.
3. Ingress
- L7 (application Layer)에서 동작하기 때문에, 더 많은 기능을 쉽게 제공할 수 있다.
- Ingress는 외부에서 Service에 액세스할 수 있게 해주는 GateWay 역할을 한다.
- LoadBalancer와 비슷한 방식으로 동작하지만 더 유연하고 확장성이 높다.
Ingress 사용해보기
Ingress를 사용해보기 앞서, 아래와 같은 Service를 만들었다.
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: ds4ouj
spec:
replicas: 3
selector:
matchLabels:
app: demo
template:
metadata:
labels:
app: demo
spec:
containers:
- name: k8sdemo
image: ds4ouj/k8s_demo
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: demo-service
spec:
type: NodePort
selector:
app: demo-app
ports:
- port: 8080
targetPort: 8080
3개의 pod를 유지하는 replicaset과 이 replicaset의 pod들을 하나의 service로 묶어주는 설정이다.
이제 만들어진 서비스를 한번 확인해보면,
kubectl get svc
정상적으로 서비스가 생성된 것을 볼 수 있다. 이때, Cluster 내부에서 접근할 수 있는 Cluster-ip는 정상적으로 생성이 되었지만, External-ip는 none인 것을 볼 수 있다. 우리는 지금 서비스를 만들었지만, 이 서비스를 외부에 노출하지 않았기 때문에 당연한 결과이고, 그림으로 나타내보면 아래와 같은 상황이다.
이제 이 service를 외부로 expose하기 위한 Ingress를 생성해볼 것이다.
kubernetes에서 Ingress를 사용하기 위해서는 2가지 요소가 필요하다.
1. Ingress Object
- Ingress를 정의한 YAML 파일이다.
- 외부에서 액세스할 수 있는 URL, 사용할 Port 번호, 트래픽을 전달할 Service, SSL 인증서 등을 설정한다.
2. Ingress Controller
- Ingress Object를 해석하고, 필요한 설정을 적용하여 실제 외부에서 Service에 액세스할 수 있도록 하는 역할을 수행한다.
- Nginx, Traefik, Istio 등으로 구현할 수 있다.
이제 Ingress를 구성해볼 것인데, 여기부터는 자신이 어떻게 kubernetes cluster를 구축했느냐에 따라 다르다.
sudo kubectl get po --all-namespaces
위의 명령어를 입력해보면, 아래와 같이 모든 namespace에 존재하는 pod를 볼 수 있다.
나는 k3s로 cluster를 구축했기 때문에 kube-system namespace를 보면 traefik이라는 pod가 띄워진 것을 볼 수 있다.
traefik은 k3s에서 제공하는 default ingress controller이기 때문에 띄워진 것이고, kubespray나 kubeadm을 사용했다면 nginx를 많이 사용하곤 한다.
이제 traefik을 ingress controller로 사용하도록 ingress object를 만들어보면 아래와 같다.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: demo-service-ingress
spec:
ingressClassName: traefik
rules:
- host: "demo-service.local"
http:
paths:
- path: /hello
pathType: Prefix
backend:
service:
name: demo-service
port:
number: 8080
이 ingress object는 traefik이라는 ingress controller를 사용하고, demo-service.local이라는 hostname으로 들어오는 요청을 demo-service라는 service로 연결하도록 한 것이다.
sudo kubectl apply -f k8s-ingress-traefik.yaml
이제 위의 명령어를 사용해 ingress를 생성해보고, 아래의 명령어를 사용해 상세 정보를 확인해보자.
kubectl describe ingress [ingress name]
상세 정보를 확인해보면, demo-service.local가 host이고, /hello path에 대한 요청이 들어온다면 demo-service에게 요청을 전달한다는 설정대로 ingress와 service가 잘 연결된 것을 확인할 수 있다. 그림으로 보면 아래와 같다.
curl http://demo-service.local/hello
그러면 위의 명령어를 통해 진짜 요청을 한번 보내보자.
하지만, 아직 ingress가 요청을 받지 못하고 있다.
왜냐면 현재 curl 명령을 수행하는 host가 demo-service.local이라는 donmain name을 어떤 ip주소로 보내야할지 모르기 때문이다. 그래서 demo-service.local을 traefik의 IP로 routing하도록 또 DNS 설정을 해줘야 한다.
나의 경우 현재 192.168.49.132 ip 주소가 master node이기에 이 정보를 /etc/hosts 파일에 이 정보를 추가하였다.
이제 client는 demo-service.local이라는 domain으로 요청을 보내기 전, 이 hosts 파일을 먼저 확인한 후 host의 ip주소를 얻을 수 있어서 요청을 정상적으로 보낼 수 있게 되었다. 지금까지의 상황을 그림으로 나타내면 아래와 같다.
이제 다시 한번 해당 도메인으로 curl 요청을 보내보면,
위와 같이 정상적으로 OK를 응답받는 것을 볼 수 있다. 이제 원하는대로, ingress가 요청을 받아 내부의 service에게 routing하는 구조가 된 것이다.
Ref:
'DevOps > Kubernetes' 카테고리의 다른 글
[Kubernetes] Namespace : 리소스를 논리적으로 구분하는 장벽 (0) | 2023.01.14 |
---|---|
[Kubernetes] Service : 파드를 연결하고 외부에 노출하기 (0) | 2023.01.14 |
[Kubernetes] Deployment : 레플리카셋, 파드의 배포를 관리 (2) | 2023.01.13 |
[Kubernetes] 레플리카셋(Replica Set) (0) | 2023.01.13 |
[Kubernetes] 쿠버네티스 시작하기 (2) | 2023.01.12 |