GitLab Linux 패키지 배포에 OpenBao 설치
GitLab v19.4Offering: GitLab Self-Managed
요약
Linux 패키지로 설치한 GitLab 인스턴스와 함께 OpenBao 를 실행하려면 Kubernetes 클러스터를 사용합니다. 이 정보는 GitLab 19.2 이상에 적용됩니다. OpenBao 는 다음 두 가지 방식 중 하나로 실행합니다.
Linux 패키지로 설치한 GitLab 인스턴스와 함께 OpenBao 를 실행하려면 Kubernetes 클러스터를 사용합니다. OpenBao 는 클러스터에서 실행되며 PostgreSQL 데이터베이스에 연결됩니다. GitLab Rails 와 Sidekiq 는 HTTPS 로 OpenBao 에 연결합니다.
이 정보는 GitLab 19.2 이상에 적용됩니다. GitLab 19.0 과 19.1 의 경우 사용 중인 GitLab 버전에 해당하는 이 페이지를 문서 아카이브에서 참고합니다.
OpenBao 는 다음 두 가지 방식 중 하나로 실행합니다.
- 코로케이티드 클러스터(Colocated cluster): 로컬 Kubernetes 배포판(예: k3s)이 Linux 패키지 인스턴스와 같은 호스트에서 실행됩니다. Linux 패키지에 번들된 NGINX 가 OpenBao 외부 URL 의 TLS 를 종료하는 리버스 프록시 역할을 합니다. GitLab 애플리케이션은 Kubernetes 가 공유 네트워크에 노출하는 엔드포인트를 통해 OpenBao 에 연결합니다.
- 외부 Kubernetes 클러스터(External Kubernetes cluster): OpenBao 가 별도의 Kubernetes 클러스터에서 실행됩니다. 클러스터 Ingress 와 TLS 종료는 직접 설계합니다. GitLab Rails 와 Sidekiq 는 노출한 OpenBao URL 에 연결합니다. 멀티 노드 Linux 패키지 배포를 사용하거나 클라우드 공급자의 관리형 Kubernetes 서비스를 사용하려는 경우 이 방식을 고려합니다.
이 설치 절차에서는 OpenBao 전용 PostgreSQL 인스턴스를 프로비저닝합니다. GitLab 이 사용하는 PostgreSQL 인스턴스와 분리된 자체 관리형 또는 관리형 PostgreSQL 서비스를 사용합니다. 자세한 내용은 이슈 7292를 참고합니다.
사전 요구 사항#
- 관리자 액세스 권한이 있고 Linux 패키지로 설치한 GitLab 19.2 이상.
- 같은 호스트에 설치된 로컬 Kubernetes 배포판.
- 호스트에서 사용할 수 있는
helm과kubectl. - OpenBao 도메인을 호스트의 공개 IP 주소로 지정하는 DNS 레코드.
- 관리자 액세스 권한이 있고 Linux 패키지로 설치한 GitLab 인스턴스.
- Linux 패키지 인스턴스 노드에서 액세스할 수 있는 외부 Kubernetes 클러스터.
- 클러스터에 액세스하도록 구성된
helm과kubectl. - OpenBao 도메인을 클러스터 Ingress IP 주소로 지정하는 DNS 레코드.
요구 사항#
OpenBao 를 설치하기 전에 Kubernetes 배포판이 다음 요구 사항을 충족하는지 확인합니다.
- Linux 패키지 인스턴스의 요구 사항과 Kubernetes 클러스터의 요구 사항에 더해 OpenBao 사이징 권장 사항도 충족해야 합니다.
- 코로케이티드 Kubernetes 안의 어떤 것도 GitLab 이 이미 사용하는 포트에 연결을 시도해서는 안 됩니다. 작은 Kubernetes 배포판 중에는 기본적으로 80번과 443번 포트에 바인딩되는 로드 밸런서를 설치하는 것이 많습니다. Linux 패키지가 관리하는 NGINX 가 이미 그 포트에서 수신 대기하므로 이러한 컴포넌트는 비활성화합니다.
- 코로케이티드 Kubernetes 는 Linux 패키지 인스턴스와 네트워크를 공유해야 합니다. 그래야 Linux
패키지가 관리하는 NGINX 가 외부 OpenBao 트래픽을 OpenBao 서비스로 라우팅하고 그 서비스에서 오는
요청을 수신할 수 있습니다. 공유 네트워크 안에서 양쪽에 도달할 수만 있다면 Linux 패키지 인스턴스는 서비스가 Kubernetes
LoadBalancer로 노출되는지NodePort로 노출되는지 상관하지 않습니다.
OpenBao 를 설치하기 전에 구성이 다음 요구 사항을 충족하는지 확인합니다.
- Kubernetes 클러스터가 OpenBao 사이징 권장 사항을 충족해야 합니다.
- 클러스터의 OpenBao Pod 와 Linux 패키지 인스턴스 노드 사이에 네트워크 연결이 있어야 합니다. 이 연결을 어떻게 구성할지는 인프라에 따라 다릅니다. 예를 들어 VPC 피어링, 공유 VPC, 방화벽 규칙을 사용할 수 있습니다. GitLab Rails 와 Sidekiq 는 클러스터에서 노출한 OpenBao URL 에 도달할 수 있어야 합니다.
- PostgreSQL 인스턴스는 클러스터 Pod CIDR 에서 오는 TCP 연결을 수락해야 합니다. 데이터베이스 포트에서 이 트래픽을 허용하도록 방화벽 또는 보안 그룹 규칙을 구성합니다.
프로덕션으로 넘어가기 전에, 특히 컴포넌트가 여러 호스트에 걸쳐 있는 경우 배포에 대한 추가 권장 사항으로 보안 강화를 검토합니다.
시작하기 전에#
시작하기 전에 다음을 수행합니다.
- Kubernetes CNI(Pod 네트워크)의 CIDR 를 수집합니다. 이후 PostgreSQL 인증을 구성할 때 필요합니다.
- Linux 패키지 인스턴스와 Kubernetes 가 공유하는 네트워크 인터페이스의 IP 주소
(
)를 수집합니다. 이후 여러 구성 값에 필요합니다. - OpenBao 설치를 시도하기 전에 Kubernetes 배포판이 완전히 실행 중인지 확인합니다.
kubectl컨텍스트가 이 클러스터로 설정되어 있는지(KUBECONFIG가 올바르게 구성되어 있는지) 확인합니다.
시작하기 전에 다음을 수행합니다.
- Kubernetes Pod 네트워크의 CIDR 를 수집합니다. 이후 PostgreSQL 인증을 구성할 때 필요합니다.
- OpenBao 가 사용하는 PostgreSQL 인스턴스의 주소
(
)를 수집합니다. - OpenBao 설치를 시도하기 전에 Kubernetes 클러스터가 완전히 실행 중인지 확인합니다.
kubectl컨텍스트가 이 클러스터로 설정되어 있는지(KUBECONFIG가 올바르게 구성되어 있는지) 확인합니다.
OpenBao PostgreSQL 데이터베이스 프로비저닝#
OpenBao 에는 자체 PostgreSQL 데이터베이스가 필요합니다. GitLab 을 구성하기 전에 외부 또는 관리형 PostgreSQL 인스턴스에 이 데이터베이스를 프로비저닝합니다.
OpenBao PostgreSQL 데이터베이스를 프로비저닝하려면 다음을 수행합니다.
-
OpenBao 데이터베이스 사용자에게 사용할 강력한 비밀번호를 선택합니다. 이 절의 마지막 단계에서 Kubernetes 시크릿에 같은 비밀번호를 사용합니다.
-
OpenBao 데이터베이스 사용자를 만듭니다.
psql -h -U <admin_user> \ -c "CREATE USER openbao WITH PASSWORD '<strong-password>';" -
OpenBao 데이터베이스를 만듭니다.
psql -h -U <admin_user> \ -c "CREATE DATABASE openbao OWNER openbao;" -
Kubernetes 네임스페이스와, Helm 차트에 데이터베이스 비밀번호를 전달하는 시크릿을 만듭니다. 시크릿 이름과 키는 생성된 Helm 값 파일과 일치해야 합니다.
kubectl create namespace openbao kubectl create secret generic openbao-db-password \ --namespace openbao \ --from-literal=password='<strong-password>'
GitLab 구성#
GitLab 호스트의 /etc/gitlab/gitlab.rb 에 다음을 추가하고, 자리표시자 값을
실제 IP 주소와 도메인으로 바꿉니다.
# PostgreSQL: accept TCP connections from Kubernetes pods.
# Use the shared network IP to restrict exposure to the shared network.
# Using '0.0.0.0' makes PostgreSQL listen on all interfaces, including public ones.
postgresql['listen_address'] = ''
# Local GitLab services (Rails, container registry) connect to the shared
# network IP address over TCP instead of the Unix socket, so include it in
# the trusted CIDR blocks.
postgresql['trust_auth_cidr_addresses'] = %w[127.0.0.1/32 ::1/128 /32]
# Kubernetes pods authenticate with a password.
# Replace 10.42.0.0/16 with the CIDR of your Kubernetes CNI (pod network).
postgresql['md5_auth_cidr_addresses'] = %w[10.42.0.0/16]
# Without this setting, NGINX routes all traffic on the shared IP to the
# OpenBao virtual host. Both virtual hosts must listen on the same addresses
# so NGINX can route by server name instead.
nginx['listen_addresses'] = ['*', '']
# OAK: OpenBao reverse proxy via GitLab NGINX.
oak['enable'] = true
oak['network_address'] = ''
oak['components']['openbao']['enable'] = true
# Replace 'https://openbao.example.com' with the URL of the DNS record
# you configured for OpenBao, which resolves to your host's public IP address.
oak['components']['openbao']['external_url'] = 'https://openbao.example.com'
# The internal URL that GitLab NGINX uses to reach the OpenBao service.
# If you use the service clusterIP, set a temporary value now and replace it after
# you install OpenBao. See the Helm installation step.
oak['components']['openbao']['internal_url'] = 'http://127.0.0.1:8200'
# The URL that the GitLab application uses to connect to OpenBao.
gitlab_rails['openbao'] = {
'url' => 'https://openbao.example.com'
}
이 구성에서 각 항목의 의미는 다음과 같습니다.
postgresql['listen_address']는 공유 네트워크 IP 입니다.trust_auth_cidr_addresses나md5_auth_cidr_addresses에 나열되지 않은 CIDR 에서 오는 연결은 PostgreSQL 이 거부합니다.postgresql['trust_auth_cidr_addresses']는 localhost 와 공유 네트워크 IP 를 포함하는 CIDR 블록 목록입니다. 이 블록에서 오는 연결에는 비밀번호가 필요하지 않습니다. 로컬 GitLab 서비스가 Unix 소켓 대신 TCP 로 이 IP 에 연결하므로 공유 네트워크 IP 가 필요합니다.postgresql['md5_auth_cidr_addresses']는 Pod CIDR 에서 가져온 CIDR 블록 목록입니다. 이 블록에서 오는 연결에는 비밀번호가 필요합니다. 이 주소는 OpenBao Pod 가 사용합니다.nginx['listen_addresses']는 GitLab 과 OpenBao NGINX 가상 호스트가 수신 대기하는 주소를 지정합니다. NGINX 가 가장 구체적인 수신 주소를 우선하지 않고 서버 이름으로 요청을 라우팅하려면 두 가상 호스트가 같은 주소에서 수신 대기해야 합니다.oak['network_address']는 공유 네트워크 IP 입니다. NGINX listen 지시문에서 사용합니다.oak['components']['openbao']['internal_url']은 GitLab 애플리케이션이 OpenBao 와 통신하는 데 사용하는 URL 입니다.gitlab_rails['openbao']['url']은 GitLab 애플리케이션이 사용하는 OpenBao URL 입니다.
클러스터에서 OpenBao 가 노출되는 방식에 따라 내부 URL 을 선택합니다.
- 로드 밸런서 또는
nodePort. OpenBao 를 설치하기 전에 URL 을 알 수 있으므로 지금 설정해 한 번의 reconfigure 로 마칠 수 있습니다. 로드 밸런서를 사용하는 경우 내부 URL 이 로드 밸런서 IP 주소로 해석되도록 DNS 를 구성합니다. - 서비스
clusterIP.clusterIP는 Helm 이 서비스를 만든 뒤에만 할당됩니다. 지금은 임시internal_url을 설정하고 OpenBao 를 설치한 뒤에 업데이트합니다.
호스트 머신은 Kubernetes 클러스터 외부에서 내부 URL 의 IP 에 도달할 수 있어야 합니다.
선택한 에서 IP 를 할당하도록 클러스터를 구성합니다.
GitLab external_url 설정이 https:// 를 사용한다면 Let's Encrypt 가 이미 활성화되어 있습니다.
OpenBao external_url 스킴을 https:// 로 설정하는 것으로 충분합니다. GitLab 이
기존 Let's Encrypt 인증서에 OpenBao 도메인을 주체 대체 이름(Subject Alternative Name, SAN)으로
자동으로 추가합니다.
대신 사용자 지정 인증서를 사용하려면 다음을 추가합니다.
oak['components']['openbao']['ssl_certificate'] = '/etc/gitlab/ssl/openbao.example.com.crt'
oak['components']['openbao']['ssl_certificate_key'] = '/etc/gitlab/ssl/openbao.example.com.key'
각 GitLab 애플리케이션 노드의 /etc/gitlab/gitlab.rb 에 다음을 추가하고, 자리표시자 값을
실제 주소와 도메인으로 바꿉니다.
# The URL GitLab Rails uses to connect to OpenBao.
gitlab_rails['openbao'] = {
'url' => 'https://openbao.example.com'
}
Sidekiq 노드가 따로 있으면 각 Sidekiq 노드의 /etc/gitlab/gitlab.rb 에도 같은
gitlab_rails['openbao'] 설정을 추가합니다. 시크릿을 프로비저닝하는 Sidekiq 워커도
OpenBao 에 대한 액세스가 필요합니다.
외부 또는 관리형 PostgreSQL 인스턴스에 OpenBao 데이터베이스와 역할은 이미 만들었습니다. 자세한 내용은 OpenBao PostgreSQL 데이터베이스 프로비저닝을 참고합니다. 요구 사항에서 설명한 대로 클러스터 Pod CIDR 에서 오는 TCP 연결을 수락하도록 해당 인스턴스를 구성합니다.
구성 변경 사항 적용#
구성 변경 사항을 적용합니다.
sudo gitlab-ctl reconfigure
이 명령은 모든 구성을 한 번에 적용합니다.
- PostgreSQL 이 Kubernetes Pod 에서 오는 TCP 연결을 수락하기 시작합니다.
- NGINX 에 OpenBao 가상 호스트가 구성되며, TLS 종료와 HTTP 에서 HTTPS 로의 리다이렉트가 포함됩니다.
- 해당하는 경우 Let's Encrypt 인증서가 발급되거나 갱신됩니다.
- Helm 값 파일이
/etc/gitlab/openbao-helm-values.yaml에 생성됩니다.
oak['components']['openbao']['external_url'] 이나 oak['components']['openbao']['internal_url'] 이 설정되어 있지 않으면 reconfigure 가 실패합니다.
gitlab.rb 를 업데이트한 각 Rails 및 Sidekiq 노드에서 구성 변경 사항을 적용합니다.
sudo gitlab-ctl reconfigure
이렇게 하면 OpenBao URL 구성이 적용됩니다.
Helm 을 사용하여 OpenBao 설치#
Helm 을 사용하여 OpenBao 를 설치하려면 다음을 수행합니다.
-
GitLab Helm 리포지터리를 추가합니다.
helm repo add gitlab https://charts.gitlab.io helm repo update -
생성된 값 파일로 OpenBao 를 설치합니다.
helm upgrade --install openbao gitlab/openbao \ --namespace openbao \ --values /etc/gitlab/openbao-helm-values.yaml생성된 파일은 PostgreSQL 스토리지, 고가용성, JWT 초기화를 구성합니다. 코로케이티드 클러스터는 Linux 패키지가 관리하는 NGINX 를 통해 OpenBao 에 도달하므로
ingress,ui,gatewayRoute는 구성하지 않습니다.사용할 수 있는 모든 차트 옵션은 OpenBao Helm 차트 문서를 참고합니다.
-
선택 사항. 서비스
clusterIP를 내부 URL 로 사용하는 경우 지금 확정합니다. 할당된clusterIP를 읽습니다.kubectl -n openbao get svc openbao-active \ -o jsonpath='{.spec.clusterIP}'/etc/gitlab/gitlab.rb에 내부 URL 을 설정합니다.oak['components']['openbao']['internal_url'] = 'http://:8200'그다음 다시 reconfigure 를 실행합니다.
sudo gitlab-ctl reconfigure로드 밸런서나
nodePort내부 URL 을 사용하는 경우 GitLab 을 구성할 때 이미 URL 을 알 수 있으므로 이 단계는 필요하지 않습니다.
Helm 을 사용하여 OpenBao 를 설치하려면 다음을 수행합니다.
-
GitLab Helm 리포지터리를 추가합니다.
helm repo add gitlab https://charts.gitlab.io helm repo update -
다음 내용으로
openbao-values.yaml파일을 만들고, 자리표시자 값을 실제 도메인과 PostgreSQL 주소로 바꿉니다. 비밀번호는openbao-db-password시크릿에서 가져옵니다.config: ui: false storage: postgresql: haEnabled: true connection: host: "" port: 5432 database: openbao username: openbao password: secret: openbao-db-password key: password initialize: enabled: true oidcDiscoveryUrl: "https://" boundIssuer: "https://" boundAudiences: '"https://"' # The chart deploys a Kubernetes Ingress resource by default, which you need to provide the hostname to be reachable for GitLab Rails and Sidekiq # Alternatively, you could configure it to deploy an HTTPRoute resource, if you prefer to deploy a Gateway API controller. # # For available network ingress and TLS configuration options, see: # https://docs.gitlab.com/charts/charts/openbao/#ingress-and-tls-configuration-options ingress: enabled: true hostname: "" -
OpenBao 를 설치합니다.
helm upgrade --install openbao gitlab/openbao \ --namespace openbao \ --values openbao-values.yaml
사용할 수 있는 모든 차트 옵션은 OpenBao Helm 차트 문서를 참고합니다.
OpenBao 가 준비될 때까지 대기#
롤아웃이 완료될 때까지 기다립니다.
kubectl -n openbao rollout status deployment openbao
설치 확인#
설치를 확인하려면 다음을 수행합니다.
-
OpenBao 에 도달할 수 있는지 확인합니다.
curl "https://openbao.example.com/v1/sys/health"성공한 응답은 다음과 같습니다.
{ "initialized": true, "sealed": false, "standby": false, "version": "2.0.0" }
보안 강화#
다음 권장 사항은 프로덕션에서 Linux 패키지와 함께 OpenBao 를 실행할 때 위험을 줄이는 데 도움이 됩니다. 기반이 되는 제어 수단은 대부분 Kubernetes 배포판과 그 주변 인프라에서의 선택에 달려 있으며, 이는 GitLab 이 관리하지 않습니다.
일반적인 GitLab 강화 권장 사항은 GitLab 강화 권장 사항을 참고합니다.
컴포넌트 간 트래픽 암호화#
단일 호스트 코로케이티드 설치에서는 Rails, Sidekiq, OpenBao, PostgreSQL 사이의 트래픽이 호스트의 공유 네트워크에 머물고 호스트 밖으로 노출되지 않습니다. 토폴로지가 여러 호스트에 걸치는 순간(예: 외부 클러스터 또는 외부 PostgreSQL 인스턴스), 컴포넌트 사이의 암호화되지 않은 트래픽이 네트워크를 통해 이동하며 그 네트워크에 액세스할 수 있는 누구에게나 노출됩니다.
OpenBao 와 PostgreSQL 사이의 연결을 포함해 컴포넌트 간 트래픽은 다음 중 하나로 암호화합니다.
- 애플리케이션 계층 mTLS.
- 로드 밸런서 오프로딩을 사용하는 TLS.
- 전용 네트워크 계층.
멀티 노드 토폴로지에서는 Kubernetes Pod, 노드, Linux 패키지 노드 사이의 트래픽에 암호화가 적용됩니다. 환경에 적용되는 구성 단계는 Kubernetes 배포판, CNI, 데이터베이스 문서를 참고합니다.
Kubernetes 데이터스토어 암호화#
Kubernetes 데이터스토어(대부분의 배포판에서 etcd)는 기본적으로 Kubernetes Secret 객체를
암호화하지 않고 저장합니다. OpenBao Helm 차트는 봉인 해제 키를 Kubernetes Secret 으로
저장하므로, 데이터스토어가 침해되면 OpenBao 볼트 전체에 대한 액세스를 부여하는 키가
노출됩니다.
배포판에서 Kubernetes 시크릿에 대한 저장 데이터 암호화를 활성화합니다. 또는 봉인 해제 키가 Kubernetes 시크릿에 저장되지 않도록 키 관리 서비스(KMS)로 OpenBao 자동 봉인 해제를 구성합니다. 차트 옵션은 OpenBao Helm 차트 문서를 참고합니다.
Pod 에서 호스트로의 네트워크 액세스 제한#
Linux 패키지의 PostgreSQL 은 postgresql['md5_auth_cidr_addresses'] 에 설정한 Kubernetes Pod
CIDR 전체에서 오는 TCP 연결을 수락합니다. OpenBao 와 무관한 워크로드를 포함해 해당 클러스터에
스케줄된 어떤 Pod 든 공유 네트워크에서 PostgreSQL 과 NGINX 에 도달할 수 있습니다. PostgreSQL
비밀번호와 JWT 검증 같은 애플리케이션 계층 제어만이 다른 Pod 의 액세스로부터 이 서비스를
보호합니다.
이 노출을 줄이려면 다음을 수행합니다.
- 클러스터를 다른 워크로드와 공유한다면 Kubernetes
NetworkPolicy를 적용하는 CNI 를 사용합니다. 기본 CNI 를 쓰는 k3s 를 포함해 일부 배포판은 기본적으로NetworkPolicy를 적용하지 않습니다. postgresql['md5_auth_cidr_addresses']를 OpenBao Pod 를 포함하는 가장 작은 CIDR 로 좁힙니다.
Kubernetes API 서버 노출 제한#
여러 Kubernetes 배포판은 기본적으로 API 서버를 0.0.0.0 에 바인딩합니다.
노출된 API 서버는 클러스터로, 나아가 OpenBao 로 가는 직접 경로가 됩니다.
API 서버를 로컬 인터페이스나 공유 네트워크 IP 에 바인딩하고, 방화벽 또는 보안 그룹 규칙으로
도달 가능 범위를 제한합니다.