Kube Ingress — Traefik 테스트내역 공유
Kube Ingress 용도로 검증한 Traefik 테스트 내역 공유 드립니다.
Kubernetes Ingress Controller 용도로 NGINX, HAPROXY 등이 가능한데 그 중 Traefik을 검증해 보았다. NGINX가 점유율은 가장 높다. 현재 서비스에도 사용 중이지만 NGINX POD 재시작하면서 hang 걸리는 등 사소한 문제가 있었다. F5 인수 후 Community 버전은 제대로 지원이 안되는 것 같은 느낌적인 느낌도 있었다. 그래서 나름 Admin UI도 있고 업계 사례도 풍부한 Traefik을 검증 해 보았다.
TL;DR
. Traefik (Kube Ingress) 운영 환경 적용 시 필요한 테스트를 무사히 완료 하였습니다. 해당 내역을 공유합니다.
1) 기본 인증서 이 외 사용자 인증서 추가
2) Http to Https Redirect 설정
3) Http, Https 이 외 특정 사용자 포트 추가
. 제 의견은 Admin GUI 도 제공하고 Kube Ingress 용도로 가장 많이 사용하는 NGINX 보다 나은 것 같습니다.
(Ingress Controller 개념 설명은 여기로..)
설치는 역시 Helm 이용하여 쉽게 가능하다.
[spkr@erdia22 57.Traefik (spkn02:prometheus)]$ helm fetch traefik/traefik
[spkr@erdia22 57.Traefik (spkn02:prometheus)]$ tar xvfz traefik-9.17.2.tgz
traefik/Chart.yaml
traefik/values.yaml
(생략)(Helm 설치 시 항상 fetch 다운받아서 values.yml 수정해서 설치한다.)
설치 시 value 파일 변경한 내역이다.
1. Deployment 이중화 및 access log enable
: POD 이중화는 당연하고 access log는 초기 장애 처리 시 필요하여 enable 하였다. (물론 용량은 많이 차지 하겠지만) 상황에 따른 적용이 필요하다.
2. 외부 admin page open 및 loadbalancerIP 지정
: Traefik POD 접속 IP가 매번 변경되면 안되므로 미리 지정한다. (LoadBalancer 사용하기 위해서 MetalLB 등 미리 설치가 필요하다)
3. resource 및 podAntiaffinity 설정
: POD가 같은 노드에 실행되면 Node 다운 시 이중화가 안되므로 antiaffinity 까지 설정 필요하다.
설치 로그
[spkr@erdia22 traefik-9.17.2 (spkn02:prometheus)]$ k create ns traefik
namespace/traefik created[spkr@erdia22 traefik-9.17.2 (spkn02:prometheus)]$ kns traefik
Context "spkn02" modified.
Active namespace is "traefik".[spkr@erdia22 traefik-9.17.2 (spkn02:traefik)]$ helm install traefik -f my-native-values.yaml .
NAME: traefik
LAST DEPLOYED: Tue Apr 27 04:03:33 2021
NAMESPACE: traefik
STATUS: deployed
REVISION: 1
TEST SUITE: None
정상 설치 완료
[spkr@erdia22 ~ (dzbumin:default)]$ kgp
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
traefik-67b4c7db7d-4x5x4 1/1 Running 0 57s 10.233.96.61 node2 <none> <none>
Ingress 설정으로 Traefik은 자체 CRD(Custom Resource Definition), IngressRoute를 사용한다.
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: simpleingressroute
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`your.example.com`) && PathPrefix(`/notls`)
kind: Rule
services:
- name: coffee-svc
port: 80
IngressRoute 설정은 ingress와 아주 유사하다. 먼저 entrypoints를 지정한다. entrypoints는 traefik deploy YAML에서 확인 가능하다. deploy YAML 파일은 아래와 같이 YAML down 받는다.
[spkr@erdia22 57.Traefik (dzbumin:traefik)]$ k get deployments.apps traefik -o yaml |k neat > traefik-deploy.yml
(k neat 사용하면 편리하다)
- 중간쯤 containers — args 부문을 확인하면 entrypoint 확인 가능하다. default로 web, websecure 가 지정되었다.
다음으로, entrypoints — web 에 대하여 redirect 해야 할 domain을 지정한다.
routes:
- match: Host(`your.example.com`) && PathPrefix(`/notls`)
kind: Rule
services:
- name: coffee-svc
port: 80
your.example.com && /notls 으로 들어오는 traefik에 대하여 coffee-svc 라는 service의 80 port로 Redirect 하도록 설정하였다.
ingressroute 적용
[spkr@erdia22 57.Traefik (spkn02:traefik)]$ ka cafe-crd-ingressRoute.yml
ingressroute.traefik.containo.us/simpleingressroute created
ingressroute.traefik.containo.us/ingressroutetls created[spkr@erdia22 57.Traefik (spkn02:traefik)]$ k get ingressroute
ingressroutes.traefik.containo.us ingressroutetcps.traefik.containo.us ingressrouteudps.traefik.containo.us[spkr@erdia22 57.Traefik (spkn02:traefik)]$ k get ingressroute -n default
NAME AGE
ingressroutetls 28s
simpleingressroute 28s
ingressroute가 가르키는 SVC와 Deploy를 만든다. (미리 만들었어야..)
apiVersion: apps/v1
kind: Deployment
metadata:
name: coffee
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: coffee
template:
metadata:
labels:
app: coffee
spec:
containers:
- name: coffee
image: nginxdemos/nginx-hello:plain-text
ports:
- containerPort: 8080
resources:
limits:
cpu: 500m
requests:
cpu: 200m
---
apiVersion: v1
kind: Service
metadata:
name: coffee-svc
namespace: default
spec:
ports:
- port: 80
targetPort: 8080
protocol: TCP
name: http
selector:
app: coffee
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: tea
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: tea
template:
metadata:
labels:
app: tea
spec:
containers:
- name: tea
image: nginxdemos/nginx-hello:plain-text
ports:
- containerPort: 8080
resources:
limits:
cpu: 500m
requests:
cpu: 200m
---
apiVersion: v1
kind: Service
metadata:
name: tea-svc
namespace: default
spec:
ports:
- port: 80
targetPort: 8080
protocol: TCP
name: http
selector:
app: tea
POD, SVC 확인
[spkr@erdia22 57.Traefik (spkn02:default)]$ k get pod,svc
NAME READY STATUS RESTARTS AGE
pod/coffee-6c8998cf9c-cdqq4 1/1 Running 0 23s
pod/coffee-6c8998cf9c-x4tvz 1/1 Running 0 23s
pod/tea-86cf945d9c-952rm 1/1 Running 0 23s
pod/tea-86cf945d9c-hg4pb 1/1 Running 0 23s
pod/tea-86cf945d9c-mlh48 1/1 Running 0 23sNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/coffee-svc ClusterIP 10.233.7.182 <none> 80/TCP 23s
service/tea-svc ClusterIP 10.233.23.150 <none> 80/TCP 23s
그럼, Load Balancing 잘되는지 확인해 보자
먼저 접속을 위해서 /etc/hosts 파일 수정한다.
[spkr@erdia22 ~ (spkn02:traefik)]$ k get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
traefik LoadBalancer 10.233.27.240 172.17.28.161 9000:30540/TCP,80:32241/TCP,443:31027/TCP 17m[spkr@erdia22 57.Traefik (spkn02:default)]$ sudo vi /etc/hosts
curl 통해서 LB 기능이 정상적인지 확인하자
[spkr@erdia22 ~ (spkn02:traefik)]$ curl your.example.com/notls
Server address: 10.233.92.45:8080
Server name: coffee-6c8998cf9c-x4tvz
Date: 26/Apr/2021:19:22:22 +0000
URI: /notls
Request ID: 390f9c6499480e24fd32fc38c6251940[spkr@erdia22 ~ (spkn02:traefik)]$ curl your.example.com/notls
Server address: 10.233.96.62:8080
Server name: coffee-6c8998cf9c-cdqq4
Date: 26/Apr/2021:19:22:25 +0000
URI: /notls
Request ID: ce00abf6148b8ee25142a5e1adf42fef[spkr@erdia22 ~ (spkn02:traefik)]$ curl your.example.com/notls
Server address: 10.233.92.45:8080
Server name: coffee-6c8998cf9c-x4tvz
Date: 26/Apr/2021:19:22:29 +0000
URI: /notls
Request ID: 8a775651714608254f5d3f78bfa470ad
위와 같이 2개의 POD가 (coffee-6c8998cf9c-x4tvz, coffee-6c8998cf9c-cdqq4) 차례로 잘 응답하고 있다. 정상이다.
흥미로운건 별다른 설정없이도 TLS가 잘되는 것이다.
[spkr@erdia22 ~ (spkn02:traefik)]$ curl -k https://my.example.com/tls
Server address: 10.233.90.68:8080
Server name: tea-86cf945d9c-mlh48
Date: 26/Apr/2021:19:28:01 +0000
URI: /tls
Request ID: a1471fd835c1827fee9bf4a98654a432[spkr@erdia22 ~ (spkn02:traefik)]$ curl -k https://my.example.com/tls
Server address: 10.233.92.46:8080
Server name: tea-86cf945d9c-952rm
Date: 26/Apr/2021:19:28:03 +0000
URI: /tls
Request ID: bee246b76b05778281d11ea1322cb653[spkr@erdia22 ~ (spkn02:traefik)]$ curl -k https://my.example.com/tls
Server address: 10.233.96.63:8080
Server name: tea-86cf945d9c-hg4pb
Date: 26/Apr/2021:19:28:05 +0000
URI: /tls
Request ID: 3b73da88d7e9a33ea5b36ce6415a94e5
TLS 설정이라고는 ingressroute 설정에 아래 문구만 추가 하였다.
tls:
certResolver: myresolver
위 문구만으로 traefik에서 제공하는 default 인증서 사용 가능하다. (참 편리하다)
다음으로 Admin Page 접속하면 아래와 같이 dashboard 확인 가능하다. (왜 /dashboard/# 까지 다 붙혀야 접속하게 만든지는 이해가 안된다.)
http://172.17.29.111:9000/dashboard/#/
현재 적용 내역을 UI로 바로 확인 가능하다. 확실히 NGINX 보다 낫다.
이상 설치 및 기본 기능을 확인해 보았다.
다음으로 실제 운영 환경 적용 시 필요한 몇가지 기능들을 검증해 보았다.
1. 인증서 설정 변경
기본 traefik 인증서가 아닌 회사에서 사용하는 인증서를 사용하였다. 설정은 IngressRoute 에서 tls, secretName 만 지정하면 된다.
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: nginx-ingressroute
namespace: nginx
spec:
entryPoints:
- websecure
routes:
- match: Host(`my.example.co.kr`)
kind: Rule
services:
- name: nginx-svc
port: 80
tls:
secretName: dzbm-tls
secret 형태로 지정되므로 먼저, 인증서를 secret type으로 생성한다.(kube 에서는 인증서를 secret type으로 저장한다.)
[spkr@erdia22 ~ (dzbumin:jitsi-meet)]$ k create secret tls dzbm-tls --key STAR.bizcubex.co.kr_key.pem --cert STAR.bizcubex.co.kr_crt.pem
secret/dzbm-tls created
적용하고 웹 사이트를 확인하면 아래와 같이 정상적으로 인증서 확인 가능하다.
2. Http to Https Redirect 설정
사용자가 Http로 접속하는 것을 Https로 자동으로 Redirect 하는 기능이 필요하다.
참조
해당 설정은 Deploy YAML에 적용한다. 위에서 다운받은 YAML 파일을 수정한다.
containers:
- args:
- --global.checknewversion
- --global.sendanonymoususage
- --entryPoints.traefik.address=:9000/tcp
- --entryPoints.web.address=:8000/tcp
- --entrypoints.web.http.redirections.entryPoint.to=:443
- --entryPoints.websecure.address=:8443/tcp
containers — args — — entrypoints.web.http.redirections.entryPoint.to=:443 를 추가한다. 주의해야 할 점은 포트 번호를 “:443”로 설정하는 것이다. websecure 라고 이름으로 지정하면 원하는 443 port가 아니라 8443 port로 리다이렉트되어 에러가 발생한다. (요것 때문에 반나절 고생)
[spkr@erdia22 23.Traefik (dzbumin:traefik)]$ curl http://your.example.com
Moved Permanently
정상적으로 redirect 된다.
3. 특정 Port 추가
참조
http, https 이 외 특정 Port를 추가하기 위해서는 위와 동일하게 Deploy YAML 수정이 필요하다.
(생략)
containers:
- args:
- --global.checknewversion
- --global.sendanonymoususage
- --entryPoints.traefik.address=:9000/tcp
- --entryPoints.web.address=:8000/tcp
- --entrypoints.web.http.redirections.entryPoint.to=:443
- --entryPoints.websecure.address=:8443/tcp
- --entryPoints.mqtt.address=:11887/tcp
- --entryPoints.my.address=:5555/tcp
(생략)
위와 같이 containers — args 아래에 위와 같이 추가 합니다.
주의점은 POD Port 추가 후 해당 포트를 Service 에도 추가해야 하는 것이다. 외부에서 접속하기 위해서는 Service Port를 열어야 접속이 가능하다. (요것 역시 한 반나절 삽질. 하고 나면 당연한데, 막상 시간에 쫒기면 당연한 게 생각이 잘 안난다.)
apiVersion: v1
kind: Service
metadata:
name: traefik
namespace: traefik
spec:
loadBalancerIP: 192.168.1.146
ports:
- name: traefik
nodePort: 32246
port: 9000
targetPort: traefik
- name: web
nodePort: 32299
port: 80
targetPort: web
- name: websecure
nodePort: 30933
port: 443
targetPort: websecure
- name: my
port: 5555
targetPort: 5555
- name: mqtt
port: 11887
targetPort: 11887
selector:
app.kubernetes.io/instance: traefik
app.kubernetes.io/name: traefik
type: LoadBalancer
4. Traefik 로그 확인
traefik 설정 후 이상 여부(redirect 등)를 파악하기 위해서는 traefik pod 로그를 봐야 한다. 아래와 같이 kubetail 이용하여 복수의 POD 로그를 동시에확인 가능하다.
[spkr@erdia22 traefik-9.17.2 (dzbumin:traefik)]$ kubetail traefik-5d5cfb4cc4-
Will tail 2 logs...
traefik-5d5cfb4cc4-lfgf9
traefik-5d5cfb4cc4-qc4vh
[traefik-5d5cfb4cc4-qc4vh] 192.168.1.155 - - [30/Apr/2021:04:45:35 +0000] "GET /ping HTTP/1.1" 200 2 "-" "-" 6418 "ping@internal" "-" 0ms
[traefik-5d5cfb4cc4-qc4vh] 192.168.1.155 - - [30/Apr/2021:04:45:38 +0000] "GET /ping HTTP/1.1" 200 2 "-" "-" 6419 "ping@internal" "-" 0ms
[traefik-5d5cfb4cc4-qc4vh] 192.168.1.155 - - [30/Apr/2021:04:45:33 +0000] "POST /http-bind?room=test2 HTTP/2.0" 200 342 "-" "-" 6417 "jitsi-meet-jitsiweb-ingressroute-756c0161f63cb1f927d2@kubernetescrd" "http://10.233.96.184:80" 9083ms
[traefik-5d5cfb4cc4-lfgf9] 10.233.96.0 - - [30/Apr/2021:04:45:26 +0000] "POST /http-bind?room=test2 HTTP/2.0" 200 342 "-" "-" 8081 "jitsi-meet-jitsiweb-ingressroute-756c0161f63cb1f927d2@kubernetescrd" "http://10.233.96.184:80" 14664ms
[traefik-5d5cfb4cc4-lfgf9] 192.168.1.158 - - [30/Apr/2021:04:45:42 +0000] "GET /ping HTTP/1.1" 200 2 "-" "-" 8086 "ping@internal" "-" 0ms
[traefik-5d5cfb4cc4-lfgf9] 192.168.1.158 - - [30/Apr/2021:04:45:47 +0000] "GET /ping HTTP/1.1" 200 2 "-" "-" 8087 "ping@internal" "-" 0ms
[traefik-5d5cfb4cc4-qc4vh] 192.168.1.155 - - [30/Apr/2021:04:45:42 +0000] "POST /http-bind?room=test2 HTTP/2.0" 200 148 "-" "-" 6420 "jitsi-meet-jitsiweb-ingressroute-756c0161f63cb1f927d2@kubernetescrd" "http://10.233.96.184:80" 2129ms
[traefik-5d5cfb4cc4-lfgf9] 10.233.96.0 - - [30/Apr/2021:04:45:41 +0000] "POST /http-bind?room=test2 HTTP/2.0" 200 2497 "-" "-" 8085 "jitsi-meet-jitsiweb-ingressroute-756c0161f63cb1f927d2@kubernetescrd" "http://10.233.96.184:80" 8515ms
[traefik-5d5cfb4cc4-qc4vh] 192.168.1.155 - - [30/Apr/2021:04:45:44 +0000] "POST /http-bind?room=test2 HTTP/2.0" 200 358 "-" "-" 6421 "jitsi-meet-jitsiweb-ingressroute-756c0161f63cb1f927d2@kubernetescrd"
이상 Traefik을 사용하기 위한 설정 내역을 공유하였습니다.
Diamanti & Managed Kubernetes Service 문의 : leejunghoon@spkr.co.kr