본문 바로가기
Devops/Kubernetes

[Kubernetes] Pgadmin4 Ingress 적용

by dev_ss 2024. 7. 7.

 

 

 

데이터베이스에 접속하여 관리를 할 수 있는 툴이 여러 가지 있는데, 사람들이 가장 많이 사용하는 툴로 Dbeaver가 있고, PostgreSQL 같은 경우 Pgadmin4라는 전용 툴도 따로 존재한다. (다른 예 : MySQL의 Workbench)

 

여기서 Pgadmin4 같은 경우, 웹으로 접속하여 설치형 애플리케이션과 동일하게 이용할 수 있는 컨테이너 이미지가 존재하고, 이를 쿠버네티스 Ingress를 적용하여 접속하는 방법을 알아볼 것이다.

 

 


문제점

 

Kubernetes에서 Ingress로 클러스터 내부의 서비스를 이용할 때, 일반적으로 애플리케이션 API는 Prefix에 오는 Path를 제거해 주는 방식으로 많이 이용하는데, 이는 구현된 API의 로직에 따라 에러가 발생할 수 있다.

 

Prefix를 제거하는 옵션에서 API에 Redirect와 같은 요소가 들어가 있으면, Prefix가 제거된 루트로 요청이 Redirect 되고, Prefix를 제거하지 않는 옵션에서는 해당 경로 그대로 API에 요청이 가는 등의 의도와 다른 경로로 요청이 가게 된다는 것이다.

 

이럴 때에는, API의 경로를 수정해 주거나, 환경변수를 지정(오픈소스 사용 시)해서 경로를 수정할 수 있다.

 

아래 예시를 통해 쿠버네티스 클러스터 내 pgadmin을 Statefulset으로 생성하고, Ingress설정을 한 후, 환경변수를 추가하여, Ingress를 정상적으로 이용하는 방법을 알아볼 것이다.

 


예제

 

아래는 pgadmin의 Statefulset의 yaml, 해당 파드로 매핑될 Service의 yaml, 그리고 서비스를 이용할 Ingress의 yaml이다.

 

 

관리자 이메일/비밀번호와 인그레스 클래스 이름은 세팅한 값에 따라서 지정해 주면 될 것이고, Ingress 경로는 알기 쉽게 /prefix/pgadmin으로 설정하였다.

 

# Statefulset Object
apiVersion: apps/v1
kind: StatefulSet
metadata:
 name: pgadmin
spec:
 replicas: 1
 updateStrategy:
   type: RollingUpdate
 selector:
   matchLabels:
     app: pgadmin
 template:
   metadata:
     labels:
       app: pgadmin
   spec:
     terminationGracePeriodSeconds: 10
     containers:
       - name: pgadmin
         image: dpage/pgadmin4:8.5
         imagePullPolicy: Always
         env:
         - name: PGADMIN_DEFAULT_EMAIL
           value: <관리자 계정의 이메일>
         - name: PGADMIN_DEFAULT_PASSWORD
           value: <관리자 계정의 비밀번호>
         ports:
         - name: http
           containerPort: 80
           protocol: TCP
---
# Service Object
apiVersion: v1
kind: Service
metadata:
  name: pgadmin
  labels:
    app: pgadmin
spec:
  ports:
  - port: 80
    targetPort: 80
  type: ClusterIP
  selector:
    app: pgadmin
---
# Ingress Object
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: pgadmin
  namespace: default
spec:
  ingressClassName: <인그레스 클래스 이름>
  rules:
  - http:
      paths:
      - backend:
          service:
            name: pgadmin
            port:
              number: 80
        path: /prefix/pgadmin
        pathType: Prefix

 

 

 

위 객체를 전부 생성하고 ExternalIP의 /prefix/pgadmin의 경로로 접속하면 아래와 같은 결과가 나올 것이다.

 

[접속 결과]

 

192.100.100.11/prefix/pgadmin으로 요청을 하였고, 404 에러를 나타낸다.

 

 

이는 실제로 Ingress 경로에서 서비스로 매핑이 정상적으로 되었고, 애플리케이션으로 요청이 도달하였으나, pgadmin에서는 /prefix/pgadmin이라는 Prefix경로가 그대로 전달이 되었고, 해당 경로의 API가 없기 때문에 발생하는 에러이다.

 

 

아래 pgadmin의 에러 로그를 통하여 확인할 수 있다.

 

+ 여기에 Prefix를 제거하는 작업(Nginx - Rewrite Path / Kong - Strip Path)을 해도 Base Path로 Redirect로 가게 되어 다른 에러가 발생한다.

 

 

 

 

이는 간단하게 해결이 가능한데, 아래와 같이 Statefulset의 yaml내에 환경변수를 추가하여 관련 설정을 하는 것으로 해결할 수 있다.

 

# 환경 변수가 추가된 Statefulset 내용
apiVersion: apps/v1
kind: StatefulSet
metadata:
 name: pgadmin
spec:
 replicas: 1
 updateStrategy:
   type: RollingUpdate
 selector:
   matchLabels:
     app: pgadmin
 template:
   metadata:
     labels:
       app: pgadmin
   spec:
     terminationGracePeriodSeconds: 10
     containers:
       - name: pgadmin
         image: dpage/pgadmin4:8.5
         imagePullPolicy: Always
         env:
         - name: PGADMIN_DEFAULT_EMAIL
           value: <관리자 계정의 이메일>
         - name: PGADMIN_DEFAULT_PASSWORD
           value: <관리자 계정의 비밀번호>
         # 추가된 환경 변수
         - name: SCRIPT_NAME
           value: /prefix/pgadmin
         ports:
         - name: http
           containerPort: 80
           protocol: TCP

 

 

 

SCRIPT_NAME이라는 환경 변수에 Prefix로 들어간 경로를 지정해 주는 것이다.

 

환경변수 내용을 추가하고 Object를 다시 만들어 주면, 정상적으로 접속이 가능한 것을 확인할 수 있다.

 

 

 

 

 

반응형