5.4 Exposing services externally through an Ingress resource
Ingress (noun)—The act of going in or entering; the right to enter; a means or place of entering; entryway.
Understanding why Ingresses are needed
LoadBalancer
service는 각각의 load balancer마다 각자의 IP 주소가 있어야 하지만, Ingress
는 여러 서비스에 한개의 IP 주소만 필요하다.
client가 HTTP 요청을 Ingress에게 보내면 request의 host와 path로 어떤 서비스로 포워딩할지를 결정한다.
Understanding that an Ingress controller is required
Ingress object를 사용하려면 Ingress controller가 필요하다.
GKE는 GCP의 HTTP 로드밸런싱 기능을 사용한다. Minikube의 경우에는 따로 controller를 제공하지 않지만 add-on을 사용하여 Ingress controller를 사용할 수 있다.
Enabling the Ingress add-on in Minikube
$ minikube addons list
|-----------------------------|----------|--------------|
| ADDON NAME | PROFILE | STATUS |
|-----------------------------|----------|--------------|
| dashboard | minikube | disabled |
| default-storageclass | minikube | enabled ✅ |
| efk | minikube | disabled |
| freshpod | minikube | disabled |
| gvisor | minikube | disabled |
| helm-tiller | minikube | disabled |
| ingress | minikube | disabled |
| ingress-dns | minikube | disabled |
| istio | minikube | disabled |
| istio-provisioner | minikube | disabled |
| logviewer | minikube | disabled |
| metrics-server | minikube | disabled |
| nvidia-driver-installer | minikube | disabled |
| nvidia-gpu-device-plugin | minikube | disabled |
| registry | minikube | disabled |
| registry-creds | minikube | disabled |
| storage-provisioner | minikube | enabled ✅ |
| storage-provisioner-gluster | minikube | disabled |
|-----------------------------|----------|--------------|
위에 ingress
가 disabled
인 것을 볼 수 있다.
$ minikube addons enable ingress
🌟 The 'ingress' addon is enabled
$ minikube addons list | grep ingress
| ingress | minikube | enabled ✅ |
| ingress-dns | minikube | disabled |
$ kubectl get po --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
default kubia-766tj 1/1 Running 0 47h
default kubia-qtfdt 1/1 Running 0 47h
default kubia-zphvm 1/1 Running 0 47h
kube-system coredns-6955765f44-9swsw 1/1 Running 0 6d9h
kube-system coredns-6955765f44-gllc6 1/1 Running 0 6d9h
kube-system etcd-m01 1/1 Running 4 36d
kube-system kube-apiserver-m01 1/1 Running 4 36d
kube-system kube-controller-manager-m01 1/1 Running 28 36d
kube-system kube-proxy-9558l 1/1 Running 4 36d
kube-system kube-scheduler-m01 1/1 Running 29 36d
kube-system nginx-ingress-controller-6fc5bcc8c9-zj58m 1/1 Running 0 53s
Creating an Ingress resource
kubia-ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: kubia
spec:
rules:
- host: kubia.example.com
http:
paths:
- path: /
backend:
serviceName: kubia-nodeport
servicePort: 80
kubia.example.com
으로 request가 들어오면 kubia-nodeport
서비스의 80
포트로 보낸다.
Accessing the service through the ingress
$ kubectl create -f kubia-ingress.yaml
ingress.extensions/kubia created
$ kubectl get ingresses
NAME HOSTS ADDRESS PORTS AGE
kubia kubia.example.com 80 14s
GKE의 경우에는
ADDRESS
에 나온 결과를 사용하면 되고, minikube는minikube service kubia-nodeport --url
의 address를 사용하면 된다.
/etc/hosts
(window의 경우에는 C:\windows\system32\drivers\etc\hosts
)에 DNS를 수정해주어야한다.
192.168.64.4 kubia.example.com
이제 curl로 호출이 가능하다.
$ curl http://kubia.example.com
You've hit kubia-zphvm
Exposing multiple servies through the same Imgress
Ingress
resource를 잘 살펴보면 rules
와 paths
는 array로 되어 있어서 여러개를 담을 수 있다.
우선 여러 개의 paths
를 가져 같은 호스트에 다른 서비스를 추가할 수 있다.
...
- host: kubia.example.com
http:
paths:
- path: /kubia 1
backend: 1
serviceName: kubia 1
servicePort: 80 1
- path: /foo 2
backend: 2
serviceName: bar 2
servicePort: 80 2
- 1:
kubia.example.com/kubia
로 들어오는 requets는kubia
서비스로 라우트 - 2:
kubia.example.com/foo
로 들어오는 requets는bar
서비스로 라우트
이와 비슷하게 path 대신 host
를 기준으로 다른 서비스로 매핑시킬 수 있다.
spec:
rules:
- host: foo.example.com 1
http:
paths:
- path: /
backend:
serviceName: foo 1
servicePort: 80
- host: bar.example.com 2
http:
paths:
- path: /
backend:
serviceName: bar 2
servicePort: 80
- 1 Requests for foo.example.com will be routed to service foo.
- 2 Requests for bar.example.com will be routed to service bar.
Configuring Ingress to handle TLS traffic
pod가 web server를 돌리면 이는 HTTP traffic밖에 받지 못하고 TLS와 관련된 모든 것은 Ingress controller가 처리하게 한다. 이를 위해서는 Ingress에 certificate와 private key가 필요하다.
이는 Kubernetes의 Secret
이라는 리소스에 저장된다. 자세한 내용은 7장에서 설명되기 때문에 여기서는 그냥 사용하는 방법만 보면됨
우선 private key와 certificate 생성
$ openssl genrsa -out tls.key 2048
$ openssl req -new -x509 -key tls.key -out tls.cert -days 360 -subj /CN=kubia.example.com
$ kubectl create secret tls tls-secret --cert=tls.cert --key=tls.key
secret/tls-secret created
private key와 certificate는 tls-secret
이라는 secret resource에 저장되었다. 이제 Ingress를 HTTPS 리퀘스트를 받게 수정하자.
kubia-ingress-tls.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: kubia
spec:
tls:
- hosts:
- kubia.example.com
secretName: tls-secret
rules:
- host: kubia.example.com
http:
paths:
- path: /
backend:
serviceName: kubia-nodeport
servicePort: 80
기존 Ingress를 지우고 다시 만드는 대신
kubectl apply -f kubia-ingress-tls.yaml
로 기존 Ingress resource를 update 하여도 된다.
이제 HTTPS로 서비스 접속이 가능하다.
$ curl -k -v https://kubia.example.com/kubia
* About to connect() to kubia.example.com port 443 (#0)
...
* Server certificate:
* subject: CN=kubia.example.com
...
> GET /kubia HTTP/1.1
> ...
You've hit kubia-xueq1