개요
Jenkins를 운영하다 보면 빌드 및 배포 과정에서 다양한 Credentials을 사용하게 되는데, Credentials이 많아지면 수동으로 관리하기엔 번거롭고 보안상의 위험이 높아져 관리의 리스크가 커진다.
이러한 문제를 해결하기 위해 Jenkins의 Kubernetes Credentials Provider 플러그인과 External Secrets Operator(ESO)를 활용할 수 있는데, ESO를 통해 AWS Secrets Manager, HashiCorp Vault, Google Secret Manager와 같은 외부 비밀 저장소와 Kubernetes Secret을 자동으로 동기화하여 Credentials를 보다 안전하고 효율적으로 관리할 수 있다.
아래 그림은 External Secrets Operator(ESO)가 IRSA(IAM Roles for Service Accounts)를 활용하여 AWS Secrets Manager에 접근할 수 있는 권한을 얻고, 저장된 Secret 값을 가져와 Kubernetes Secret을 생성한 후, 이를 기반으로 Jenkins에서 Kubernetes Credentials Provider 플러그인을 사용하여 Jenkins Credentials를 자동으로 동기화하는 과정을 보여준다.

본 글에서는 실습을 통해 위 그림과 같이 구성하는 과정을 다룬다.
구성 환경
- Amazon EKS: 1.30
- Helm CLI: 3.17.2
- Jenkins: 2.480
- ESO Helm Chart APP : 0.15.0
설치 버전
- Jenkins Plugin
- Kubernetes Credentials Provider : 1.276.v99a_de03cb_076
전제 조건
- Jenkins 구성
- ESO 구성 (External Secrets Operator)
- Amazon EKS 클러스터
- Kubectl, Helm CLI 도구
1. Kubernetes Credentials Provider 플러그인 설치
먼저, Kubernetes 클러스터에 저장된 Secret을 Jenkins에서 사용할 수 있도록 "Kubernetes Credentials Provider" 플러그인을 설치한다.
- Jenkins Dashboard > Jenkins 관리 > Plugins

플러그인 설치가 완료되면 Jenkins 재시작을 위해 다음과 같이 체크박스를 체크한다.

다음 경로로 이동하면 Kubernetes Store가 생성된 것을 확인할 수 있다.
- Jenkins Dashboard > Jenkins 관리 > Credentials

이제부터 Kubernetes Secrets에 추가 설정을 하면, 해당 설정이 Kubernetes Store Credentials에 자동으로 등록된다.
2. ESO(External Secrets Operator) 설정 & Kubernetes Secrets 생성
AWS Secrets Manager를 통해 Kubernetes Secrets이 생성될 수 있도록 ESO 관련 구성을 해야 한다.
AWS Secrets Manager와 연결하기 위해 다음과 같이 ClusterSecretStore 리소스를 배포한다.
apiVersion: external-secrets.io/v1beta1
kind: ClusterSecretStore
metadata:
name: secretstore-sample-test
spec:
provider:
aws:
service: SecretsManager
region: ap-northeast-2
auth:
jwt:
serviceAccountRef:
name: external-secrets
namespace: external-secrets
ClusterSecretStore 리소스가 정상적으로 생성되었는지 확인한다.
$ kubectl get clustersecretstores.external-secrets.io
NAME AGE STATUS CAPABILITIES READY
secretstore-sample-test 9s Valid ReadWrite True
AWS Secrets Manager의 Secret이 생성될 수 있도록 ExternalSecret 리소스를 배포한다.
아래 YAML에서 각 환경에 맞는 AWS Secrets Manager 이름과 Key Name을 입력해야 한다.
target의 template 하위 내용은 앞서 설치한 Jenkins의 "Kubernetes Credentials Provider 플러그인"을 사용하여 Jenkins Credentials를 생성하는 방법이다.
- labels: Jenkins Credentials 타입을 입력한다. usernamePassword, secretText 등을 설정할 수 있다.
- annotations: Jenkins Credentials의 description 내용을 입력한다.
방법 1
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: example
namespace: jenkins
spec:
refreshInterval: 1m
secretStoreRef:
name: secretstore-sample-test
kind: ClusterSecretStore
target:
name: secrets-manager-key1
template:
metadata:
labels:
"jenkins.io/credentials-type": "secretText"
annotations:
"jenkins.io/credentials-description": "Secrets Manager Key"
data:
text: "{{ .key }}"
data:
- secretKey: key
remoteRef:
key: {AWS Secret Manager name}
property: {AWS Secret Manager key name}
방법 2
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: example
namespace: jenkins
spec:
refreshInterval: 1m
secretStoreRef:
name: secretstore-sample-test
kind: ClusterSecretStore
target:
name: secrets-manager-key1
template:
metadata:
labels:
"jenkins.io/credentials-type": "secretText"
annotations:
"jenkins.io/credentials-description": "Secrets Manager Key"
data:
text: "{{ .AWS_Secret_Manager_key_name }}"
dataFrom:
- extract:
key: {AWS Secret Manager name}
참고
Kubernetes Secrets에서 labels과 annotations 설정을 통해 Credentials을 사용하는 방법에 대한 다양한 예제는 여기를 참고한다.
ExternalSecret 리소스 생성 후 target의 name에 지정한 이름으로 Kubernetes Secret이 생성되었는지 확인한다.
$ kubectl get secrets -n jenkins secrets-manager-key1
NAME TYPE DATA AGE
secrets-manager-key1 Opaque 1 11m
Kubernetes Secret의 내용을 확인하고, 실제 AWS Secrets Manager의 정보와 동일한지 비교한다.
$ kubectl get secrets -n jenkins secrets-manager-key1 -ojsonpath="{.data.text}" | base64 -d
3. Jenkins Credentials 확인 및 검증
ExternalSecret 리소스에서 설정한 내용에 맞게 Jenkins Credentials가 생성되었는지 확인해 보자.
다음 경로로 이동하여 확인한다.
- Jenkins Dashboard > Jenkins 관리 > Credentials

