문제: "비밀을 제외한 모든 K8s 구성을 git에서 관리할 수 있습니다."
해결 방법: 공개 저장소 내부에도 안전하게 저장할 수 있는 SealedSecret로 비밀을 암호화하세요. SealedSecret은 대상 클러스터에서 실행되는 컨트롤러에 의해서만 해독될 수 있으며 다른 누구도(원 작성자도 포함) SealedSecret에서 원본 비밀을 얻을 수 없습니다.
개요
비밀을 위한 템플릿인 SealedSecrets
공개키/인증서
범위
설치
홈브류
MacPort
리눅스
소스에서 설치
사용자 정의
투구 차트
제어 장치
큐브실
치받이
용법
기존 비밀 관리
기존 비밀 패치
기존 비밀 업데이트
원시 모드(실험적)
봉인된 비밀 검증
비밀 순환
봉인키 갱신
사용자 비밀번호 순환
조기 키 갱신
키 갱신에 대한 일반적인 오해
수동 키 관리(고급)
재암호화(고급)
세부정보(고급)
암호화폐
개발 중
FAQ
더 이상 클러스터에 액세스할 수 없는 경우에도 여전히 암호를 해독할 수 있습니까?
SealedSecrets를 어떻게 백업할 수 있나요?
백업 키를 사용하여 오프라인에서 내 비밀을 해독할 수 있나요?
Kubeseal에는 어떤 플래그를 사용할 수 있나요?
봉인된 비밀로 암호화된 JSON/YAML/TOML/.. 파일의 일부를 어떻게 업데이트합니까?
내 (미리 생성된) 인증서를 가져올 수 있나요?
컨트롤러가 kube-system
네임스페이스 내에서 실행되고 있지 않은 경우 kubeseal을 어떻게 사용합니까?
이미지를 어떻게 확인하나요?
네임스페이스 하위 집합에 하나의 컨트롤러를 사용하는 방법
컨트롤러 봉인 해제 재시도를 구성할 수 있나요?
지역 사회
관련 프로젝트
봉인된 비밀은 두 부분으로 구성됩니다.
클러스터 측 컨트롤러/운영자
클라이언트측 유틸리티: kubeseal
kubeseal
유틸리티는 비대칭 암호화를 사용하여 컨트롤러만 해독할 수 있는 비밀을 암호화합니다.
이러한 암호화된 비밀은 SealedSecret
리소스에 인코딩되어 있으며, 이를 비밀 생성 방법으로 볼 수 있습니다. 그 모습은 다음과 같습니다.
apiVersion: bitnami.com/v1alpha1kind: SealedSecretmetadata: 이름: mysecret 네임스페이스: mynamespacespec: 암호화된Data: foo: AgBy3i4OJSWK+PiTySYZZA9rO43cGDEq.....
봉인이 해제되면 다음과 같은 비밀이 생성됩니다.
apiVersion: v1kind: Secretmetadata: name: mysecret 네임스페이스: mynamespacedata: foo: YmFy # <- base64로 인코딩된 "bar"
이 일반 kubernetes 비밀은 몇 초 후에 클러스터에 표시됩니다. 직접 생성한 비밀을 사용하는 것처럼 사용할 수 있습니다(예: Pod
에서 참조).
시작하고 실행하려면 설치 섹션으로 이동하세요.
사용법 섹션에서는 SealedSecret
리소스를 만드는 방법을 자세히 살펴봅니다.
이전 예는 암호화된 비밀 항목 자체에만 초점을 맞췄지만 SealedSecret
사용자 정의 리소스와 이것이 공개하는 Secret
사이의 관계는 여러 면에서(모두는 아니지만) 친숙한 Deployment
대 Pod
와 유사합니다.
특히 SealedSecret
리소스의 주석과 라벨은 생성된 보안 Secret
의 주석과 동일하지 않습니다.
이러한 구별을 포착하기 위해 SealedSecret
객체에는 컨트롤러가 봉인되지 않은 Secret
에 넣기를 원하는 모든 필드를 인코딩하는 template
섹션이 있습니다.
Sprig 함수 라이브러리는 기본 Go Text Template 함수 외에도 사용할 수 있습니다.
metadata
블록은 있는 그대로 복사됩니다(비활성화되지 않는 한 ownerReference
필드는 업데이트됨).
다른 비밀 필드는 개별적으로 처리됩니다. type
및 immutable
필드가 복사되고 data
필드는 Secret
의 복합 값을 템플릿화하는 데 사용될 수 있습니다. 다른 모든 필드는 현재 무시됩니다.
apiVersion: bitnami.com/v1alpha1kind: SealedSecretmetadata: 이름: mysecret 네임스페이스: mynamespace 주석: "kubectl.kubernetes.io/last-applied-configuration": ....spec: 암호화된 데이터: .dockerconfigjson: AgBy3i4OJSWK+PiTySYZZA9rO43cGDEq.... . 템플릿: 유형: kubernetes.io/dockerconfigjson immutable: true # 이것은 출력 비밀 메타데이터에 추가될 레이블 및 주석의 예입니다. labels: "jenkins.io/credentials-type": usernamePassword 주석: "jenkins.io/credentials-description ": Kubernetes의 자격 증명
컨트롤러는 이를 다음과 같이 풀어냅니다.
apiVersion: v1kind: Secretmetadata: 이름: mysecret 네임스페이스: mynamespace 라벨: "jenkins.io/credentials-type": usernamePassword 주석: "jenkins.io/credentials-description": Kubernetes ownerReferences의 자격 증명: - apiVersion: bitnami.com/v1alpha1 컨트롤러: true 종류: SealedSecret 이름: mysecret uid: 5caff6a0-c9ac-11e9-881e-42010aac003etype: kubernetes.io/dockerconfigjsonimmutable: truedata: .dockerconfigjson: ewogICJjcmVk...
보시다시피 생성된 Secret
리소스는 SealedSecret
의 "종속 개체"이므로 SealedSecret
개체가 업데이트되거나 삭제될 때마다 업데이트되고 삭제됩니다.
키 인증서(공개 키 부분)는 비밀을 봉인하는 데 사용되며 kubeseal
사용되는 모든 곳에서 사용할 수 있어야 합니다. 인증서는 비밀 정보가 아니지만 올바른 인증서를 사용하고 있는지 확인해야 합니다.
kubeseal
런타임 시 컨트롤러에서 인증서를 가져옵니다(Kubernetes API 서버에 대한 보안 액세스 필요). 이는 대화형 사용에 편리하지만 사용자 사이에 방화벽이 있는 비공개 GKE 클러스터와 같은 특수 구성의 클러스터가 있는 경우 불안정한 것으로 알려져 있습니다. 제어 평면 및 노드.
대체 워크플로우는 kubeseal --fetch-cert >mycert.pem
사용하여 인증서를 어딘가(예: 로컬 디스크)에 저장하고 kubeseal --cert mycert.pem
사용하여 오프라인으로 사용하는 것입니다. 인증서는 시작 시 컨트롤러 로그에도 인쇄됩니다.
v0.9.x 인증서는 30일마다 자동으로 갱신됩니다. 귀하와 귀하의 팀이 정기적으로 오프라인 인증서를 업데이트하는 것이 좋습니다. 이를 돕기 위해 v0.9.2 kubeseal
에서는 URL도 허용합니다. 신뢰할 수 있는 곳에 인증서를 게시하도록 내부 자동화를 설정할 수 있습니다.
kubeseal --cert https://your.intranet.company.com/sealed-secrets/your-cluster.cert
또한 SEALED_SECRETS_CERT
환경 변수도 인식합니다. (프로 팁: direnv도 참조하세요).
참고 : 우리는 암호화를 HSM 기반 모듈 또는 KMS와 같은 관리형 클라우드 암호화 솔루션으로 오프로드하는 키 관리 메커니즘을 제공하기 위해 노력하고 있습니다.
SealedSecrets는 최종 사용자의 POV에서 "쓰기 전용" 장치입니다.
SealedSecret은 대상 클러스터에서 실행되는 컨트롤러에 의해서만 해독될 수 있으며 다른 누구도(원 작성자도 포함) SealedSecret에서 원본 비밀을 얻을 수 없다는 아이디어입니다.
사용자는 대상 클러스터에 직접 액세스할 수도 있고 그렇지 않을 수도 있습니다. 더 구체적으로 말하면, 사용자는 컨트롤러에 의해 공개된 비밀에 액세스할 수도 있고 그렇지 않을 수도 있습니다.
k8s에서 RBAC를 구성하는 방법은 여러 가지가 있지만 권한이 낮은 사용자가 비밀을 읽지 못하도록 금지하는 것이 매우 일반적입니다. 또한 사용자에게 더 높은 권한이 있는 하나 이상의 네임스페이스를 제공하는 것이 일반적입니다. 이를 통해 사용자는 비밀을 생성하고 읽을 수 있습니다(및/또는 해당 비밀을 참조할 수 있는 배포를 생성할 수 있습니다).
암호화된 SealedSecret
리소스는 숨겨진 비밀에 대한 지식을 얻지 않고도 안전하게 볼 수 있도록 설계되었습니다. 이는 사용자가 액세스할 수 없는 네임스페이스에 대한 SealedSecret을 읽도록 허용할 수 없으며 비밀을 읽을 수 있는 네임스페이스에 복사본을 푸시하기만 하면 된다는 것을 의미합니다.
따라서 봉인된 비밀은 각 네임스페이스에 고유한 독립적인 암호화 키가 있는 것처럼 작동하므로 일단 네임스페이스에 대한 비밀을 봉인하면 다른 네임스페이스로 이동하거나 그곳에서 해독할 수 없습니다.
기술적으로 각 네임스페이스에 대해 독립적인 개인 키를 사용하지 않지만 대신 암호화 프로세스 중에 네임스페이스 이름을 포함하여 효과적으로 동일한 결과를 얻습니다.
게다가 네임스페이스는 RBAC 구성이 누가 어떤 비밀을 볼 수 있는지 결정할 수 있는 유일한 수준이 아닙니다. 실제로 사용자는 지정된 네임스페이스에서 foo
라는 비밀에 액세스할 수 있지만 동일한 네임스페이스의 다른 비밀에는 액세스할 수 없습니다. 따라서 기본적으로 사용자가 SealedSecret
리소스의 이름을 자유롭게 바꾸도록 허용할 수 없습니다. 그렇지 않으면 악의적인 사용자가 이름을 변경하여 사용자가 액세스할 수 있는 하나의 비밀을 덮어쓰기만 하면 해당 네임스페이스에 대한 SealedSecret의 암호를 해독할 수 있습니다. 암호화 키에 네임스페이스를 포함하는 데 사용된 것과 동일한 메커니즘을 사용하여 비밀 이름도 포함합니다.
즉, 이 수준의 보호에 관심이 없는 시나리오가 많이 있습니다. 예를 들어 클러스터에 액세스할 수 있는 유일한 사람은 관리자이거나 Secret
리소스를 전혀 읽을 수 없습니다. 봉인된 비밀을 다른 네임스페이스로 이동하는 사용 사례가 있을 수 있습니다(예: 네임스페이스 이름을 미리 모를 수 있음). 또는 비밀의 이름을 모를 수도 있습니다(예: 비밀의 해시를 기반으로 하는 고유한 접미사를 포함할 수 있음) 내용 등).
가능한 범위는 다음과 같습니다.
strict
(기본값): 비밀은 정확히 동일한 이름 과 네임스페이스 로 봉인되어야 합니다. 이러한 속성은 암호화된 데이터의 일부 가 되므로 이름 및/또는 네임스페이스를 변경하면 "암호 해독 오류"가 발생합니다.
namespace-wide
: 지정된 네임스페이스 내에서 봉인된 비밀의 이름을 자유롭게 바꿀 수 있습니다.
cluster-wide
: 비밀은 모든 네임스페이스에서 공개될 수 있고 어떤 이름도 부여될 수 있습니다.
이름 및 네임스페이스 제한과 달리 비밀 항목 (예: spec.encryptedData.my-key
와 같은 JSON 객체 키)은 봉인된 비밀을 해독하는 기능을 잃지 않고 마음대로 이름을 바꿀 수 있습니다.
범위는 --scope
플래그를 사용하여 선택됩니다.
kubeseal --scope 클러스터 전체sealed-secret.json
kubeseal
에 전달하는 입력 비밀의 주석을 통해 범위를 요청하는 것도 가능합니다.
sealedsecrets.bitnami.com/namespace-wide: "true"
-> namespace-wide
의 경우
sealedsecrets.bitnami.com/cluster-wide: "true"
-> cluster-wide
의 경우
이러한 주석이 없다는 것은 strict
모드를 의미합니다. 둘 다 설정된 경우 cluster-wide
우선 적용됩니다.
참고: 다음 릴리스에서는 이를 단일
sealedsecrets.bitnami.com/scope
주석으로 통합할 예정입니다.
최신 릴리스와 자세한 설치 지침은 https://github.com/bitnami-labs/sealed-secrets/releases를 참조하세요.
클라우드 플랫폼별 참고 사항 및 지침:
GKE
매니페스트를 배포하면 SealedSecret
리소스가 생성되고 컨트롤러가 kube-system
네임스페이스에 설치되며 서비스 계정과 필요한 RBAC 역할이 생성됩니다.
잠시 후 컨트롤러가 시작되고 키 쌍이 생성되며 작동 준비가 완료됩니다. 그렇지 않은 경우 컨트롤러 로그를 확인하십시오.
공식 컨트롤러 매니페스트 설치 메커니즘은 YAML 파일일 뿐입니다.
경우에 따라 사용자 정의 네임스페이스 설정 또는 일부 환경 변수 설정과 같은 자체 사용자 정의를 적용해야 할 수도 있습니다.
kubectl
이를 기본적으로 지원합니다. kustomize를 참조하세요.
Sealed Secrets 헬름 차트는 이제 이 GitHub 리포지토리에서 공식적으로 지원되고 호스팅됩니다.
helm repo에 봉인된 비밀 추가 https://bitnami-labs.github.io/sealed-secrets
참고: Helm 차트의 버전 관리 체계는 봉인된 비밀 프로젝트 자체의 버전 관리 체계와 다릅니다.
원래 조타 차트는 커뮤니티에 의해 유지 관리되었으며 첫 번째 버전은 메이저 버전 1을 채택했지만 봉인된 비밀 프로젝트 자체는 여전히 메이저 0입니다. 조타 차트 자체의 버전이 반드시 버전이 될 필요는 없기 때문에 괜찮습니다. 앱 자체의. 그러나 이는 혼란스럽기 때문에 현재 버전 관리 규칙은 다음과 같습니다.
SealedSecret
컨트롤러 버전 체계: 0.XY
조타 차트 버전 체계: 1.XY-rZ
따라서 정적 YAML 매니페스트 또는 컨트롤러 이미지 자체에 영향을 주지 않고 Helm 차트에만 적용되는 수정 사항을 포함하여 Helm 차트의 여러 개정판이 있을 수 있습니다.
참고: Helm 차트 추가 정보에는 여전히 사용 중단 알림이 포함되어 있지만 더 이상 현실을 반영하지 않으며 다음 릴리스에서 제거됩니다.
참고: 기본적으로 Helm 차트는
sealed-secrets
라는 이름의 컨트롤러를 설치하는 반면,kubeseal
명령줄 인터페이스(CLI)는sealed-secrets-controller
이름의 컨트롤러에 액세스하려고 시도합니다.--controller-name
CLI에 명시적으로 전달할 수 있습니다.
kubeseal --controller-name 봉인된 비밀
또는 차트를 설치할 때 fullnameOverride
설정하여 이름을 재정의할 수 있습니다. 또한 kubeseal
은 컨트롤러가 기본적으로 kube-system
네임스페이스 내에 설치되어 있다고 가정합니다. 따라서 예상 컨트롤러 이름과 네임스페이스를 전달하지 않고 kubeseal
CLI를 사용하려면 다음과 같이 Helm 차트를 설치해야 합니다.
helm install 봉인된 비밀 -n kube-system --set-string fullnameOverride=sealed-secrets-controller 봉인된 비밀/봉인된 비밀
일부 회사에서는 전체 클러스터가 아닌 단일 네임스페이스에만 액세스할 수 있습니다.
직면할 수 있는 가장 제한적인 환경 중 하나는 다음과 같습니다.
일부 service account
사용하여 namespace
할당되었습니다.
클러스터 CRD는 물론 클러스터의 나머지 부분에도 액세스할 수 없습니다.
네임스페이스에 추가 서비스 계정이나 역할을 생성하지 못할 수도 있습니다.
모든 배포에 리소스 제한을 포함해야 합니다.
이러한 제한 사항에도 불구하고 봉인된 비밀 Helm Chart를 설치할 수 있으며 전제 조건은 하나뿐입니다.
클러스터에는 이미 봉인된 비밀 CRD가 설치되어 있어야 합니다 .
관리자가 CRD를 설치한 후 아직 CRD가 없는 경우 다음과 같은 YAML 구성 파일을 준비하여 차트를 설치할 수 있습니다.
서비스계정: 생성: 거짓 이름: {할당 서비스 계정} rbac: 생성: 거짓 클러스터역할: false자원: 제한: CPU: 150m 메모리: 256Mi
참고:
서비스 계정은 생성되지 않으며 대신 할당된 서비스 계정이 사용됩니다.
{allocated-service-account}
클러스터에 할당된 service account
의 이름입니다.
네임스페이스나 클러스터에는 RBAC 역할이 생성되지 않습니다.
리소스 제한을 지정해야 합니다.
제한은 작동해야 하는 샘플이지만 특정 설정에서 검토할 수도 있습니다.
해당 파일이 준비되면 이름을 config.yaml
로 지정하면 이제 다음과 같이 봉인된 비밀 Helm Chart를 설치할 수 있습니다.
helm install 봉인된 비밀 -n {allocation-namespace} 봉인된 비밀/봉인된 비밀 --skip-crds -f config.yaml
여기서 {allocated-namespace}
는 클러스터에 할당된 namespace
의 이름입니다.
kubeseal
클라이언트는 homebrew에서도 사용할 수 있습니다.
양조 설치 kubeseal
kubeseal
클라이언트는 MacPorts에서도 사용할 수 있습니다.
포트 설치 kubeseal
kubeseal
클라이언트는 Nixpkgs에서도 사용할 수 있습니다: ( 면책 조항 : bitnami-labs에서 유지 관리하지 않음)
nix-env -iA nixpkgs.kubeseal
kubeseal
클라이언트는 아래 명령을 사용하여 Linux에 설치할 수 있습니다.
KUBESEAL_VERSION='' # 예를 들어 다음과 같이 설정합니다. KUBESEAL_VERSION='0.23.0'curl -OL "https://github.com/bitnami-labs/sealed-secrets/releases/download/v${KUBESEAL_VERSION:?} /kubeseal-${KUBESEAL_VERSION:?}-linux-amd64.tar.gz"tar -xvzf kubeseal-${KUBESEAL_VERSION:?}-linux-amd64.tar.gz kubeseal sudo install -m 755 kubeseal /usr/local/bin/kubeseal
컴퓨터에 curl
과 jq
설치되어 있으면 이 방법으로 버전을 동적으로 얻을 수 있습니다. 이는 자동화 등에 사용되는 환경에 유용할 수 있습니다.
# Fetch the latest sealed-secrets version using GitHub API KUBESEAL_VERSION=$(curl -s https://api.github.com/repos/bitnami-labs/sealed-secrets/tags | jq -r '.[0].name' | cut -c 2-) # Check if the version was fetched successfully if [ -z "$KUBESEAL_VERSION" ]; then echo "Failed to fetch the latest KUBESEAL_VERSION" exit 1 fi curl -OL "https://github.com/bitnami-labs/sealed-secrets/releases/download/v${KUBESEAL_VERSION}/kubeseal-${KUBESEAL_VERSION}-linux-amd64.tar.gz" tar -xvzf kubeseal-${KUBESEAL_VERSION}-linux-amd64.tar.gz kubeseal sudo install -m 755 kubeseal /usr/local/bin/kubeseal
여기서 KUBESEAL_VERSION
은 사용하려는 kubeseal 릴리스의 버전 태그입니다. 예: v0.18.0
.
최신 클라이언트 도구만 원할 경우 다음을 사용하여 $GOPATH/bin
에 설치할 수 있습니다.
github.com/bitnami-labs/sealed-secrets/cmd/kubeseal@main 설치로 이동하세요.
main
대신 릴리스 태그나 커밋 SHA를 지정할 수 있습니다.
go install
명령은 $GOPATH/bin
에 kubeseal
바이너리를 배치합니다.
$(go env GOPATH)/bin/kubeseal
클라이언트 도구 및/또는 컨트롤러를 업그레이드할 때 발생할 수 있는 주요 변경 사항에 대한 지침은 릴리스 노트를 확인하는 것을 잊지 마십시오.
현재 프로덕션 환경에서는 최신 버전의 Sealed Secrets만 지원됩니다.
Sealed Secrets 컨트롤러는 안정적인 Kubernetes API를 사용하여 다양한 버전의 Kubernetes와의 호환성을 보장합니다. 일반적으로 1.16 이상의 Kubernetes 버전은 호환되는 것으로 간주됩니다. 그러나 현재 권장되는 Kubernetes 버전을 공식적으로 지원합니다. 또한 1.24 이상의 버전은 릴리스할 때마다 CI 프로세스를 통해 철저한 검증을 거칩니다.
# 어떻게든 json/yaml로 인코딩된 비밀을 생성합니다:# (`--dry-run` 사용에 유의하세요 - 이것은 단지 로컬 파일입니다!)echo -n bar | kubectl create secret generic mysecret --dry-run=client --from-file=foo=/dev/stdin -o json >mysecret.json# 이것이 중요한 비트입니다:kubeseal -f mysecret.json -w mysealedsecret.json# 이 시점에서 mysealedsecret.json은 Github에 업로드하거나 # Twitter에 게시하는 등의 작업을 수행해도 안전합니다. # 결국:kubectl create -f mysealedsecret.json# 이익!kubectl은 비밀을 얻습니다 mysecret
SealedSecret
과 Secret
동일한 네임스페이스와 이름을 가져야 합니다. 이는 동일한 클러스터에 있는 다른 사용자가 봉인된 비밀을 재사용하는 것을 방지하는 기능입니다. 자세한 내용은 범위 섹션을 참조하세요.
kubeseal
입력 시크릿에서 네임스페이스를 읽고, 명시적인 --namespace
인수를 허용하고, kubectl
기본 네임스페이스를 해당 순서대로 사용합니다. 원본 Secret
의 모든 라벨, 주석 등은 보존되지만 SealedSecret
에 자동으로 반영되지는 않습니다.
설계상 이 체계는 사용자를 인증하지 않습니다 . 즉, 누구나 자신이 좋아하는 Secret
포함하는 SealedSecret
을 만들 수 있습니다(네임스페이스/이름이 일치하는 경우). 의도한 SealedSecret
만 클러스터에 업로드되는지 확인하는 것은 기존 구성 관리 워크플로, 클러스터 RBAC 규칙 등에 달려 있습니다. 기존 Kubernetes의 유일한 변경 사항은 이제 Secret
의 내용 이 클러스터 외부에 숨겨져 있다는 것입니다.
Sealed Secrets 컨트롤러가 기존 Secret
관리하도록 하려면 sealedsecrets.bitnami.com/managed: "true"
주석을 사용하여 Secret
주석을 달 수 있습니다. 이름과 네임스페이스가 동일한 SealedSecret
해제하면 기존 Secret
덮어쓰게 되며 SealedSecret
Secret
의 소유권을 갖게 됩니다(따라서 SealedSecret
이 삭제되면 Secret
도 삭제됩니다).
v0.23.0의 새로운 기능
전체 Secret
교체하지 않고 기존 Secret
에서 일부 키만 추가하거나 수정하는 사용 사례가 있습니다. 이를 위해 sealedsecrets.bitnami.com/patch: "true"
로 Secret
주석을 달 수 있습니다. 이 주석을 사용하면 SealedSecret
에 없는 Secret
의 비밀 키, 라벨 및 주석이 삭제되지 않고 SealedSecret
에 있는 것이 Secret
에 추가됩니다(존재하는 비밀 키, 라벨 및 주석). Secret
과 SealedSecret
모두 SealedSecret
에 의해 수정됩니다.
이 주석은 SealedSecret
이 Secret
의 소유권을 갖도록 만들지 않습니다. patch
와 managed
주석을 모두 추가하여 패치 동작을 얻으면서 Secret
의 소유권도 가져올 수 있습니다.
SealedSecret
과 Secret
이 독립적이기를 원하는 경우(즉, SealedSecret
삭제할 때 Secret
함께 사라지지 않음을 의미), 해당 비밀에 sealedsecrets.bitnami.com/skip-set-owner-references: "true"
주석을 달아야 합니다. sealedsecrets.bitnami.com/skip-set-owner-references: "true"
. SealedSecret
이 업데이트될 때 비밀이 업데이트되도록 sealedsecrets.bitnami.com/managed: "true"
Secret
에 추가할 수도 있습니다.
다른 항목에 대한 일반 텍스트 없이 기존 봉인된 비밀을 추가하거나 업데이트하려면 새 암호화된 데이터 항목을 복사하여 붙여넣고 기존 봉인된 비밀에 병합하면 됩니다.
업데이트된 항목을 호환 가능한 이름과 네임스페이스로 봉인해야 합니다(위의 범위에 대한 참고 사항 참조).
복사 및 붙여넣기를 원하지 않는 경우 --merge-into
명령을 사용하여 기존 봉인된 비밀을 업데이트할 수 있습니다.
에코 -n 바 | kubectl 비밀 생성 일반 mysecret --dry-run=client --from-file=foo=/dev/stdin -o json | kubeseal > mysealedsecret.jsonecho -n baz | kubectl 비밀 생성 일반 mysecret --dry-run=client --from-file=bar=/dev/stdin -o json | kubeseal --merge-into mysealedsecret.json
kubectl
명령을 사용하여 임시 보안 비밀을 생성한 후 kubeseal
에 파이프된 후에만 버리는 것은 상당히 비우호적인 사용자 경험이 될 수 있습니다. 우리는 CLI 환경을 전면적으로 점검하는 작업을 진행 중입니다. 그 동안 우리는 kubeseal이 stdout에 대한 값 암호화에만 관심을 갖고 이를 SealedSecret
리소스(다른 k8s 리소스와 다르지 않음)에 넣는 것은 사용자의 책임인 대체 모드를 제공합니다.
또한 편집기/IDE 통합을 위한 빌딩 블록으로도 유용할 수 있습니다.
단점은 봉인 범위, 네임스페이스 및 이름의 일관성을 유지하도록 주의해야 한다는 것입니다.
범위 보기
strict
범위(기본값):
$ 에코 -n foo | kubeseal --raw --namespace bar --name mysecretAgBChHUWLMx...
namespace-wide
범위:
$ 에코 -n foo | kubeseal --raw --namespace bar --scope 네임스페이스-wideAgAbbFNkM54...
SealedSecret
에 sealedsecrets.bitnami.com/namespace-wide
주석을 포함합니다.
메타데이터: 주석: sealingsecrets.bitnami.com/namespace-wide: "true"
cluster-wide
범위:
$ 에코 -n foo | kubeseal --raw --scope 클러스터-와이드AgAjLKpIYV+...
SealedSecret
에 sealedsecrets.bitnami.com/cluster-wide
주석을 포함합니다.
메타데이터: 주석: sealingsecrets.bitnami.com/cluster-wide: "true"
기존의 봉인된 비밀을 검증하려는 경우 kubeseal
에는 --validate
플래그가 있어 도움이 됩니다.
다음 봉인된 비밀을 포함하는 sealed-secrets.yaml
이라는 파일 제공:
apiVersion: bitnami.com/v1alpha1kind: SealedSecretmetadata: 이름: mysecret 네임스페이스: mynamespacespec: 암호화된Data: foo: AgBy3i4OJSWK+PiTySYZZA9rO43cGDEq.....
봉인된 비밀이 제대로 생성되었는지 여부를 확인할 수 있습니다.
$ 고양이 봉인 비밀.yaml | kubeseal --검증
봉인된 비밀이 유효하지 않은 경우 kubeseal
다음을 표시합니다.
$ 고양이 봉인 비밀.yaml | kubeseal --validateerror: 봉인된 비밀을 해독할 수 없습니다
보안 비밀은 항상 교체해야 합니다. 그러나 귀하의 비밀은 다른 비밀로 암호화되므로 올바른 결정을 내리려면 이 두 계층이 어떻게 연관되어 있는지 이해해야 합니다.
요약:
봉인된 개인 키가 손상된 경우 실제 비밀 값을 교체하기 전에 아래 "조기 키 갱신" 섹션의 지침을 따라야 합니다.
SealedSecret 키 갱신 및 재암호화 기능은 실제 비밀 값의 주기적인 교체를 대체하지 않습니다 .
봉인 키는 30일마다 자동으로 갱신됩니다. 즉, 새로운 봉인 키가 생성되어 컨트롤러가 SealedSecret
리소스 봉인을 해제하는 데 사용할 수 있는 활성 봉인 키 세트에 추가됩니다.
가장 최근에 생성된 봉인 키는 kubeseal
사용할 때 새로운 비밀을 봉인하는 데 사용되는 키이며, kubeseal --fetch-cert
사용할 때 인증서가 다운로드되는 키입니다.
30일의 갱신 시간은 합리적인 기본값이지만 SealedSecret
컨트롤러의 포드 템플릿에 있는 명령에 대한 --key-renew-period=
플래그를 사용하여 필요에 따라 조정할 수 있습니다. value
필드는 golang 기간 플래그(예: 720h30m
)로 제공될 수 있습니다. 봉인된 비밀을 kube-system
네임스페이스에 설치했다고 가정하고 다음 명령을 사용하여 배포 컨트롤러를 편집하고 --key-renew-period
매개변수를 추가합니다. 텍스트 편집기를 닫고 배포 컨트롤러가 수정되면 이전 Pod를 대체하기 위해 새 Pod가 자동으로 생성됩니다.
kubectl edit deployment/sealed-secrets-controller --namespace=kube-system
값이 0
이면 자동 키 갱신이 비활성화됩니다. 물론 자동 봉인 키 갱신을 비활성화하는 유효한 사용 사례가 있을 수 있지만 경험에 따르면 신규 사용자는 봉인된 비밀의 작동 방식을 완전히 이해하기 전에 키 갱신을 제어하고 싶다는 결론을 내리는 경향이 있습니다. 이에 대한 자세한 내용은 아래의 일반적인 오해 섹션을 참조하세요.
불행하게도 Go stdlib에서는 지원되지 않기 때문에 "d"를 며칠 동안 단위로 사용할 수 없습니다. 손바닥으로 얼굴을 때리는 대신, 이것을 프로그래머들이 시간에 대해 믿고 있는 거짓에 대해 묵상할 기회로 삼으십시오.
일반적인 오해는 키 갱신을 키 순환의 한 형태로 생각하는 경우가 많습니다. 즉, 이전 키가 쓸모없을 뿐만 아니라 실제로 상태가 좋지 않아 이를 제거하고 싶어한다는 것입니다. 이 기능을 역사적으로 "키 순환"이라고 불렀다는 사실은 도움이 되지 않으며 이로 인해 혼란이 가중될 수 있습니다.
봉인된 비밀은 자동으로 교체되지 않으며 새 키가 생성될 때 이전 키는 삭제되지 않습니다. 이전 SealedSecret
리소스는 여전히 해독될 수 있습니다(이는 이전 봉인 키가 삭제되지 않기 때문입니다).
봉인 키 갱신 및 SealedSecret 순환은 실제 비밀 순환을 대체하지 않습니다 .
이 도구의 핵심 가치 제안은 다음과 같습니다.
공개 저장소 내부에도 안전하게 저장할 수 있는 SealedSecret으로 비밀을 암호화하세요.
버전 제어 저장소, 특히 공개 저장소에 무엇이든 저장하는 경우 해당 정보를 삭제할 수 없다고 가정해야 합니다.
봉인 키가 클러스터 외부로 유출되는 경우 해당 키로 암호화된 모든 SealedSecret
리소스가 손상된 것으로 간주해야 합니다. 클러스터에서 봉인 키 순환을 아무리 많이 하거나 기존 SealedSecrets 파일을 다시 암호화해도 이를 변경할 수 없습니다.
가장 좋은 방법은 모든 실제 비밀을 주기적으로 교체 하고 (예: 비밀번호 변경) 해당 새 비밀로 새 SealedSecret
리소스를 만드는 것입니다.
그러나 SealedSecret
컨트롤러가 봉인 키를 갱신하지 않는 경우 공격자는 새 비밀도 해독할 수 있으므로 순환이 문제가 될 수 있습니다. 따라서 정기적으로 봉인 키를 갱신하고 실제 비밀을 교체하는 두 가지 작업을 모두 수행해야 합니다!
봉인 키가 손상되었음을 알고 있거나 의심되는 경우 교체된 새 비밀 봉인을 시작하기 전에 최대한 빨리 키를 갱신해야 합니다. 그렇지 않으면 공격자에게도 새 비밀에 대한 액세스 권한을 부여하게 됩니다.
현재 타임스탬프를 컨트롤러에 --key-cutoff-time
이라는 플래그 또는 SEALED_SECRETS_KEY_CUTOFF_TIME
이라는 환경 변수에 전달하여 키를 조기에 생성할 수 있습니다. 예상 형식은 RFC1123이며 date -R
unix 명령을 사용하여 생성할 수 있습니다.
봉인된 비밀 봉인 키는 액세스 제어 키(예: 비밀번호)가 아닙니다. 이는 귀하에게 전송된 암호화된 메일을 읽는 데 사용할 수 있는 GPG 키와 더 유사합니다. 잠시 이메일 비유를 계속해 보겠습니다.
개인 GPG 키가 손상되었을 수 있다고 믿을 만한 이유가 있다고 가정해 보세요. 가장 먼저 개인 키를 삭제하는 것이라면 얻는 것보다 잃는 것이 더 많을 것입니다. 해당 키와 함께 전송된 모든 이전 이메일은 더 이상 액세스할 수 없으며(해당 이메일의 암호 해독된 사본이 없는 한), 아직 새 키를 사용하라고 알리지 않은 친구가 보낸 새 이메일에도 액세스할 수 없습니다.
물론, 암호화된 이메일의 내용은 공격자가 이제 해독할 수 있기 때문에 안전하지 않지만 이미 완료된 작업은 완료되었습니다. 이러한 이메일을 읽을 수 있는 능력이 갑자기 상실되었다고 해서 피해가 복구되지는 않습니다. 오히려 공격자가 어떤 비밀을 알게 되었는지 더 이상 확실히 알 수 없기 때문에 상황은 더 나쁩니다. 당신이 정말로 원하는 것은 당신의 친구가 당신의 이전 키 사용을 중단하고 이제부터 모든 추가 통신이 새 키 쌍으로 암호화되도록 하는 것입니다(즉, 당신의 친구는 새 키에 대해 알아야 합니다).
SealedSecrets에도 동일한 논리가 적용됩니다. 궁극적인 목표는 실제 "사용자" 비밀을 보호하는 것입니다. "봉인" 비밀은 단지 하나의 메커니즘, 즉 "봉투"일 뿐입니다. 비밀이 유출되면 되돌릴 수 없으며 이미 수행된 작업은 완료됩니다.
먼저 새 비밀이 이전에 손상된 키로 암호화되지 않도록 해야 합니다(위의 이메일 비유에서는 새 키 쌍을 만들고 모든 친구에게 새 공개 키를 제공합니다).
두 번째 논리적 단계는 피해를 무력화하는 것인데, 이는 비밀의 성격에 따라 달라집니다. 간단한 예는 데이터베이스 비밀번호입니다. 실수로 데이터베이스 비밀번호를 유출한 경우 해야 할 일은 단순히 데이터베이스 비밀번호를 변경하고(데이터베이스에서 이전 비밀번호를 취소하는 것입니다!) SealedSecret
리소스를 다음과 같이 업데이트하는 것 입니다 . 새 비밀번호(즉, kubeseal
다시 실행).
두 단계 모두 이전 섹션에서 덜 장황하게 설명되어 있습니다. 이제 기본 근거를 더 깊이 이해했으므로 다시 읽어도 부끄러운 일이 아닙니다.
SealedSecret
컨트롤러 및 관련 워크플로는 기존 봉인 키를 유지하고 주기적으로 새 키를 추가하도록 설계되었습니다. 수행 중인 작업을 알지 못하는 경우 이전 키를 삭제하면 안 됩니다.
즉, 원하는 경우 봉인 키를 수동으로 관리(생성, 이동, 삭제)할 수 있습니다. 이는 SealedSecret
컨트롤러가 있는 동일한 네임스페이스(일반적으로 kube-system
이지만 구성 가능)에 있는 일반적인 k8s 비밀입니다.
봉인 키를 창의적으로 관리하여 해결할 수 있는 고급 사용 사례가 있습니다. 예를 들어, 여러 클러스터에 동일한 봉인된 비밀을 적용할 수 있도록 여러 클러스터 간에 동일한 봉인 키를 공유할 수 있습니다. 봉인 키는 일반적인 k8s 비밀이므로 봉인된 비밀 자체를 사용할 수도 있고 GitOps 워크플로를 사용하여 봉인 키를 관리할 수도 있습니다(다른 클러스터 간에 동일한 키를 공유하려는 경우 유용함)!
봉인 키 비밀에 active
이외의 레이블을 지정하면 SealedSecret
컨트롤러에서 키가 효과적으로 삭제되지만 필요한 경우 수동 암호화/암호 해독을 위해 k8s에서 계속 사용할 수 있습니다.
참고 SealedSecret
컨트롤러는 현재 수동으로 생성, 삭제 또는 레이블이 다시 지정된 봉인 키를 자동으로 선택하지 않습니다. 효과가 적용되기 전에 관리자는 컨트롤러를 다시 시작해야 합니다.
오래된 봉인 키를 제거하기 전에 최신 개인 키로 SealedSecrets를 다시 암호화해야 합니다.
kubeseal --re-encrypttmp.json && mv tmp.json my_sealed_secret.json
위의 호출은 비밀이 클러스터를 클라이언트에 남겨두지 않고 최신 키로 새로 암호화된 새로운 봉인된 비밀 파일을 생성합니다. 그런 다음 해당 파일을 버전 제어 시스템에 저장할 수 있습니다( kubeseal --re-encrypt
클러스터 내 객체를 업데이트하지 않음).
현재 이전 키는 자동으로 가비지 수집되지 않습니다.
SealedSecrets를 주기적으로 다시 암호화하는 것이 좋습니다. 그러나 위에서 언급했듯이 잘못된 보안 감각에 빠지지 마십시오. 이전 버전의 SealedSecret
리소스(죽었다고 생각하는 키로 암호화된 리소스)가 여전히 잠재적으로 존재하며 공격자가 액세스할 수 있다고 가정해야 합니다. 즉, 재암호화는 실제 비밀을 주기적으로 교체하는 것을 대체할 수 없습니다.
이 컨트롤러는 새로운 SealedSecret
사용자 정의 리소스를 추가합니다. SealedSecret
의 흥미로운 부분은 base64로 인코딩되고 비대칭으로 암호화된 Secret
입니다.
컨트롤러는 개인/공개 키 쌍 세트를 Kubernetes 비밀로 유지 관리합니다. 키에는 sealedsecrets.bitnami.com/sealed-secrets-key
라는 라벨이 붙어 있으며 라벨에서 active
또는 compromised
으로 식별됩니다. 시작 시 봉인된 비밀 컨트롤러는 다음을 수행합니다.
이러한 키를 검색하고 활성으로 표시되면 로컬 저장소에 추가하세요.
새 키 만들기
키 순환 주기 시작
암호화폐에 대한 자세한 내용은 여기에서 확인할 수 있습니다.
개발 지침은 개발자 가이드에서 확인할 수 있습니다.
예, 가능합니다! 하나의 파일에 원하는 만큼 많은 비밀을 삭제하세요. YAML의 경우 ---
통해 분리하고 JSON의 추가 단일 객체로 분리하세요.
아니요, 개인 키는 컨트롤러가 관리하는 보안 비밀에만 저장됩니다(k8s 개체에 대한 다른 백업이 없는 경우). 백도어가 없습니다. 지정된 SealedSecrets를 암호화하는 데 사용되는 개인 키가 없으면 암호를 해독할 수 없습니다. 암호화 키를 사용하여 비밀에 접근할 수 없고 클러스터에 있는 암호의 해독된 버전에도 접근할 수 없는 경우 모든 것에 대해 새 비밀번호를 다시 생성하고 새 비밀번호로 다시 봉인해야 합니다. 봉인 키 등
암호화 개인 키를 백업하고 싶다면 적절한 액세스 권한이 있는 계정에서 쉽게 백업할 수 있습니다.
kubectl 비밀 얻기 -n kube-system -l sealingsecrets.bitnami.com/sealed-secrets-key -o yaml >main.keyecho "---" >> main.key kubectl get secret -n kube-system sealing-secrets-key -o yaml >>main.key
참고: 클러스터에 0.9.x 버전보다 오래된 봉인된 비밀을 설치한 경우에만 두 번째 문이 필요합니다.
참고: 이 파일에는 컨트롤러의 공개 키와 개인 키가 포함되어 있으므로 안전하게 보관해야 합니다!
참고: 키 갱신을 봉인한 후에는 백업을 다시 생성해야 합니다. 그렇지 않으면 백업에서 봉인된 새로운 비밀을 해독할 수 없습니다.
재해 발생 후 백업에서 복원하려면 컨트롤러를 시작하기 전에 해당 비밀을 다시 넣으십시오. 또는 컨트롤러가 이미 시작된 경우 새로 생성된 비밀을 교체하고 컨트롤러를 다시 시작하십시오.
Helm 배포의 경우:
kubectl apply -f main.key kubectl 삭제 포드 -n kube-system -l app.kubernetes.io/name=sealed-secrets
controller.yaml
매니페스트를 통한 배포의 경우
kubectl apply -f main.key kubectl 삭제 포드 -n kube-system -l 이름=sealed-secrets-controller
봉인된 비밀을 비밀을 위한 장기 저장 시스템으로 취급하는 것은 권장되는 사용 사례가 아니지만 일부 사람들은 k8s 클러스터가 다운되고 백업을 새로운 SealedSecret
컨트롤러 배포로 복원할 때 비밀을 복구할 수 있어야 한다는 합법적인 요구 사항을 갖고 있습니다. 현실적인.
하나 이상의 개인 키를 백업한 경우(이전 질문 참조) kubeseal --recovery-unseal --recovery-private-key file1.key,file2.key,...
명령을 사용하여 암호를 해독할 수 있습니다. 봉인된 비밀 파일.
kubeseal --help
사용하여 사용 가능한 플래그를 확인할 수 있습니다.
kubernetes Secret
리소스에는 기본적으로 키/값 쌍의 평면 맵인 여러 항목이 포함되어 있습니다. SealedSecrets는 해당 수준에서 작동하며 값에 무엇을 입력하든 상관하지 않습니다. 즉, 비밀에 넣은 구조화된 구성 파일을 이해할 수 없으므로 그 안의 개별 필드를 업데이트하는 데 도움이 될 수 없습니다.
이는 특히 레거시 애플리케이션을 다룰 때 흔히 발생하는 문제이므로 가능한 해결 방법의 예를 제공합니다.
예, 컨트롤러에 자체 인증서를 제공하면 해당 인증서가 사용됩니다. 해결 방법은 여기를 확인하세요.
kube-system
네임스페이스 내에서 실행되고 있지 않은 경우 kubeseal을 어떻게 사용합니까? 기본 kube-system
과 다른 네임스페이스에 컨트롤러를 설치한 경우 이 네임스페이스를 kubeseal
명령줄 도구에 제공해야 합니다. 두 가지 옵션이 있습니다:
명령줄 옵션 --controller-namespace
를 통해 네임스페이스를 지정할 수 있습니다.
kubeseal --controller-namespace 봉인된 비밀mysealedsecret.json
환경 변수 SEALED_SECRETS_CONTROLLER_NAMESPACE
를 통해:
SEALED_SECRETS_ControlLER_NAMESPACE=봉인된 비밀 내보내기 kubesealmysealedsecret.json
우리 이미지는 cosign을 사용하여 서명됩니다. 서명은 GitHub 컨테이너 레지스트리에 저장되었습니다.
v0.20.2까지의 이미지는 Cosign v1을 사용하여 서명되었습니다. 최신 이미지는 Cosign v2로 서명됩니다.
이미지를 확인하는 것은 매우 간단합니다.
# COSIGN_VARIABLE 설정 내보내기 GitHub 컨테이너 레지스트리 서명 pathexport COSIGN_REPOSITORY=ghcr.io/bitnami-labs/sealed-secrets-controller/signs# GHCRcosign에 업로드된 이미지 확인 cosign verify --key .github/workflows/cosign.pub ghcr. io/bitnami-labs/sealed-secrets-controller:latest# Dockerhubcosign에 업로드된 이미지 확인 --key .github/workflows/cosign.pub docker.io/bitnami/sealed-secrets-controller:latest 확인
두 개 이상의 네임스페이스에 대해 하나의 컨트롤러를 사용하고 싶지만 모든 네임스페이스에 대해 사용하려는 경우 명령줄 플래그 --additional-namespaces=
사용하여 추가 네임스페이스를 제공할 수 있습니다. 컨트롤러가 거기에서 비밀을 관리할 수 있도록 대상 네임스페이스에 적절한 역할과 역할 바인딩을 제공해야 합니다.
대답은 '예'입니다. --max-unseal-retries
플래그를 사용하여 컨트롤러에서 재시도 횟수를 구성할 수 있습니다. 이 플래그를 사용하면 봉인된 비밀을 해제하기 위한 최대 재시도 횟수를 구성할 수 있습니다.
Kubernetes Slack의 #sealed-secrets
Kubernetes Slack 조직에 가입하려면 여기를 클릭하세요.
kubeseal-convert
: https://github.com/EladLeev/kubeseal-convert
Visual Studio 코드 확장: https://marketplace.visualstudio.com/items?itemName=codecontemplator.kubeseal
WebSeal: 브라우저에서 비밀을 생성합니다: https://socialgouv.github.io/webseal
HybridEncrypt TypeScript 구현: https://github.com/SocialGouv/aes-gcm-rsa-oaep
[지원 중단됨] 봉인된 비밀 운영자: https://github.com/disposab1e/sealed-secrets-operator-helm