
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