설정에 맞게 Kubernetes Store에 Credentials이 생성된 것을 확인할 수 있다.
생성된 Jenkins Credentials이 실제 AWS Secrets Manager의 정보와 동일한지 확인해 보자.
Credentials 값은 기본적으로 파이프라인에서 마스킹(***) 되어 표시되기 때문에 직접 확인할 수 없다.
하지만 Jenkins에서 제공하는 "Script Console"을 사용하면 이를 확인할 수 있다.
Script Console
Script Console은 Jenkins 서버에서 Groovy 스크립트를 실행할 수 있는 도구이다. 관리자 권한을 가진 사용자만 접근할 수 있으며, Jenkins 인스턴스의 상태를 확인하고 설정 변경 및 문제를 디버깅하는 데 사용될 수 있다.
Groovy 스크립트를 다음과 같이 입력 후 실행하면, Credentials에 설정된 값을 확인할 수 있다. 각 환경에 맞는 Credentials ID를 입력 후 실행하면 된다.
- Jenkins Dashboard > Jenkins 관리 > Script Console
import com.cloudbees.plugins.credentials.CredentialsProvider
import jenkins.model.Jenkins
import org.jenkinsci.plugins.plaincredentials.StringCredentials
import hudson.util.Secret
def allCredentials = CredentialsProvider.lookupCredentials(
com.cloudbees.plugins.credentials.Credentials.class,
Jenkins.instance,
null,
[]
)
allCredentials.each { cred ->
if (cred instanceof StringCredentials && cred.id == '{Credentials ID 입력}') {
println "ID: ${cred.id}"
println "Type: ${cred.getClass().simpleName}"
println "Value: ${cred.secret.plainText}"
println "-------------------"
}
}
결과는 Value 항목에서 확인할 수 있다.

값이 일치한 지 확인한 후 AWS Secrets Manager에서 값을 변경하고 앞서 실행한 Groovy 스크립트를 다시 실행하면 변경된 값이 출력되는 것을 확인할 수 있을 것이다.
'CICD > Jenkins' 카테고리의 다른 글
Jenkins로 가상 머신(VM) 환경에 배포하기 (with Pipeline) (0) | 2024.06.20 |
---|---|
Jenkins란? 개념부터 설치 실행까지 (쿠버네티스 환경) (0) | 2023.12.23 |
댓글