Troubleshooting

Jenkins → Harbor HTTPS 연결 실패

Jenkins와 SUSE Private Registry(Harbor)가 같은 클러스터 내에 있고 Traefik Ingress + self-signed TLS 환경에서 HTTPS 연결 실패하는 이슈 분석

Ingress Controller
Traefik (IngressRoute)
TLS 인증서
Self-signed, *.[IP].nip.io wildcard
Jenkins URL
Ingress hostname 사용 (https://[IP].nip.io)
현상
https:// → Connection refused | http:// → 정상
에러 로그
미확인 (추정 분석)

1 연결 레이어 구분 — 어느 구간이 문제인가

HTTPS 연결은 두 구간으로 나뉜다. 에러 종류에 따라 원인이 완전히 다름.

연결 경로
Jenkins Pod
──HTTPS──▶
Traefik :443
──HTTP/HTTPS──▶
Harbor Pod :80/443
【프론트엔드 레이어】 【백엔드 레이어】
레이어구간Connection refused 시 원인502 Bad Gateway 시 원인
프론트엔드 Jenkins → Traefik:443 Traefik에 websecure 라우트 없음
TLS 미설정
해당 없음
백엔드 Traefik → Harbor Pod 해당 없음 scheme: https 미설정
ServersTransport 미설정 (cert 검증 실패)
핵심: "Connection refused"는 프론트엔드 레이어 문제 — Traefik:443 포트에 Harbor 라우트가 없거나 TLS가 설정되지 않은 것. scheme/ServersTransport는 백엔드 레이어 문제로 502를 유발하지 Connection refused를 유발하지 않음.

2 Connection refused 원인 후보 (3가지)

후보 1 — 가장 유력
IngressRoute에 websecure entrypoint 미선언
Harbor의 IngressRoute가 web(HTTP, :80) entrypoint만 선언하고 websecure(HTTPS, :443)가 없으면, Traefik:443은 열려 있지만 해당 호스트에 대한 HTTPS 라우트가 없어 연결이 거부된다.
⚠ IngressRoute: entryPoints: [web] 만 있고 websecure 없음
# 문제 있는 상태
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
spec:
  entryPoints:
    - web         # ← websecure 없음
  routes:
    - match: Host(`harbor.x.x.x.nip.io`)
      services:
        - name: harbor-core
          port: 80
후보 2
IngressRoute TLS 블록 없음
websecure entrypoint는 선언했지만 tls: {} 블록이 없으면 Traefik이 TLS handshake를 처리하지 못해 연결이 끊긴다. Jenkins 입장에서는 Connection refused처럼 보일 수 있다.
# 문제 있는 상태
spec:
  entryPoints:
    - websecure
  routes:
    - match: Host(`harbor.x.x.x.nip.io`)
      ...
  # tls: {} 블록 없음 ← 문제
후보 3
Docker daemon CA 미신뢰 (에러 메시지 오독 가능성)
실제 에러는 x509: certificate signed by unknown authority인데 Jenkins 로그에서 "connection refused"로 표시될 수 있다. TCP 연결은 성공하지만 TLS handshake에서 cert 검증 실패. 에러 로그 미확인 상태에서 배제 불가.
⚠ docker push 시 x509 에러 → Jenkins 로그 가공 시 "refused"로 보일 수 있음

3 scheme / ServersTransport 가설 분석

사용자 질문: "Ingress scheme에 https 미설정, ServersTransport 없어서 실패 가능성?"

결론: 이 두 설정은 백엔드 레이어(Traefik → Harbor Pod) 문제다. "Connection refused"를 설명하지 못한다. 단, Harbor Pod가 실제로 HTTPS-only로 동작한다면 연관된다.
설정 누락영향 레이어발생 에러Connection refused 관련?
scheme: https 없음 Traefik → Harbor 백엔드 502 Bad Gateway 관련 없음
ServersTransport 없음 Traefik → Harbor 백엔드 502 (cert 검증 실패) 관련 없음
websecure entrypoint 없음 Jenkins → Traefik 프론트엔드 Connection refused 직접 원인
단, 추후 고려 필요: 프론트엔드 문제를 고치고 나면 백엔드 레이어에서 scheme/ServersTransport 문제가 드러날 수 있다. Harbor Pod가 실제로 HTTPS 포트를 쓴다면 둘 다 설정 필요.

4 실제 원인 특정 — 진단 명령

① IngressRoute 설정 확인
# Harbor IngressRoute에 websecure + tls 있는지 확인
kubectl -n suse-private-registry get ingressroute -o yaml \
  | grep -E "entryPoint|tls|scheme"
② Jenkins 파드에서 직접 연결 테스트
# -k : cert 무시, -v : 상세 출력
kubectl -n jenkins exec -it <jenkins-pod> -- \
  curl -vk https://<HARBOR_IP>.nip.io/v2/ 2>&1 \
  | grep -E "Connected|refused|certificate|SSL|tls|handshake"

# 결과 판독
# "Connection refused"    → 포트/라우트 문제 (후보 1, 2)
# "SSL handshake failed"  → TLS 설정 문제 (후보 2)
# "certificate unknown"   → Docker CA 신뢰 문제 (후보 3)
# -k 없을 때만 실패        → CA 신뢰 문제 (후보 3)
③ Traefik 라우터 목록 확인
# Traefik API로 등록된 라우터 목록 조회
kubectl -n kube-system port-forward svc/traefik 9000:9000 &
curl http://localhost:9000/api/http/routers | jq '.[] | select(.rule | contains("nip.io")) | {name, rule, entryPoints, tls}'

5 수정 방법

후보 1 + 2 수정 — IngressRoute 재작성

# harbor-ingressroute.yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: harbor-https
  namespace: suse-private-registry
spec:
  entryPoints:
    - websecure        # ← HTTPS 443 entrypoint
  routes:
    - match: Host(`harbor.<IP>.nip.io`)
      kind: Rule
      services:
        - name: harbor-core
          port: 80             # Harbor pod 내부는 HTTP
  tls:                         # ← TLS 블록 필수
    secretName: tls-secret     # self-signed cert Secret 이름
확인: kubectl -n suse-private-registry get secret tls-secret 로 시크릿 존재 확인 후 적용.

후보 3 수정 — Docker daemon CA 신뢰 등록

# Jenkins 노드에서 실행
kubectl -n suse-private-registry get secret tls-secret \
  -o jsonpath='{.data.tls\.crt}' | base64 -d > harbor-ca.crt

mkdir -p /etc/docker/certs.d/<IP>.nip.io
cp harbor-ca.crt /etc/docker/certs.d/<IP>.nip.io/ca.crt
# Docker 재시작 불필요 — certs.d는 런타임 반영

백엔드 레이어 (추후 필요 시) — ServersTransport 설정

# Harbor pod가 HTTPS-only일 경우만 필요
apiVersion: traefik.io/v1alpha1
kind: ServersTransport
metadata:
  name: harbor-transport
  namespace: suse-private-registry
spec:
  insecureSkipVerify: true   # self-signed cert 검증 스킵
---
# IngressRoute의 service에 추가
services:
  - name: harbor-core
    port: 443
    serversTransport: harbor-transport
    scheme: https
우선순위: 먼저 진단 명령으로 원인 특정 → IngressRoute 수정 (후보 1+2) → 여전히 실패하면 CA 등록 (후보 3) → 502 발생 시 ServersTransport 추가 순서로 적용.

6 결론 요약

항목내용
증상 HTTPS → Connection refused / HTTP → 정상
가장 유력한 원인 Harbor IngressRoute에 websecure entrypoint 또는 tls: 블록 없음
scheme/ServersTransport 가설 Connection refused와 무관 (백엔드 레이어, 502 유발). 프론트엔드 해결 후 별도 확인 필요.
확인 방법 curl -vk https://harbor.nip.io/v2/ 결과로 TCP vs TLS vs Cert 오류 구분
1순위 픽스 IngressRoute에 entryPoints: [websecure] + tls: secretName: tls-secret 추가
2순위 픽스 Jenkins 노드 /etc/docker/certs.d/에 Harbor CA 등록