
Windows 11 Pro 시스템의 Docker Desktop + WSL2 환경에 있는 Kubernetes 클러스터에 인증 서비스를 설정했습니다.
예를 들어 동일한 Windows 시스템(WSL2 계층 외부)의 CURL 및 PostMan 요청을 통해 도달할 수 있습니다.
그러나 여기에 문제가 있습니다. 동일한 LAN 네트워크 내의 Linux 시스템에서는 해당 나머지 끝점에 액세스할 수 없습니다.
해당 인증 서비스에 대한 연결이 실제로 작동하는지 확인하기 위해 "NodePort" 유형으로 서비스를 설정했습니다. 'kubectl get svc'에서 가져온 외부 포트를 사용하면 Windows 및 Linux 시스템에서 컬 요청이 모두 제대로 작동하고 서비스가 적절한 응답으로 응답합니다.
그러나 NodePort 서비스는 가짜 인증서와 함께 제공되는 K8s 수신의 TSL/SSL을 완전히 우회하므로 요청은 성공하더라도 HTTP를 통한 요청에만 작동합니다.
인증 서비스의 응답에서 쿠키를 사용해야 하기 때문에 HTTPS를 통한 요청이 중요하지만 K8s Ingress는 응답을 전혀 보내지 않습니다.
Windows 컴퓨터에서 관련 포트 80, 443(그리고 확실히 22)을 열었고 Windows 방화벽의 연결 규칙에서 신뢰할 수 있는 컴퓨터에 Linux 컴퓨터를 추가했습니다. 또한 실제로 연결 시도를 차단하고 있는지 확인하기 위해 일시적으로 비활성화하려고 시도했습니다. 하지만 여전히 요청은 자동으로 삭제됩니다(아마도 Ingress에 의해).
그러나 가정을 시작하기 전에 모든 관련 K8s yaml 파일뿐만 아니라 시스템 간 POST 요청이 포함된 LAN 개요를 보여드리겠습니다.
인증 배포 및 서비스는 다음과 같이 정의됩니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: gts-auth-depl
spec:
replicas: 1
selector:
matchLabels:
app: gts-auth
template:
metadata:
labels:
app: gts-auth
spec:
containers:
- name: gts-auth
image: creativewarlock/gts-auth
imagePullPolicy: IfNotPresent
env:
- name: MONGO_URI
value: 'mongodb://gts-auth-mongo-srv:27017/auth'
- name: JWT_KEY
valueFrom:
secretKeyRef:
name: gts-jwt-secret
key: JWT_KEY
imagePullSecrets:
- name: docker-hub
---
apiVersion: v1
kind: Service
metadata:
name: gts-auth-srv
spec:
type: ClusterIP
selector:
app: gts-auth
ports:
- name: gts-auth
protocol: TCP
port: 3000
targetPort: 3000
인증 및 웹 클라이언트에 대한 수신(관련은 없지만 단지 보여주기 위한 것임):
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: gts-ingress-srv
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/use-regex: 'true'
spec:
rules:
- host: gts.dev # Entry in System32/etc/hosts: 127.0.0.1 gts.dev (alternatively: localhost)
http:
paths:
- path: /api/users/?(.*) # will match /api/users/signin
pathType: Prefix
backend:
service:
name: gts-auth-srv
port:
number: 3000
- path: /?(.*) # map all other requests to web client
pathType: Prefix
backend:
service:
name: gts-client-srv
port:
number: 8080
인증 서비스에 대한 외부/직접 액세스를 위한 NodePort 서비스:
apiVersion: v1
kind: Service
metadata:
name: gts-auth-srv-ext
spec:
type: NodePort
selector:
app: gts-auth
ports:
- name: gts-auth-srv
protocol: TCP
port: 3000
targetPort: 3000
Kubernetes가 Ingress를 설명하는 방법은 다음과 같습니다.
k describe pod ingress-nginx-controller-6bf7bc7f94-krv2c -n ingress
-nginx
Name: ingress-nginx-controller-6bf7bc7f94-krv2c
Namespace: ingress-nginx
Priority: 0
Node: docker-desktop/192.168.65.4
Start Time: Thu, 11 Aug 2022 12:31:42 +0200
Labels: app.kubernetes.io/component=controller
app.kubernetes.io/instance=ingress-nginx
app.kubernetes.io/name=ingress-nginx
pod-template-hash=6bf7bc7f94
Annotations: <none>
Status: Running
IP: 10.1.28.235
IPs:
IP: 10.1.28.235
Controlled By: ReplicaSet/ingress-nginx-controller-6bf7bc7f94
Containers:
controller:
Container ID: docker://0cef9bec68d309011a32e18bf4f3a2a7ec7050b3db6cc7bafd87565e370f6695
Image: registry.k8s.io/ingress-nginx/controller:v1.3.0@sha256:d1707ca76d3b044ab8a28277a2466a02100ee9f58a86af1535a3edf9323ea1b5
Image ID: docker-pullable://registry.k8s.io/ingress-nginx/controller@sha256:d1707ca76d3b044ab8a28277a2466a02100ee9f58a86af1535a3edf9323ea1b5
Ports: 80/TCP, 443/TCP, 8443/TCP
Host Ports: 0/TCP, 0/TCP, 0/TCP
Args:
/nginx-ingress-controller
--publish-service=$(POD_NAMESPACE)/ingress-nginx-controller
--election-id=ingress-controller-leader
--controller-class=k8s.io/ingress-nginx
--ingress-class=nginx
--configmap=$(POD_NAMESPACE)/ingress-nginx-controller
--validating-webhook=:8443
--validating-webhook-certificate=/usr/local/certificates/cert
--validating-webhook-key=/usr/local/certificates/key
State: Running
Started: Sun, 19 Feb 2023 11:50:07 +0100
Last State: Terminated
Reason: Error
Exit Code: 255
Started: Sat, 18 Feb 2023 11:44:18 +0100
Finished: Sun, 19 Feb 2023 11:49:36 +0100
Ready: True
Restart Count: 132
Requests:
cpu: 100m
memory: 90Mi
Liveness: http-get http://:10254/healthz delay=10s timeout=1s period=10s #success=1 #failure=5
Readiness: http-get http://:10254/healthz delay=10s timeout=1s period=10s #success=1 #failure=3
Environment:
POD_NAME: ingress-nginx-controller-6bf7bc7f94-krv2c (v1:metadata.name)
POD_NAMESPACE: ingress-nginx (v1:metadata.namespace)
LD_PRELOAD: /usr/local/lib/libmimalloc.so
Mounts:
/usr/local/certificates/ from webhook-cert (ro)
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-hpxhw (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
webhook-cert:
Type: Secret (a volume populated by a Secret)
SecretName: ingress-nginx-admission
Optional: false
kube-api-access-hpxhw:
ConfigMapOptional: <nil> DownwardAPI: true
QoS Class: Burstable
Node-Selectors: kubernetes.io/os=linux
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal RELOAD 54m (x3 over 95m) nginx-ingress-controller NGINX reload triggered due to a change in configuration
Ingress 컨트롤러의 로그는 다음과 같습니다. 마지막 줄은 Windows 시스템의 컬 요청에 대한 응답을 보여줍니다.
k logs -f ingress-nginx-controller-6bf7bc7f94-krv2c -n ingress-nginx
W0219 10:50:08.009613 7 client_config.go:617] Neither --kubeconfig nor --master was specified. Using the inClusterConfig. This might not work.
I0219 10:50:08.010796 7 main.go:230] "Creating API client" host="https://10.96.0.1:443"
W0219 10:50:30.162337 7 main.go:271] Initial connection to the Kubernetes API server was retried 1 times.
I0219 10:50:30.162386 7 main.go:274] "Running in Kubernetes cluster" major="1" minor="24" git="v1.24.1" state="clean" commit="3ddd0f45aa91e2f30c70734b175631bec5b5825a" platform="linux/amd64"
I0219 10:50:30.278395 7 main.go:104] "SSL fake certificate created" file="/etc/ingress-controller/ssl/default-fake-certificate.pem"
I0219 10:50:30.299891 7 ssl.go:531] "loading tls certificate" path="/usr/local/certificates/cert" key="/usr/local/certificates/key"
I0219 10:50:30.314983 7 nginx.go:258] "Starting NGINX Ingress controller"
I0219 10:50:30.321843 7 event.go:285] Event(v1.ObjectReference{Kind:"ConfigMap", Namespace:"ingress-nginx", Name:"ingress-nginx-controller", UID:"407f816e-98b9-4ab6-a08f-95efafa21ddc", APIVersion:"v1", ResourceVersion:"612", FieldPath:""}): type: 'Normal' reason: 'CREATE' ConfigMap ingress-nginx/ingress-nginx-controller
I0219 10:50:31.516611 7 nginx.go:301] "Starting NGINX process"
I0219 10:50:31.516698 7 leaderelection.go:248] attempting to acquire leader lease ingress-nginx/ingress-controller-leader...
I0219 10:50:31.517522 7 nginx.go:321] "Starting validation webhook" address=":8443" certPath="/usr/local/certificates/cert" keyPath="/usr/local/certificates/key"
I0219 10:50:31.517893 7 controller.go:167] "Configuration changes detected, backend reload required"
I0219 10:50:31.543621 7 leaderelection.go:258] successfully acquired lease ingress-nginx/ingress-controller-leader
I0219 10:50:31.543648 7 status.go:84] "New leader elected" identity="ingress-nginx-controller-6bf7bc7f94-krv2c"
I0219 10:50:31.610775 7 controller.go:184] "Backend successfully reloaded"
I0219 10:50:31.610910 7 controller.go:195] "Initial sync, sleeping for 1 second"
192.168.65.4 - - [19/Feb/2023:13:09:46 +0000] "POST /api/users/signin/ HTTP/1.1" 200 150 "-" "curl/7.83.1" 259 0.054 [default-gts-auth-srv-3000] [] 10.1.28.246:3000 150 0.050 200 5b8761d90f76b4c160b0a2effc980b85
내 Linux 시스템 'Kaspar'의 컬 HTTPS 요청이 Ingress 포드에 기록되지 않고 발신자가 NGINX로부터 404 HTML 문서를 받습니다.
Blacky@Kaspar:~$ curl -k -H 'Content-Type: application/json' https://192.168.0.57/api/users/signin/ -X POST -d '{ "email": "[email protected]", "password": "iHhRCF9Dm3wKT" }'
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>
Windows 방화벽에서는 Linux 시스템을 신뢰할 수 있는 컴퓨터에 추가하고 Powershell 스크립트를 통해 명시적으로 다음 규칙을 설정했습니다.
$wsl_ip = (ubuntu.exe -c "ifconfig eth0 | grep 'inet '").trim().split()| where {$_}
$regex = [regex] "\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b"
$ip_array = $regex.Matches($wsl_ip) | %{ $_.value }
$wsl_ip = $ip_array[0]
Write-Host "WSL Machine IP: ""$wsl_ip"""
New-NetFireWallRule -DisplayName 'WSL SSL' -Direction Outbound -LocalPort 443 -Action Allow -Protocol TCP
New-NetFireWallRule -DisplayName 'WSL SSL' -Direction Inbound -LocalPort 443 -Action Allow -Protocol TCP
#### ------------ Clear all portproxy rules ------------ ####
netsh int portproxy reset all
#### ------------ SSH rule - port 22 ------------ ####
netsh interface portproxy add v4tov4 listenport=22 listenaddress=0.0.0.0 connectport=22 connectaddress=$wsl_ip
#### ------------ Webserver SSL rule - port 443 ------------ ####
netsh interface portproxy add v4tov4 listenport=443 listenaddress=0.0.0.0 connectport=443 connectaddress=$wsl_ip
#### ------------ Webserver SSL rule - port 80 ------------ ####
netsh interface portproxy add v4tov4 listenport=80 listenaddress=0.0.0.0 connectport=80 connectaddress=$wsl_ip
그래서 내 주요 질문은 다음과 같습니다.
Kubernetes의 (자체 서명된) 가짜 인증서가 문제를 일으키나요? 내 LAN 내에서 사용하려면 적절한 LetEncrypt 인증서를 사용해야 합니까?
컬/포스트맨 요청은 Windows 시스템(WSL2 레이어 외부)에서 작동하므로 먼저 Windows 방화벽을 구성하는 문제를 살펴보았지만 K8s Ingress에서 요청이 제대로 응답하지 않는 것 같습니다. 하지만 Ingress 내부에서 무슨 일이 일어나고 있는지 분석할 수 있는 도구가 부족합니다. 'kubectllogs -f <ingress...> -n ingress-nginx' 이외의 다른 수단이 있나요?
내 LAN 내의 다른 컴퓨터에서 HTTPS 요청 작업을 수행하는 방법에 대한 제안을 환영합니다.