컨테이너화 플러그인 추가하기
컨테이너화 플러그인 추가하기
플러그인과 Vault 사이의 격리를 높이기 위해 외부 시크릿 플러그인을 컨테이너에서 실행해 봐요.
출처: 문서
본문
시작하기 전에
- Vault 인스턴스가 Linux에서 실행 중이어야 해요.
- Vault 인스턴스가 Docker Engine API에 로컬로 접근할 수 있어야 해요. Vault는 Docker SDK를 사용해 컨테이너화 플러그인을 관리해요.
- gVisor가 설치되어 있어야 해요. Vault는 컨테이너 런타임의 엔트리포인트로 runsc를 사용해요.
- gVisor 외의 컨테이너 런타임을 사용한다면 runsc 호환 컨테이너 런타임이 설치되어 있어야 해요.
1단계: 컨테이너 엔진 설치
지원되는 컨테이너 엔진 중 하나를 설치하세요.
- Docker
- Rootless Docker
2단계: 컨테이너 런타임 구성
호스트와 플러그인 바이너리 사이의 Unix 소켓에 runsc를 사용하도록 컨테이너 엔진을 업데이트하세요.
- Docker 데몬 구성에 runsc를 추가하세요.
$ sudo tee PATH_TO_DOCKER_DAEMON_CONFIG_FILE <<EOF
{
"runtimes": {
"runsc": {
"path": "PATH_TO_RUNSC_INSTALLATION",
"runtimeArgs": [
"--host-uds=all"
]
}
}
}
EOF
- Docker를 다시 시작하세요.
$ sudo systemctl reload docker
- 아직 없으면 구성 디렉터리를 만드세요.
$ mkdir -p ~/.config/docker
- Docker 구성에 runsc를 추가하세요.
$ tee ~/.config/docker/daemon.json <<EOF
{
"runtimes": {
"runsc": {
"path": "PATH_TO_RUNSC_INSTALLATION",
"runtimeArgs": [
"--host-uds=all"
"--ignore-cgroups"
]
}
}
}
EOF
- Docker를 다시 시작하세요.
$ systemctl --user restart docker
3단계: HashiCorp go-plugin 라이브러리 업데이트
완성된 바이너리가 컨테이너화와 호환되도록 플러그인을 v1.5.0+의 HashiCorp go-plugin 라이브러리로 로컬에서 빌드해야 해요.
go install로 GitHub의 hashicorp/go-plugin 저장소에서 최신 버전의 플러그인 라이브러리를 가져오세요.
$ go install github.com/hashicorp/go-plugin@latest
4단계: 플러그인 컨테이너 빌드
컨테이너화 플러그인은 완성된 컨테이너에서 바이너리로 실행되어야 하며, 컨테이너에서 실행되든 독립 실행형 애플리케이션으로 실행되든 동일하게 동작해야 해요.
- 플러그인 바이너리를 Linux에서 실행되도록 빌드하세요.
- 컴파일된 바이너리를 엔트리포인트로 하는 플러그인용 컨테이너 파일을 만드세요.
- 고유한 태그로 이미지를 빌드하세요.
예를 들어 Docker용 내장 키-값(KV) 시크릿 플러그인의 컨테이너화 버전을 빌드하려면:
- hashicorp/vault-plugin-secrets-kv에서 최신 버전의 KV 시크릿 플러그인을 클론하세요.
$ git clone https://github.com/hashicorp/vault-plugin-secrets-kv.git
- Linux용 Go 바이너리를 빌드하세요.
$ cd vault-plugin-secrets-kv ; CGO_ENABLED=0 GOOS=linux \
go build -o kv cmd/vault-plugin-secrets-kv/main.go
- 빈 Dockerfile을 만드세요.
$ touch Dockerfile
- 빈 Dockerfile을 인프라 빌드 세부 정보와 컴파일된 바이너리를 엔트리포인트로 하도록 업데이트하세요.
FROM gcr.io/distroless/static-debian12
COPY kv /bin/kv
ENTRYPOINT [ "/bin/kv" ]
- 컨테이너 이미지를 빌드하고 식별 가능한 태그를 지정하세요.
$ docker build -t hashicorp/vault-plugin-secrets-kv:1.0.0 .
5단계: 플러그인 등록
컨테이너화 플러그인을 Vault에 등록하는 것은 Vault에 로컬로 사용 가능한 다른 외부 플러그인을 등록하는 것과 유사해요.
- 플러그인 이미지의 SHA256을 저장하세요. 예를 들면:
$ export SHA256=$(docker images \
--no-trunc \
--format="{{ .ID }}" \
YOUR_PLUGIN_IMAGE_TAG | cut -d: -f2)
$ export SHA256=$(docker images \
--no-trunc \
--format="{{ .ID }}" \
hashicorp/vault-plugin-secrets-kv:1.0.0 | cut -d: -f2)
vault plugin register로 플러그인을 등록하고oci_image플래그로 플러그인 이미지를 지정하세요. 예를 들면:
$ vault plugin register \
-sha256="${SHA256}" \
-oci_image=YOUR_PLUGIN_IMAGE_TAG \
NEW_PLUGIN_TYPE NEW_PLUGIN_ID
$ vault plugin register \
-sha256="${SHA256}" \
-oci_image=hashicorp/vault-plugin-secrets-kv:1.0.0 \
secret my-kv-container
vault secrets enable과 새 플러그인 ID로 Vault 인스턴스에 새 플러그인을 활성화하세요. 예를 들면:
$ vault secrets enable NEW_PLUGIN_ID
$ vault secrets enable my-kv-container
6단계: 플러그인 테스트
이제 컨테이너가 Vault에 등록되었으므로 다른 플러그인처럼 상호작용할 수 있어야 해요. 새 플러그인으로 새 시크릿을 쓰고 가져와 보세요.
- 컨테이너화 플러그인으로 시크릿을 저장하려면
vault write를 사용하세요. 예를 들면:
$ vault write NEW_PLUGIN_ID/SECRET_PATH SECRET_KEY=SECRET_VALUE
$ vault write my-kv-container/testing subject=containers
Success! Data written to: my-kv-container/testing
- 방금 쓴 시크릿을 가져오세요. 예를 들면:
$ vault read NEW_PLUGIN_ID/SECRET_PATH
$ vault read my-kv-container/testing
===== Data =====
Key Value
--- -----
subject containers
대체 런타임 사용
런타임이 로컬에 설치되어 있으면 Vault가 대체 런타임을 사용하도록 강제할 수 있어요.
대체 런타임을 사용하려면:
vault plugin runtime register로 런타임을 등록하고 이름을 지정하세요. 예를 들어 기본 Docker 런타임(runc)을 docker-rt로 등록하려면:
$ vault plugin runtime register \
-oci_runtime=runc \
-type=container docker-rt
- 플러그인 등록 중에
--runtime플래그를 사용해 Vault에 사용할 런타임을 알려주세요. 예를 들면:
$ vault plugin register \
-runtime=RUNTIME_NAME \
-sha256="${SHA256}" \
-oci_image=YOUR_PLUGIN_IMAGE_TAG \
NEW_PLUGIN_TYPE NEW_PLUGIN_ID
$ vault plugin register \
-runtime=docker-rt \
-sha256="${SHA256}" \
-oci_image=hashicorp/vault-plugin-secrets-kv:1.0.0 \
secret my-kv-container
트러블슈팅
잘못된 백엔드 버전 오류
플러그인 등록 중 다음과 같은 오류가 발생하면:
invalid backend version error: 2 errors occurred:
* error creating container: Error response from daemon: error while looking up the specified runtime path: exec: " /usr/bin/runsc": stat /usr/bin/runsc: no such file or directory
* error creating container: Error response from daemon: error while looking up the specified runtime path: exec: " /usr/bin/runsc": stat /usr/bin/runsc: no such file or directory
이는 Vault가 runsc 실행 파일을 찾지 못한다는 뜻이에요. 다시 시도하기 전에 다음이 참인지 확인하세요.
- Vault에 로컬로 gVisor가 설치되어 있음.
- Docker 구성에서 runsc 경로가 올바름.
- Vault가 runsc 실행 파일을 실행할 권한이 있음.
플러그인 등록 시 여전히 오류가 발생하면 권장 해결 방법은 기본 Docker 런타임(runc)을 대체 런타임으로 사용하는 거예요.