Ingress Controller 를 사용하여 같은 도메인에서 subpath 로 웹서비스를 분리하는 방법은 각 서비스마다 Ingress 를 만들고, '/' path 는 무조건 포함시키는 방법입니다. 한가지 단점은 root path '/' 는 처음 만든 Ingress 가 먼저 선점하게 됩니다.
물론 이 방법은 '/' 가 경로가 반드시 필요한 서비스가 2개 이상이면 적용할 수 없지만 그런 경우는 없다고 가정합니다.
예를 들어 Jupyterlab 은 '/' 경로를 반드시 필요로 합니다. '/jupyter' 를 호출할 때 jupyterlab 이 호출되게 Ingress 의 subpath 를 지정하려면 다음과 같이 작성하면 됩니다.
여기서 두번째에 들어가 '/' 는 소용이 없습니다. Nginx 에서는 처음 입력된 순서에 의해서 location 이 결정되기 때문에 'http://jupyterlab.myserver/' 를 호출하면 첫번째 생성한 jupyterlab ingress 가 적용되기 때문입니다.
웹서비스를 인터넷에 노출시키기 위해서는 Cloud Provider 가 제공하는 Load Balancer 나 On-Prem 에서 Load Balancer 나 Ingress Controller 를 사용해야 합니다. Ingress Controller 를 사용할 때 원래의 Client IP 를 확인하는 방법은 다음과 같습니다.
여기서 사용하는 Ingress Controller 와 Pod 의 Web Server 는 Nginx 를 사용했습니다.
1. [ 인터넷 ] ---> [ Ingress Controller ] ---> [ Pod (Web Server) ]
가장 기본적인 방법으로 추가 세팅없이도 바로 original client ip 를 알 수 있습니다.
set_real_ip_from 은 ingress controller 가 실행될 수 있는 서버의 cidr 입니다.
2. [ 인터넷 ] ---> [ Google or Azure LB ] ---> [ Pod (Web Server) ]
Cloud Provider (Google or Azure) 의 LB 를 이용하고 Service 의 LoadBalancer type 으로 웹서비스를 한다면 아래와 같이 Service 의 externalTrafficPolicy 값을 local 로 지정하면 됩니다. local 로 지정하면 LB 에서 바로 Web Server Pod 가 떠 있는 서버로만 접근되기 때문에 다른 서버를 통해서 연결될 때 client ip 가 해당 서버의 ip 로 들어가는 것을 방지해 줍니다.
---
kind: Service
apiVersion: v1
metadata:
name: example-service
spec:
ports:
- port: 8765
targetPort: 9376
selector:
app: example
type: LoadBalancer
externalTrafficPolicy: Local
Azure 부분은 한국 MS 의 박인혜 차장께서 알려주셨습니다.
3. [ 인터넷 ] ---> [ AWS ELB (classic lb) ] ---> [ Pod (Web Server) ]
Classic LB 에 proxy protocol 을 enable 하고, Service 의 annotations 에 다음과 같이 설정합니다.
AWS NLB 의 각 타겟 그룹에 Proxy Protocol V2 를 설정한 후, Ingress Controller 의 Service annotations 에 다음과 같이 설정합니다.
# by default the type is elb (classic load balancer).
service.beta.kubernetes.io/aws-load-balancer-type: nlb
# Enable PROXY protocol
service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: "*"
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: 'tcp'
Ingress Controller 를 활용한 웹서비스에 TLS 를 적용하는 방법 중 가장 쉬운 방법은 Ingress Controller 에 TLS 를 적용하는 방법입니다. 이 방법은 client 와 Ingress Controller 까지 https 로 통신하고 Ingress Controller 와 web server 와는 http 로 통신하게 됩니다.
아래의 방법은 Ingress Controller 는 미리 설치되어 있다고 가정합니다.
먼저, letsencrypt 로 접속하여 3개월간 무료로 인증서를 받는 방법을 알아봅니다.
중요한 것은 인터넷에서 해당 도메인으로 로컬 서버에 접속이 되어야 하며 (Inbound 가능) standalone 을 사용할 때 로컬에 80 포트는 unbind 되어 있어야 합니다. 아래와 같은 경우는 외부에서 cloudnativeday.kr, www.cloudnativeday.kr, test.cloudnativeday.kr 도메인이 갖는 ip address 가 내 로컬 서버여야 한다는 의미입니다. 정확히는 해당 ip address 로 외부에서 내 서버로 연결이 가능해야 합니다.
인증서 발급이 완료되면 다음과 같은 디렉토리에 인증서가 생성되어 보입니다. archive 디렉토리와 심볼릭 링크가 있는 live 디렉토리가 있는데 live 디렉토리를 활용합니다. 그리고, crt 는 fullchain.pem 을, key 는 private.pem 을 사용합니다.
http 로 들어오면 자동으로 https 로 redirect 됩니다. 왜냐하면 기본 값이 nginx.ingress.kubernetes.io/ssl-redirect: "true" 이기 때문입니다. 일반 http 와 다른 부분은 tls 부분입니다. secret 과 인증서가 적용될 도메인명을 적으면 됩니다.
# kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
* kubernetes-admin@cluster.local cluster.local kubernetes-admin
seungkyua@k1 cluster.local seungkyua
# kubectl config use-context seungkyua@k1
# kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
kubernetes-admin@cluster.local cluster.local kubernetes-admin
* seungkyua@k1 cluster.local seungkyua seungkyua
Kubernetes 에 접속하여 해당 계정이 해당 네임스페이스에만 접속 권한이 있는지 확인
# kubectl get pods
No resources found.
# kubectl get pods -n defaults
Error from server (Forbidden): pods is forbidden: User "seungkyua" cannot list resource "pods" in API group "" in the namespace "defaults"