현재 회사에서는 AWS의 Athena
와 QuickSight
를 통해 데이터를 정제 및 시각화 하고 있다.
하지만, 해당 서비스들의 비용 발생과 Athena
를 통해 테이블을 조회할 때 속도가 느린 점을 보완하기 위해 Redash
의 도입을 고려하게 되었다.
Redash
는 데이터 시각화 도구이다.
다양한 Database
를 소스로 연결하고, 해당 Database
에 대한 쿼리를 수행할 수 있으며, 쿼리문의 결과를 그래프 형태로 나타나는 시각화가 가능하다.
Redash
를 설치하는 방법은 크게 두 가지가 있다.
우리는 현재 AWS EKS
를 통해 서비스를 제공하고 있으며, 현재 제공하고 있는 서비스나 트래픽 대비 Worker Node
의 리소스를 여유롭게 잡아둔 상태였기 때문에 Container
를 통해 Kubernetes
위에 서비스를 올리는 방법을 선택하였다.
Kubernetes
에 Redash
를 설치하기 위해서는 redash-helm-chart링크의 HelmChart
를 통해 배포하였다.
위의 이미지는 Redash
공식 사이트에서 제공하고 있는 스타팅 가이드 공식 문서인데, 해당 문서를 보면 각종 퍼블릭 클라우드의 이미지나 Docker
를 통한 설치 방법은 제시되어 있지만 Kubernetes
에 배포하는 방법에 대해서는 명시되어 있지 않다.
설치에 사용한 차트는 Redash
에서 공식적으로 배포하는 차트는 아니기 때문에 향후 공식적으로 지원하는 차트가 생기거나, 다른 방식으로 설치를 할 수 있다면 굳이 해당 HelmChart
를 통해서 설치하지 않아도 된다.
해당 HelmChart
를 통해 Redash
를 배포하기 위해서는 몇 가지 전제조건이 필요하다.
Redash
를 설치할 클러스터가 PV
를 지원해야 한다.Redash
는 데이터베이스, 유저, 쿼리 정보를 PostgreSQL
에 저장하기 때문에 PostgreSQL
이 준비되어야 한다.사실 2번의 경우 HelmChart
를 통해 설치할 경우 뿐 아니라 모든 경우에 해당하며, 해당 HelmChart
는 PostgreSQL
을 StatefulSet
컨트롤러를 이용해 Pod
로 생성해 사용하기 때문에 크게 신경써야 할 사항은 아니다.
하지만, 만약 해당 PostgreSQL Pod
에 문제가 생겼을 경우 데이터베이스, 유저, 쿼리 정보가 모두 날아갈 수 있기 때문에 해당 Pod
의 정보를 안전하게 저장하기 위해 PV
를 제공하는 클러스터 위에서 운영하는것이 좋다.
우리의 경우 실제로 데이터분석가나 마케팅담당자 등이 해당 툴을 실제로 사용할 예정이었기 때문에 데이터베이스, 유저, 쿼리 등의 정보를 PV
를 통해 볼륨에 저장하는 형태가 아닌 RDS
를 통해 PostgreSQL
데이터베이스를 생성하고 external PostgreSQL
로 설정하여 데이터를 관리하였다.
# HelmChart clone
$ git clone https://github.com/pedaling/redash-helm-chart.git
$ cd redash-helm-chart
먼저 위의 HelmChart Repository
를 로컬 환경에 clone한 뒤, redash-helm-chart
디렉토리로 이동한다.
해당 디렉토리에는 Values.yaml
이라는 파일을 찾을 수 있는데 이 Values.yaml
파일을 수정하여 환경을 설정해준다.
# 설정 파일 수정
$ vi values.yaml
...
# Redash 시크릿 값 설정
redash:
cookieSecret: $(openssl rand -base64 32)
secretKey: $(openssl rand -base64 32)
...
# 외부 PostgreSQL 기능 활성화
# postgresql://user:pass@host:5432/database 형태로 DB 정보 입력
# 현재 설치시 Data Engineer가 데이터 분석용으로 사용중인 Production 환경 PostgreSQL 설정
externalPostgreSQL: {PostgreSQL 정보}
...
# Pod를 통해 생성되는 PostgreSQL 비활성화
postgresql:
enable: false
...
# Redis 비밀번호 설정
redis:
password: "비밀번호 설정"
...
# Redash Web 서비스 설정
service:
annotations: # VPN을 통해 접속 가능하도록 Private Network Loadbalancer 설정 어노테이션 추가
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: instance
service.beta.kubernetes.io/aws-load-balancer-type: external
# 외부 노출 필요시 추가
# service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing"
type: LoadBalancer # 기본값 ClusterIP에서 LoadBalancer로 변경
기본적으로 해당 HelmChart
에서 대부분의 설정은 완료된 상태이기 때문에 우리는 최소한의 수정을 통해 적합한 환경의 Redash
를 설치해야 한다.
먼저 Redash
의 시크릿 값을 설정해야 한다. 이 값은 구축 이후 현재까지 실제로 사용할 일은 없었기 때문에 위와 같이 openssl
을 통해 랜덤하게 생성해 주었다.
다음으로 externalPostgreSQL
값을 설정해준다. 이 값은 RDS
나 다른 방법을 통해 생성한 PostgreSQL
데이터베이스의 접근정보를 입력해주면 된다.
postgresql://{user}:{password}@{host}:{port}/{schemaName}
의 형태로 데이터베이스에 접근할 수 있는 모든 정보를 제공해야 한다.
아래의 postgrelsql.enable
값을 false로 바꾸는 것은 Pod
를 통해 PostgreSQL
을 DaemonSet
으로 올리지 않게 해준다.
마지막으로 service
부분에서는 Redash
웹 콘솔을 외부에 어떻게 노출시킬 것인지를 정의한다.
기본값은 ClusterIP
로 되어 있는데, NodePort
, LoadBalancer
, Ingress
등을 통해 외부에 노출시킬 수 있다.
우리의 경우 최초에는 간편하게 로드밸런서로 변경하여 배포하였고, 어노테이션을 통해 AWS NLB
로 배포하였다.
service:
# service.annotations -- Annotations to add to the service
annotations: {}
# service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: instance
# service.beta.kubernetes.io/aws-load-balancer-type: external
# service.loadBalancerIP -- Specific IP address to use for cloud providers such as Azure Kubernetes Service [ref](https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer)
loadBalancerIP:
# service.type -- Kubernetes Service type
type: ClusterIP
# service.port -- Service external port
port: 80
ingress:
# ingress.enabled -- Enable ingress controller resource
enabled: true
# ingress.annotations -- Ingress annotations configuration
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internal
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP":80, "HTTPS":443}]'
alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/healthcheck-path: /healthcheck
alb.ingress.kubernetes.io/healthcheck-protocol: HTTP
alb.ingress.kubernetes.io/healthcheck-port: "80"
alb.ingress.kubernetes.io/certificate-arn: "{ACM 인증서 arn값}"
alb.ingress.kubernetes.io/subnets: {서브넷1}, {서브넷2}, ... {서브넷N} # 해당 로드밸런서가 배포될 서브넷의 id 정보
meta.helm.sh/release-name: {helm release 이름}
meta.helm.sh/release-namespace: {배포 Namespace}
alb.ingress.kubernetes.io/target-group-attributes: deregistration_delay.timeout_seconds=30
# ingress.ingressClassName -- Sets the ingress controller class name to use.
ingressClassName: ""
# ingress.hosts -- Ingress resource hostnames and path mappings
hosts:
- host: {Ingress로 설정할 도메인 이름}
paths: ["/"]
하지만, 인증서 적용 및 VPN을 통한 접근을 위해 위와 같이 Ingress
의 형태로 변경하였다.
EKS
환경에서 Ingress
를 통해 배포하기 위해서는 Nginx Ingress Controller
를 설치하거나, AWS LoadBalancer Controller
(구 AWS ALB Ingress Controller
)를 설치해 주어야 한다. (링크 참조)
위와 같이 service
부분을 원래대로 복원하고 ingress.enabled
값을 true로 바꾼 뒤 원하는 어노테이션 또는 host 정보를 설정해주었다.
ingressClassName
의 경우 여러개의 Ingress Controller
가 설치되어 있을 경우 kubectl get ingressclass
를 검색해 원하는 Ingres
를 지정해 줄 수 있다.
이렇게 설정 후 배포를 진행한뒤 배포된 서비스를 확인해보자.
$ helm upgrade --install -f values.yaml redash redash/redash
# 배포된 서비스 확인
$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/redash-adhocworker-698c69bc66-f6rms 1/1 Running 0 14d
pod/redash-f85d7df49-rb7bh 1/1 Running 0 14d
pod/redash-genericworker-58d54576fd-t4mq9 1/1 Running 0 14d
pod/redash-redis-master-0 1/1 Running 0 14d
pod/redash-redis-slave-0 1/1 Running 0 14d
pod/redash-redis-slave-1 1/1 Running 0 14d
pod/redash-scheduledworker-f97c9d466-q5r28 1/1 Running 0 14d
pod/redash-scheduler-85756f65d7-gn5f2 1/1 Running 3 (14d ago) 14d
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/redash ClusterIP 172.20.192.236 <none> 80/TCP 14d
service/redash-redis-headless ClusterIP None <none> 6379/TCP 14d
service/redash-redis-master ClusterIP 172.20.123.24 <none> 6379/TCP 14d
service/redash-redis-slave ClusterIP 172.20.70.76 <none> 6379/TCP 14d
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/grafana 1/1 1 1 78d
deployment.apps/redash 1/1 1 1 14d
deployment.apps/redash-adhocworker 1/1 1 1 14d
deployment.apps/redash-genericworker 1/1 1 1 14d
deployment.apps/redash-scheduledworker 1/1 1 1 14d
deployment.apps/redash-scheduler 1/1 1 1 14d
NAME DESIRED CURRENT READY AGE
replicaset.apps/redash-54fd7c7566 0 0 0 14d
replicaset.apps/redash-adhocworker-698c69bc66 1 1 1 14d
replicaset.apps/redash-adhocworker-7476f6fd6c 0 0 0 14d
replicaset.apps/redash-f85d7df49 1 1 1 14d
replicaset.apps/redash-genericworker-58d54576fd 1 1 1 14d
replicaset.apps/redash-genericworker-68d597fc67 0 0 0 14d
replicaset.apps/redash-scheduledworker-58f4cd85b7 0 0 0 14d
replicaset.apps/redash-scheduledworker-f97c9d466 1 1 1 14d
replicaset.apps/redash-scheduler-64f465fb8b 0 0 0 14d
replicaset.apps/redash-scheduler-85756f65d7 1 1 1 14d
NAME READY AGE
statefulset.apps/redash-redis-master 1/1 14d
statefulset.apps/redash-redis-slave 2/2 14d
NAME COMPLETIONS DURATION AGE
job.batch/prd-mgmt-redash-install 0/1 61d 61d
# Ingress 정보 확인
$ kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
redash <none> redash.xxxx.xx internal-{로드밸런서 정보} 80 14d
배포 후에는 위와 같이 Pod
들과 Ingress
정보를 확인할 수 있는데, Ingress
의 Address
부분의 도메인으로 Redash
콘솔에 접근할 수 있다.
해당 도메인에 최초 접근시 Admin
계정을 설정할 수 있으며, 설정 완료 후에는 해당 계정으로 위 화면에서 로그인을 진행하면 된다.