티스토리 뷰

Cloud/Kubernetes

ingress with subpath

jacobbaek Jacob_baek 2021. 3. 23. 22:49

nginx-ingress를 사용해 다수의 subpath를 각 Application별로 지정해 접근할수 있는 환경을 만들어보고자 한다.

ingress에서 subpath를 사용해야 하는 경우 아래와 같은 설정이 필요하다.
(kubernetes 1.19.8 에서 아래 설정이 동작되었다.)

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: grafana-ingress
  namespace: monitoring
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  rules:
  - host: "test.jacobbaek.com"
    http:
      paths:
        - path: /grafana(/|$)(.*)
          pathType: Prefix
          backend:
            service:
              name: grafana-service
              port:
                number: 3000

간단히 설명을 추가하면 다음과 같은 경우의 path가 접근이 가능해진다.

  • /grafana(/|$) : /grafana 혹은 /grafana/
  • /grafana(/|$)(.) : /grafana/ (* 은 any)

하지만 위 ingress를 생성한후에도 ingress에서 지정한 host로 subpath를 추가하여 접속해도 접속이 실패되는 경우가 있다.
실제 어떤 문제인지를 알기 위해 아래와 같이 확인을 해보면 /grafana란 subpath를 입력해서 접근했음에도 /grafana/login 이 아닌
/login으로 redirect를 수행하여 접근이 실패하게 되는것을 볼수 있다.

jacob@dubaekPC:~$ curl -vL https://test.jacobbaek.com/grafana --insecure
*   Trying 100.100.100.100:443...
* TCP_NODELAY set
* Connected to test.jacobbaek.com (100.100.100.100) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use h2
* Server certificate:
*  subject: O=Acme Co; CN=Kubernetes Ingress Controller Fake Certificate
*  start date: Mar 15 09:27:26 2021 GMT
*  expire date: Mar 15 09:27:26 2022 GMT
*  issuer: O=Acme Co; CN=Kubernetes Ingress Controller Fake Certificate
*  SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x7fffbe483b00)
> GET /grafana HTTP/2
> Host: test.jacobbaek.com
> user-agent: curl/7.68.0
> accept: */*
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
* Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
< HTTP/2 302
< date: Tue, 23 Mar 2021 04:53:21 GMT
< content-type: text/html; charset=utf-8
< content-length: 29
< cache-control: no-cache
< expires: -1
< location: /login    ### <============== 문제의 location
< pragma: no-cache
< set-cookie: redirect_to=%2F; Path=/; HttpOnly; SameSite=Lax
< x-content-type-options: nosniff
< x-frame-options: deny
< x-xss-protection: 1; mode=block
< strict-transport-security: max-age=15724800; includeSubDomains
<
* Ignoring the response-body
* Connection #0 to host test.jacobbaek.com left intact
* Issue another request to this URL: 'https://test.jacobbaek.com/login'
* Found bundle for host test.jacobbaek.com: 0x7fffbe483940 [can multiplex]
* Re-using existing connection! (#0) with host test.jacobbaek.com
* Connected to test.jacobbaek.com (100.100.100.100) port 443 (#0)
* Using Stream ID: 3 (easy handle 0x7fffbe483b00)
> GET /login HTTP/2
> Host: test.jacobbaek.com
> user-agent: curl/7.68.0
> accept: */*
>
< HTTP/2 404
< date: Tue, 23 Mar 2021 04:53:21 GMT
< content-type: text/html
< content-length: 146
< strict-transport-security: max-age=15724800; includeSubDomains
<
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>
* Connection #0 to host test.jacobbaek.com left intact

즉, 해당 Application에서 Base path를 /로 인지하고 있고 다시 /로 redirection 시키는 것이다.
이러한 경우는 Application에서 이를 수정해야 한다.

Kubernetes 에서 동작되는 container의 경우 대체로 Environment를 통해 이를 제어할수 있다.
위 예제에 나온 grafana를 예로 들자면, 아래와 같은 deployment가 사용될수 있으며 이를 반영해 놓으면 subpath가 반영된 형태로 deployment를 통한 pod가 생성된다.

  template:
    spec:
      containers:
        - image: grafana/grafana
          name: grafana
          env:
            - name: GF_SERVER_ROOT_URL
              value: "http://test.jacobbaek.com/grafana/"

참고사이트

'Cloud > Kubernetes' 카테고리의 다른 글

initcontainer with multicommand  (0) 2021.04.13
Velero  (0) 2021.04.06
ingress with subpath  (0) 2021.03.23
Cluster-API  (0) 2021.03.20
kubernetes ingress  (0) 2021.03.15
Longhorn  (0) 2021.03.13
댓글
댓글쓰기 폼