Ingress는 L7 Load Balancer이며 Cluster 외부에서 안으로 접근하는 요청들을 어떻게 처리할지 정의해둔 규칙 모음이다.
URL을 사용할 수 있도록 해주고 Traffic Load Balancing, SSL 인증서 처리, 도메인 기반 가상 호스팅 또한 제공한다.
Ingress Controller를 Kubernetes 내부 혹은 외부 어디에 두느냐에 따라 Packet 흐름이 달라진다.
⇒ On-Premises : 클러스터 내부에 Pod로 구현된다.
⇒ Public Cloud : 클러스터 외부에 존재한다.
출처 : 오리뎅이 Slideshare
Ingress Controller 설치
https://kubernetes.github.io/ingress-nginx/deploy/#installation-guide
namespace, serviceaccount, role, rolebinding, configmap, service, deployment 등이 생성된다.
# kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.44.0/deploy/static/provider/baremetal/deploy.yaml
# kubectl get pods -n ingress-nginx
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-5gqc5 0/1 Completed 0 12m
ingress-nginx-admission-patch-j8rzn 0/1 Completed 1 12m
ingress-nginx-controller-67897c9494-z7ljs 1/1 Running 0 12m
# kubectl get all -n ingress-nginx
NAME READY STATUS RESTARTS AGE
pod/ingress-nginx-admission-create-5gqc5 0/1 Completed 0 12m
pod/ingress-nginx-admission-patch-j8rzn 0/1 Completed 1 12m
pod/ingress-nginx-controller-67897c9494-z7ljs 1/1 Running 0 12m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/ingress-nginx-controller NodePort 10.233.32.198 <none> 80:30888/TCP,443:31204/TCP 12m
service/ingress-nginx-controller-admission ClusterIP 10.233.30.1 <none> 443/TCP 12m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/ingress-nginx-controller 1/1 1 1 12m
NAME DESIRED CURRENT READY AGE
replicaset.apps/ingress-nginx-controller-67897c9494 1 1 1 12m
NAME COMPLETIONS DURATION AGE
job.batch/ingress-nginx-admission-create 1/1 6s 12m
job.batch/ingress-nginx-admission-patch 1/1 6s 12m
root@instance-1:~# kubectl create deployment nginx nginx --image=nginx
root@instance-1:~# kubectl expose deployment nginx --type=NodePort --port=80 --target-port=80
service/nginx exposed
root@instance-1:~# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
clusterip-service ClusterIP 10.233.23.13 <none> 80/TCP 14h
ext-service ExternalName <none> google.com <none> 11h
headless-svc ClusterIP None <none> 80/TCP 11h
kubernetes ClusterIP 10.233.0.1 <none> 443/TCP 6d17h
my-service NodePort 10.233.53.193 <none> 80:30007/TCP 12h
nginx NodePort 10.233.7.196 <none> 80:30456/TCP 7s
# nginx 서비스의 cluster-ip로 curl 명령어 날림
root@instance-1:~# curl 10.233.7.196
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
Ingress Template
Path만 설정해주었다.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: minimal-ingress
# 인그레스를 설정할 때 .metadata.annotations 하위 필드를 사용해야 한다.
# 각 인그레스 컨트롤러마다 설정이 다르다.
# / 경로로 리다이렉트하라는 뜻이다.
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
# 규칙들을 지정해줄 수 있다.
rules:
# foo.bar.com의 주소로 요청이 들어올 시 다음에 설정하는 규칙에 따라 처리
- host: "foo.bar.com"
http:
paths:
- path: /login
pathType: Prefix
backend:
# nginx라는 서비스의 80번 포트로 보낸다.
service:
name: nginx
port:
number: 80
- host: "foo.bar.com"
http:
paths:
- path: /logout
pathType: Prefix
backend:
# nginx라는 서비스의 80번 포트로 보낸다.
service:
name: nginx
port:
number: 80
Ingress 생성
Web에서 접속할 때는 ingress-nginx-controller svc의 nodeport로 접속하여야 한다.
root@instance-1:~/kubernetes-sample/ing# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
**ingress-nginx-controller NodePort 10.233.32.198 <none> 80:30888/TCP,443:31204/TCP 28m**
ingress-nginx-controller-admission ClusterIP 10.233.30.1 <none> 443/TCP 28m
root@instance-1:~/kubernetes-sample/ing# kubectl describe ing
Name: minimal-ingress
Namespace: default
Address: 10.142.0.5
Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
**Rules:
Host Path Backends
---- ---- --------
foo.bar.com
/login nginx:80 (10.233.125.37:80)
foo.bar.com
/logout nginx:80 (10.233.125.37:80)**
Annotations: nginx.ingress.kubernetes.io/rewrite-target: /
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Sync 40s (x3 over 2m56s) nginx-ingress-controller Scheduled for sync
해당 파일을 메모장이나 편집기 등으로 열어서 수정해주자.
<<instance-1 or 5의 external ip>> foo.bar.com
root@instance-1:~/kubernetes-sample/ing# openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=foo.bar.com"
Generating a 2048 bit RSA private key
........................................................................................................................................................................................................................................................................+++
..+++
writing new private key to 'tls.key'
-----
# 키, 인증서 확인
root@instance-1:~/kubernetes-sample/ing# ls
ingress.yaml tls.crt tls.key
# 시크릿 생성
root@instance-1:~/kubernetes-sample/ing# kubectl create secret tls foo-secret --key tls.key --cert tls.crt
secret/foo-secret created
# secret 확인
root@instance-1:~/kubernetes-sample/ing# kubectl describe secrets foo-secret
Name: foo-secret
Namespace: default
Labels: <none>
Annotations: <none>
Type: kubernetes.io/tls
Data
====
tls.crt: 1099 bytes
tls.key: 1704 bytes
Secret을 Ingress에 적용
443 포트가 31204 NodePort와 바인딩이 된 것을 확인할 수 있다.
# 수정사항 적용
root@instance-1:~/kubernetes-sample/ing# kubectl apply -f ingress.yaml
ingress.networking.k8s.io/minimal-ingress configured
# 포트 확인
root@instance-1:~/kubernetes-sample/ing# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
**ingress-nginx-controller NodePort 10.233.32.198 <none> 80:30888/TCP,443:31204/TCP 84m**
ingress-nginx-controller-admission ClusterIP 10.233.30.1 <none> 443/TCP 84m
⇒ 두 필드 값을 한꺼번에 0으로 설정할 수는 없다. Pod가 없을 수 있기 때문이다.
readinessProbe는 컨테이너가 서비스 요청을 처리할 준비가 되었는지 진단한다.
예를 들어 Java Process를 실행했을 때 초기화 과정이 긴데 이 때 livenessProbe가 OK더라도 readinessProbe를 따로 지원하지 않으면 아직 준비되지 않은 컨테이너에 요청이 가서 응답이 제대로 오지 않을 수 있으므로 readinessProbe를 설정해주어야 한다.
readinessProbe를 설정하기 힘들다면 .spec.minReadySeconds 필드를 이용해 어느 정도 비슷한 효과를 낼 수 있다. 이 필드는 Pod가 준비 상태일 때까지의 최소 대기 시간으로 기본값은 0이다.
https://kubernetes.io/ko/docs/concepts/services-networking/ingress/
https://kubernetes.github.io/ingress-nginx/deploy/#installation-guide