curl: (35) OpenSSL SSL_connect: Connection reset by peer
오류는 SSL 핸드셰이크를 시도하는 도중 상대방 서버(또는 중간 노드)가 TCP 연결을 강제로 종료했을 때 발생합니다. SSL 세션을 설정하기도 전에 RST
패킷이 반환되며 연결이 끊기기 때문에, 근본적으로는 네트워크 레벨 또는 SSL 설정 문제입니다. 따라서 k8s 서비스로의 통신 과정에서 OpenSSL 오류가 발생하였다면, 네트워크의 어느 구간에서 연결이 끊기는지를 확인하여야 합니다.
목 차
수정된 HTML:
1. Connection reset by peer 원인
OpenSSL SSL_connect: Connection reset by peer 오류 메시지를 자세히 분석해 보겠습니다.
curl: (35)
→ TLS 연결 시도 중 발생한 오류SSL_connect
→ 클라이언트가 TLS 핸드셰이크를 시작하는 단계Connection reset by peer
→ 상대 서버나 중간 장치가 TCP 세션을RST
로 종료함
해당 오류가 발생할 수 있는 케이스와 해결방법을 분석해 보았습니다.
(1) 서버(API-Server)가 TLS 핸드셰이크 전에 연결을 종료
- 가능한 상황:
- API-Server가 포트는 열려 있으나 TLS를 지원하지 않음 (예: 포트는 열렸지만 HTTP만 허용)
- API-Server가 과부하 상태이거나 connection limit 초과
--tls-cert-file
/--tls-private-key-file
설정 누락 또는 TLS 바인딩 실패
- 해결 방법:
- API-Server 로그 확인:
kubectl logs -n kube-system <api-server-pod>
- API-Server에서 TLS가 바인딩된 포트를 리스닝 중인지 확인:
netstat -tulnp | grep 6443
- API-Server 재시작 로그 또는 certificate 로딩 실패 여부 확인
- API-Server 로그 확인:
(2) 중간 장치 (L4 Load Balancer, 보안 장비, Proxy)가 TCP 연결을 리셋
- 가능한 상황:
- L4 LB가 비정상 패킷 또는 Timeout으로 연결을 리셋
- TLS 프로토콜 미지원 서비스로 연결 시도
- 보안 장비가 TLS 핸드셰이크를 “위협”으로 간주하고 연결 차단 (IPS/SSL Inspection 등)
- 해결 방법:
- LB 로그 확인 (NAT GW / LB / Proxy 레이어에 connection reset 로그 존재 여부)
- 보안 장비가 있는 경우 해당 장비의 이벤트 로그 확인
tcpdump
를 사용해 클라이언트 측에서RST
패킷이 오는지 확인:tcpdump -i eth0 host <API-SERVER-IP> and port 443 -nn -X
(3) API-Server에 연결은 되었지만, 클라이언트가 기대하는 프로토콜(TLS)이 아님
- 즉, 포트는 열려 있고 연결도 되지만 서버는 TLS가 아닌 다른 프로토콜로 응답 중인 경우
- 해결 방법:
- curl 명령으로 요청 시
-v
옵션으로 핸드셰이크 과정 확인:curl -vk https://<host>:6443
openssl s_client
로 인증서 직접 요청:openssl s_client -connect <host>:6443
- 응답이 TLS가 아니라면 해당 포트에서 TLS를 제공하지 않는 것 → 잘못된 포트 접근이거나 API-Server 설정 오류
- curl 명령으로 요청 시
(4) MTU 또는 패킷 손실로 인한 TLS 핸드셰이크 실패
- TLS 핸드셰이크 초기에 큰 크기의 패킷 전송이 발생하며, MTU가 작거나 ICMP Block 등으로 인해 핸드셰이크 실패 가능
- MTU (MAxium Transmission Unit) : 네트워크에서 한 번에 전송할 수 있는 최대 패킷 크기. 기본값은 1500 byte.
- 해결 방법:
- 클라이언트 또는 워커노드에서 MTU 확인:
ip link show dev eth0
- 테스트로 MTU 축소 후 요청:
curl --interface eth0 --max-time 10 -k https://<API-SERVER-IP>:6443
- 필요 시
ip link set dev eth0 mtu 1400
설정으로 임시 축소 후 테스트
- 클라이언트 또는 워커노드에서 MTU 확인:
(5) 클라이언트에서 TLS SNI (Server Name Indication) 미설정으로 연결 종료
- 일부 서버는 SNI가 설정되지 않으면 연결을 종료하는 보안 정책을 가짐
- 해결 방법:
curl
에서 SNI 지정:curl -vk --resolve my-k8s.example.com:<PORT>:<IP> https://my-k8s.example.com:<PORT>
- 또는
openssl s_client
에서-servername
옵션 추가:openssl s_client -connect <host>:6443 -servername my-k8s.example.com
2. 검증
정확한 원인 파악을 위해 다음과 같은 사항을 검증해 보아야 합니다.
(1) TLS가 동작하는 포트인지 확인
openssl s_client -connect <LB_IP>:PORT -showcerts
(2) 패킷이 어디서 리셋되는지 확인
tcpdump -i eth0 port 6443 -nn -v
(3) API-Server 로그에서 연결 시도 실패 확인
kubectl logs -n kube-system <api-server-pod>
(4) 보안 장비, LB 설정 확인
- IPS, Proxy, WAF, DPI, EDR 등이 연결을 차단하고 있는지 확인
- 중간 장비가 TLS handshake 또는 인증서를 조작하는지 검사
3. 요약정리
Connection reset by peer
는 상대방 서버 또는 중간 장치가 TCP 연결을 비정상적으로 종료했음을 의미 합니다.- 주요 발생 원인은 다음과 같습니다.
- TLS 미지원 포트에 curl로 접속
- API-Server가 인증서나 리스닝 상태 오류
- 보안 장비가 TLS 트래픽 차단
- MTU/패킷 손실로 TLS handshake 실패
curl -vk, openssl s_client, tcpdump, 로그 분석을 통해 원인을 좁히고, 네트워크 경로상 중간 장치 및 TLS 설정을 집중적으로 점검하여 문제를 해결할 수 있습니다.
'쿠버네티스' 카테고리의 다른 글
Kubernetes에서 Object Storage 사용하는 법: S3 연동부터 코드 예시까지 (0) | 2025.03.25 |
---|---|
Kubernetes Multi Cluster (0) | 2025.03.24 |
helm uninstall시 일부 리소스가 남아 있는 이유 (0) | 2025.03.21 |
helm Chart로 생성한 object 수동 삭제하기 (0) | 2025.03.15 |
PV, PVC, StorageClass 실습 (0) | 2025.03.13 |