본문 바로가기
AI Journey/클라우드

[Docker Swarm] 데이터 관리: 시크릿(secret)과 컨피그(config)

by 보눔비스타 2026. 1. 16.

도커 스웜 모드에서 애플리케이션을 운영할 때, 가장 먼저 보안 데이터와 설정 파일을 어떻게 관리할 것인지 고려해야 한다.

소스 코드에 포함해서는 안 되는 민감한 정보(비밀번호, API 키)와 환경에 따라 변하는 설정 파일(yml, txt)을 안전하고 효율적으로 관리하기 위해 도커는 SecretConfig라는 객체를 제공한다.

1. Docker Secret: 민감 정보의 암호화 저장

데이터베이스 패스워드나 API 키와 같은 민감 정보는 docker secret을 통해 스웜 클러스터 내부에 안전하게 저장한다.

# 1. 시크릿 생성
echo "pswd1234" | docker secret create my_mysql_password - 

# 2. 시크릿 목록 확인
docker secret ls

# 3. 시크릿 상세 정보 확인
docker secret inspect my_mysql_password

 

docker secret create [이름] -표준 입력(-)을 통해 전달받은 문자열을 my_mysql_password라는 이름의 시크릿 객체로 생성한다. 

 

[동작 원리]

Raft 기반 암호화 저장

  • 생성된 시크릿은 매니저 노드 내부의 전용 데이터베이스(Raft 스토리지)에 암호화되어 기록된다.
  • 매니저 노드가 여러개라면 매니저들끼리 데이터를 주고받을 때 상호 TLS(mTLS)를 통해 암호화된 통로를 사용하며, 각 매니저의 디스크에 저장될 때도 암호화된 상태로 저장된다. (Raft 로그에 복제됨)

메모리 기반 마운트

  • 서비스가 실행될 때 해당 컨테이너 내부의 /run/secrets/ 경로에 파일 형태로 마운트된다.
  • 서비스 배포 시 컨테이너 내부의 메모리 기반 파일 시스템(tmpfs)에 마운트되므로 디스크에 흔적이 남지 않아 보안성이 매우 높다. (시크릿은 디스크에 저장되지 않고 컨테이너가 중단되면 메모리에서 즉시 사라지기 때문)
  • 이는 환경 변수(ENV)로 비밀번호를 전달할 때 발생할 수 있는 보안 취약점(로그 노출 등)을 보완한다.

 

2. Docker Config: 일반 설정 파일 관리

암호화가 필요 없는 일반 설정값(예: settings.yml)은 docker config를사용한다.

# 1. 설정 파일 생성
echo "setting: { debug: true }" > my_config.txt (.yml도 상관없음)

# 2. 컨피그 생성
docker config create my_app_config my_config.txt

# 3. 컨피그 정보 확인 (메타데이터)
docker config inspect my_app_config

 

 

  • docker config create : 로컬 파일(my_config.txt)의 내용을 도커 스웜 클러스터의 데이터베이스에 저장한다.
  • Secret과 달리 암호화되지 않으므로 누구나 읽을 수 있는 설정값에 사용한다. 서비스 배포 시 특정 경로(예: /etc/config/settings.yml)에 파일을 생성해 주는 역할을 한다.
  • 이미지를 다시 빌드하지 않고도 실행 시점에 설정 파일을 주입할 수 있게 해준다.
  • docker config inspect를 통해 등록된 데이터가 Base64로 인코딩되어 저장된 것을 확인할 수 있다.

💡 Config 데이터가 이상하게 보인다? (Base64 인코딩)

 

docker config inspect를 실행했을 때 나타나는 Data 필드의 값은 암호화된 것이 아니라 Base64로 인코딩된 상태다.

  • 확인 방법: "Data" 값을 복사해서 echo "[데이터]" | base64 --decode 명령을 통해 언제든지 원문을 확인할 수 있다.
  • 주의 사항: 누구나 디코딩하여 내용을 볼 수 있으므로, Config에는 절대로 패스워드를 저장하면 안 된다. 보안이 필요한 데이터는 반드시 docker secret을 사용하자. (Secret은 inspect를 해도 이 Data 필드 자체가 아예 나타나지 않는다.)
echo "c2V0dGluZzogeyBkZWJ1ZzogdHJ1ZSB9Cg==" |base64 --decode
setting: { debug: true }

 

3. YAML 파일에서의 자원 참조 (Compose & Stack)

 

생성된 시크릿과 컨피그를 서비스에서 사용하기 위해서는 컴포즈 파일(docker-compose.yml) 또는 스택 파일(docker-stack.yml)에서 이를 정의하고 참조해야 한다.

 

[참조 방식]

상단 services 섹션에서 개별 서비스가 어떤 자원을 사용할지 지정하고, 하단 전역 섹션에서 해당 자원이 외부에서 생성된 것(external: true)임을 정의한다.

services:
  my_service:
    image: alpine
    secrets:
      - my_mysql_password    # 서비스에서 사용할 시크릿 선언
    configs:
      - source: my_app_config # 사용할 컨피그 소스
        target: /etc/config/settings.yml # 컨테이너 내 저장 경로

# 외부에서 이미 생성된 자원임을 명시 (external: true)
secrets:
  my_mysql_password:
    external: true

configs:
  my_app_config:
    external: true

 

4. 데이터 주입 프로세스

매니저 노드에 저장된 자원이 워커 노드의 컨테이너로 전달되는 논리적 흐름이다.

 

다음 글에서는 지금까지 생성한 시크릿과 컨피그를 사용해서 실제로 3개의 레플리카를 갖는 데이터베이스 서비스를 배포하는 실습을 진행한다.