이야기박스
Kubernetes. Ingress and TLS Setting 본문
쿠버네티스에서 제공하는 REST API 서비스에 https 통신을 제공하기 위하여 Ingress와 SSL 설정에 대한 기술 조사를 진행하게 되었습니다. 간략한 기술 소개 및 yaml 파일 예시를 소개하려고 합니다.
# Ingress란?
Ingress (명사) - 가거나 들어가는 행위; 들어갈 수 있는 권리; (어떤 장소에) 들어감; 입장권
보통 ingress는 서버 내부로 유입되는 트래픽을 나타내고 egress는 서버 외부로 나가는 트래픽을 의미합니다.
마찬가지로 Kubernetes Ingress는 외부에서 Kubernetes Service 및 다른 Resource에 접근하기 위한 게이트웨이라고 생각하시면 됩니다.
## Ingress가 필요한 이유
- 하나의 공인된 주소로 다양한 서비스에 포워딩될 수 있음
- HTTP Layer Control(Layer 7)이 가능
## Kubernetes Ingress 필요 구성 요소
- Ingress : 규칙 정의
- Ingress Controller : Deployment, 실제 Ingress가 실행되는 pod
- Ingress Service : Ingress Controller를 외부에 제공하기 위한 서비스
# Ingress Controller
이제 Kubernetes에 Ingress를 적용하는 방법을 알아보려고 합니다. Ingress 또한 하나의 프로세스 이므로 Pod를 생성해 주어야 하고 이 Pod에 대한 Service 또한 생성해 주어야 합니다. 즉, Ingress는 규칙을 정의하는 것일 뿐이고 동작하기 위해서는 Ingress Controller(Deployment)가 필요하게 됩니다.
## Ingress 확인
현재 사용중인 클러스터에도 citrix로 되어 있는 ingress-controller가 있었습니다. 아무래도 LB 구성에 사용되는 것 같습니다.
kubectl get po --all-namespaces | grep "ingress"
kube-system cic-k8s-ingress-controller-6fcdd6a576-jq46v 1/1 Running 1 7d23h
## Ingress 구성
그럼 이제 https 통신을 위하여 nginx의 ingress-controller를 구성해보려고 합니다. 아래 공식 링크를 참조하여 설치를 진행하면 됩니다.
위 github에서 ingress-nginx/deploy/static/mandatory.yaml 파일을 받아서 kubernetes에 제출하면 됩니다.
kubectl apply -f mandatory.yaml
이후 ingress 리소스를 생성해주면 자동으로 ingress-controller에 매핑되게 됩니다. 이 ingress에 대한 설명은 아래에서 다시 하도록 하겠습니다.
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: my-ingress
namespace: test-namespace
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- http:
paths:
- path: /test
backend:
serviceName: test-service
servicePort: 80
## Ingress Controller Service 등록
ingress-controller를 생성하고 ingress 규칙 또한 정의했지만 여기에 접근할 수 있는 수단이 아직 없네요. 그러므로 이제 Ingress Controller에 접근할 수 있는 Service를 만들어 주면 됩니다.
kind: Service
apiVersion: v1
metadata:
name: ingress-nginx
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
externalTrafficPolicy: Local
type: LoadBalancer
selector:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
ports:
- name: http
port: 80
protocol: TCP
targetPort: http
- name: https
port: 443
protocol: TCP
targetPort: https
그럼 이제 이 서비스를 통하여 위에서 정의했던 ingress 규칙의 효과를 볼 수 있습니다.
storyparks> kubectl get ingress
NAME HOSTS ADDRESS PORTS AGE
tls-dev-ingress * 10.106.***.*** 80 103m
여기서 'ADDRESS'는 Ingress-Controller의 Service External IP가 됩니다. 이 공인 IP를 통하여 Ingess에 정의된 모든 서비스에 접근할 수 있습니다.
## 확인
curl {nginx-ingress-service 공인ip}/test
## 참고. Bypassing
Nginx Ingress Controller는 bypassing이라는 기능을 통하여 application pod에 트래픽을 직접 전달합니다. 해당 Pod의 Service를 경유해야 하는 네트워크 홉을 줄이게 되죠.
"[It routes to pods directly] in order to bypass kube-proxy to allow NGINX features like session affinity and custom load balancing algorithms. It also removes some overhead, such as conntrack entries for iptables DNAT."
# TLS Setting
다음은 TLS Setting을 해보려고 합니다. 우선 인증 정보를 담고 있는 Kubernetes Secret 생성이 필요합니다.
# tls-secret.yaml
apiVersion: v1
data:
tls.crt: {your crt}
tls.key: {your key}
kind: Secret
metadata:
name: tls-secret
namespace: test-namespace
type: kubernetes.io/tls
다음은 위 Secret 정보를 이용하여 ingress를 다시 구성합니다.
# tls-ingress.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: my-ingress
namespace: test-namespace
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
kubernetes.io/ingress.class: "nginx"
spec:
tls:
- hosts:
- test.storyparks.com
secretName: tls-secret
rules:
- host: test.storyparks.com
http:
paths:
- path: /test
backend:
serviceName: test-service
servicePort: 80
## 확인
curl https://test.storyparks.com/test
# Ingress Annotation
위 tls-ingress.yaml에서 사용했던 nginx.ingress.kubernetes.io/rewrite-target, kubernetes.io/ingress.class과 같이 Ingress Service의 동작 방식을 어노테이션을 통하여 컨트롤할 수 있습니다.
## nginx.ingress.kubernetes.io
Nginx의 설정을 위한 어노테이션입니다. nginx-ingress의 deployment를 보면 다음과 같은 설정이 있는 걸 볼 수 있습니다. 이 어노테이션을 통하여 nginx 설정을 컨트롤할 수 있고 커스텀 설정을 여러 개 지정할 수도 있습니다.
containers:
- name: nginx-ingress-controller
image: nos-gitlab-registry.nmn.io/kubernetes/base-images/nginx-ingress-controller:master
args:
- /nginx-ingress-controller
- --configmap=$(POD_NAMESPACE)/nginx-configuration
- --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
- --udp-services-configmap=$(POD_NAMESPACE)/udp-services
- --publish-service=$(POD_NAMESPACE)/ingress-nginx
- --annotations-prefix=nginx.ingress.kubernetes.io
설정 예시 입니다.
- nginx.ingress.kubernetes.io/rewrite-target : 지정된 경로로 Redirect를 한다. "/ (Root)"로 지정되어 있으면, 하위 context와 무관하게 항상 ROOT으로 Redirect 된다.
- nginx.ingress.kubernetes.io/force-ssl-redirect : https로 강제 Redirect를 한다.
- nginx.ingress.kubernetes.io/app-root : ROOT 경로를 재설정한다.
## kubernetes.io/ingress.class
한 클러스터에 여러 Ingress Controller가 정의되어 있는 경우, 어떠한 Ingress Controller를 사용할 것인지 정의하는 어노테이션입니다. 아까 nginx-ingress-controller를 설치하기 전, citrix-ingress-controller가 있는 것을 확인했었습니다. 때문에 지금 제가 테스트를 진행한 클러스터에는 ingress-controller가 두 개 이므로 어느 controller를 사용할지 지정이 필요합니다.
# Conclusion
- Ingress Resource 자체는 하나의 규칙일 뿐입니다. 동작을 위해서는 Deployment, Service가 필요합니다.
- 다양한 Ingress Controller가 있다면 kubernetes.io/ingress.class 어노테이션을 통하여 특정 Controller를 지정할 수 있습니다.
- Nginx Controller는 다른 서비스들로 라우팅을 해줄 수 있습니다.
# Reference
'Computer & Data > Orchestration' 카테고리의 다른 글
Kubernetes. 고급 스케줄링 (1) | 2022.01.12 |
---|---|
Kubernetes. 소스 IP 주소 구하기 (0) | 2020.06.29 |
Kubernetes. Helm3 (1) | 2020.01.10 |
(작성중) Kubernetes. Pod AutoScaling (0) | 2019.12.06 |
Docker - SpringBoot JVM Option 이슈 (0) | 2019.12.03 |