네, 알겠습니다. not an SSL/TLS record 로그를 통해 원인이 명확해졌으니, 이제 해결을 위한 설정 부분만 명확하고 간결하게 다시 정리해 드리겠습니다.
두 가지 방법이 있으며, 상황에 맞는 방법 하나를 선택하여 진행하시면 됩니다.
Cilium은 Service의 포트 이름을 보고 백엔드 프로토콜을 자동으로 판단합니다. 이 방법은 Cilium의 설계 철학에 가장 잘 맞는 깔끔한 해결책입니다.
⚠️ 주의: 이 방법은 datalake-os-coordinator Service 리소스를 수정해야 합니다.
먼저 현재 Service의 설정을 확인합니다. 포트 이름이 http로 되어 있을 것입니다.
kubectl get service datalake-os-coordinator -n [네임스페이스] -o yaml
아래와 같이 ports[0].name을 http에서 https로 변경합니다.
# datalake-os-coordinator-service.yaml
apiVersion: v1
kind: Service
metadata:
name: datalake-os-coordinator
namespace: [네임스페이스]
spec:
selector:
app: os-coordinator # 기존 셀렉터 유지
ports:
- name: https # <-- 'http'를 'https'로 변경
port: 9200
protocol: TCP
targetPort: 9200
type: ClusterIP # 기존 타입 유지
수정한 YAML 파일을 적용하여 Service를 업데이트합니다.
kubectl apply -f datalake-os-coordinator-service.yaml
이제 Cilium Ingress는 백엔드를 HTTPS 서비스로 인식하고 암호화된 요청을 보내기 시작합니다. OpenSearch의 인증서가 자체 서명된 경우라면, 이어서 방법 2의 CiliumEnvoyConfig를 추가로 적용해야 할 수도 있습니다.
Service를 절대 수정할 수 없는 제약이 있다면, CiliumEnvoyConfig를 사용하여 Cilium의 동작을 강제로 변경할 수 있습니다. 이 방법은 SSL/TLS 인증서 검증을 비활성화까지 한 번에 처리합니다.
아래 내용으로 os-coordinator-tls.yaml 파일을 생성합니다. [네임스페이스] 부분만 실제 환경에 맞게 수정하세요.
# os-coordinator-tls.yaml
apiVersion: cilium.io/v2alpha1
kind: CiliumEnvoyConfig
metadata:
name: os-coordinator-tls-config
namespace: [네임스페이스] # OpenSearch 서비스가 있는 네임스페이스
spec:
# 이 설정이 적용될 서비스를 지정합니다.
services:
- name: datalake-os-coordinator
namespace: [네임스페이스]
# 해당 서비스의 9200 포트로 가는 트래픽을 HTTPS로 처리하도록 설정합니다.
perPortConfig:
- port: 9200
protocol: HTTPS
# Envoy 클러스터 설정을 정의합니다.
clusters:
- name: datalake-os-coordinator
connectTimeout: 5s
type: STRICT_DNS
loadAssignment:
clusterName: datalake-os-coordinator
endpoints:
- lbEndpoints:
- endpoint:
address:
socketAddress:
# Fully Qualified Domain Name (FQDN) 형식으로 서비스 주소를 지정합니다.
address: datalake-os-coordinator.[네임스페이스].svc.cluster.local
portValue: 9200
# 가장 중요한 부분: TLS 설정
transportSocket:
name: envoy.transport_sockets.tls
typedConfig:
'@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
# OpenSearch의 인증서가 공인된 것이 아니므로 검증을 건너뜁니다.
skipServerCertificateVerification: true
생성한 YAML 파일을 클러스터에 적용합니다.
kubectl apply -f os-coordinator-tls.yaml
잠시 후, Cilium Ingress를 통해 다시 접속하여 서비스가 정상적으로 동작하는지 확인합니다.
| 상황 | 추천 방법 | 장점 | 단점 |
|---|---|---|---|
| Service를 수정할 수 있음 | 방법 1: Service 포트 이름 변경 | Cilium 표준 방식, 가장 깔끔함 | Service 리소스 변경 필요 |
| Service를 수정할 수 없음 | 방법 2: CiliumEnvoyConfig 사용 | Service 변경 불필요, SSL 검증까지 한 번에 해결 | 설정이 다소 복잡함 |
권장 순서는 방법 1을 먼저 시도해보고, 만약 인증서 문제로 여전히 연결이 안 된다면 방법 2를 추가하거나, 처음부터 방법 2만 적용
네, 지금 겪고 계신 상황과 해결 과정을 시각적으로 이해하실 수 있도록 전체 처리 과정을 도표로 정리해 드리겠습니다.
upstream connect error 발생먼저, 문제가 발생했을 때의 트래픽 흐름과 실패 지점을 보여줍니다.
graph TD
subgraph "클라이언트"
A[사용자 브라우저]
end
subgraph "Kubernetes 클러스터"
B[Cilium Ingress<br>eBPF + Envoy]
C[Service: datalake-os-coordinator<br><b>port name: http</b>]
D[Pod: os-coordinator<br><b>HTTPS 기대 (9200 포트)</b>]
end
A -- 1. HTTP 요청 --> B
B -- 2. Service 'http' 확인 --> C
B -- 3. <b>HTTP</b> 요청 (평문) --> D
D -- 4. <font color=red><b>연결 거부</b><br/>not an SSL/TLS record</font> --> B
B -- 5. 502 Bad Gateway<br/>(upstream connect error) --> A
style D fill:#f9f,stroke:#333,stroke-width:2px
style B fill:#ffcccb,stroke:#333,stroke-width:2px
도표 설명:
1. 사용자가 브라우저를 통해 HTTP로 요청을 보냅니다.
2. Cilium Ingress는 요청을 받아, 연결된 Service의 정보를 확인합니다.
3. (문제의 핵심) Service의 포트 이름이 http이므로, Cilium은 백엔드가 HTTP 서비스라고 판단하고 암호화되지 않은 평문(Plain Text) HTTP 요청을 os-coordinator Pod로 보냅니다.
4. os-coordinator Pod는 security.ssl.transport 설정으로 인해 HTTPS 통신만 준비하고 있습니다. 암호화되지 않은 데이터를 받고 "이건 SSL/TLS 레코드가 아니야!"라며 연결을 거부합니다.
5. 연결 실패가 Cilium Ingress에 전달되고, Ingress는 클라이언트에게 502 Bad Gateway (upstream connect error) 에러를 반환합니다.
CiliumEnvoyConfig 적용 후CiliumEnvoyConfig를 적용하여 문제를 해결했을 때의 정상적인 트래픽 흐름입니다.
graph TD
subgraph "클라이언트"
A[사용자 브라우저]
end
subgraph "Kubernetes 클러스터"
B[Cilium Ingress<br>eBPF + Envoy]
subgraph "CiliumEnvoyConfig 설정"
E[<b>TLS Origination</b><br/>- protocol: HTTPS<br/>- skipServerCertificateVerification: true]
end
C[Service: datalake-os-coordinator<br><b>port name: http</b>]
D[Pod: os-coordinator<br><b>HTTPS 통신 (9200 포트)</b>]
end
A -- 1. HTTP 요청 --> B
B -- 2. CiliumEnvoyConfig<br/>참조 --> E
B -- 3. <b>HTTPS</b> 요청 (암호화) --> D
D -- 4. HTTPS 응답 (암호화) --> B
B -- 5. HTTP 응답 (평문) --> A
style D fill:#d4edda,stroke:#155724,stroke-width:2px
style B fill:#d1ecf1,stroke:#0c5460,stroke-width:2px
style E fill:#fff3cd,stroke:#856404,stroke-width:2px
도표 설명:
1. 사용자는 여전히 HTTP로 요청을 보냅니다.
2. Cilium Ingress는 요청을 받지만, 이제는 CiliumEnvoyConfig에 정의된 규칙을 참조합니다.
3. (해결의 핵심) CiliumEnvoyConfig는 "이 서비스로 가는 트래픽은 무조건 HTTPS로 보내고, 인증서 검증은 하지 마라"고 Envoy에게 지시합니다. 따라서 Cilium은 받은 HTTP 요청을 HTTPS로 암호화(TLS Origination)하여 os-coordinator Pod로 보냅니다.
4. os-coordinator Pod는 암호화된 HTTPS 요청을 정상적으로 수신하고 처리한 뒤, 암호화된 응답을 반환합니다.
5. Cilium Ingress는 응답을 복호화하여 최종적으로 사용자에게 평문 HTTP 응답을 전달합니다. 사용자는 이 모든 과정을 인지하지 못하고 정상적으로 서비스를 이용하게 됩니다.
이 도표들이 Cilium Ingress와 Envoy가 어떻게 협력하여 트래픽을 처리하고, CiliumEnvoyConfig가 문제 해결의 어떤 지점에서 핵심적인 역할을 하는지 시각적으로 이해하는 데 도움이 되었기를 바랍니다.