사전 설정 관리
개념

설정 관리

gabury1고친 사람 github-actions[bot]

설정 관리는 서버를 파일에 미리 적어 둔 대로 맞춰 줍니다. 백 대를 파일 하나로 똑같이 맞춥니다. 손으로 바꿔 어긋난 서버도 적힌 대로 되돌립니다. 소프트웨어 공학에서는 같은 이름이 개발 산출물의 변경을 추적하는 일을 가리키기도 합니다.

쉽고 빠른 이해

설정 관리는 서버 안을 파일에 적힌 대로 맞추는 일입니다. 웹 서버 백 대에 같은 프로그램을 깔고 같은 설정 파일을 두는 일이 그렇습니다.

이게 없으면 사람이 서버마다 들어가 손으로 고칩니다. 한 대만 고치고 나머지를 잊는 일이 생깁니다. 시간이 지나면 서버마다 조금씩 달라집니다. 무엇이 다른지는 아무도 모릅니다.

  1. 서버가 갖춰야 할 모습을 파일에 적습니다
  2. 도구가 서버마다 지금 상태와 파일에 적힌 내용을 견줍니다
  3. 다른 것만 고칩니다. 이미 같으면 아무것도 안 합니다

대가는 적어 둔 것만 지켜진다는 것입니다. 파일에 없는 것은 바뀌어도 도구가 모릅니다. 도구를 익히고 그 파일을 계속 손보는 수고도 듭니다.

그래서 오래 켜 두는 서버가 여럿일 때 제값을 합니다. 서버가 한두 대뿐이면 손으로 맞추는 쪽이 덜 수고로울 수 있습니다.

상세

빵집 체인 본사는 매장을 어떻게 꾸밀지 적은 매뉴얼을 한 권 둡니다. 점검원은 매장을 돌며 매뉴얼과 다른 데만 찾아 되돌립니다. 이미 매뉴얼대로인 매장에서는 아무것도 건드리지 않고 나옵니다.

서버의 설정

설정 관리가 맞추는 대상은 서버 안의 상태입니다. 먼저 그 상태가 무엇으로 이루어지는지부터 봅니다.

여기서 말하는 설정은 설정 파일 하나보다 넓습니다. 서버가 어떤 모습인지를 정하는 것 전부를 가리킵니다.

패키지는 설치할 프로그램을 파일 하나로 묶은 것입니다. 서버에 어떤 프로그램이 깔려 있는지가 패키지로 정해집니다.

서비스는 서버가 켜져 있는 동안 뒤에서 계속 도는 프로그램입니다(데몬이라고도 부릅니다). 웹 서버처럼 요청을 기다리는 프로그램이 그렇습니다. 여기에 파일과 사용자를 더해 넷을 표로 모았습니다.

무엇 서버가 갖춰야 할 모습의 예
패키지 웹 서버 프로그램이 깔려 있다
파일 /etc/app/app.conf 에 port=8080 줄이 있다
서비스 웹 서버가 켜져 있고 부팅 때도 뜬다
사용자와 권한 deploy 사용자가 있고 로그 폴더에 쓸 수 있다

표의 오른쪽 칸처럼 서버가 갖춰야 할 모습을 원하는 상태라 합니다. 설정 관리 도구는 서버를 이 상태에 맞춥니다.

손으로 맞출 때 생기는 일

서버를 손으로 관리하면 무엇이 쌓이는지부터 따라가 봅니다.

사람이 서버마다 원격으로 들어가 명령을 칩니다. 이때 쓰는 것이 SSH(Secure Shell, 원격 접속 프로토콜)입니다. 서버가 두세 대일 때는 이걸로 됩니다.

대수가 늘면 어긋남이 쌓입니다. 급한 장애가 나면 한 대에만 설정을 바꿉니다. 나머지 서버는 옛 설정으로 남습니다. 나중에 들인 서버에는 설치 문서가 낡아서 옛 버전이 깔립니다.

서버끼리, 또는 기대한 모습과 실제 모습이 이렇게 벌어지는 것을 설정 드리프트라 합니다. 드리프트는 떠내려간다는 뜻입니다. 변경 하나하나는 작아도 모이면 서버가 기준에서 멀어집니다.

드리프트가 오래 쌓인 서버를 눈송이 서버라고 부릅니다. 눈송이처럼 한 대 한 대가 다 다르다는 뜻입니다. 이런 서버가 죽으면 똑같이 다시 세우기 어렵습니다. 그 안에 무엇이 있었는지 어디에도 적혀 있지 않기 때문입니다.

설정 관리는 서버 안에 무엇이 있어야 하는지를 파일로 남깁니다. 그 파일을 버전관리에 넣으면 누가 언제 무엇을 바꿨는지도 남습니다.

명령 대신 결과를 적는 방식

손으로 치던 명령을 스크립트로 모으는 것이 첫걸음입니다. 스크립트는 여러 서버에 같은 명령을 돌려 줍니다. 문제는 같은 스크립트를 두 번 돌릴 때 생깁니다.

아래는 설정 파일 끝에 한 줄을 붙이는 명령입니다. 같은 명령을 두 번 돌린 뒤 파일에 남는 줄 수를 오른쪽에 적었습니다.

터미널
echo "port=8080" >> app.conf  # 1회: 한 줄
echo "port=8080" >> app.conf  # 2회: 두 줄

두 번째 실행이 이미 있는 줄을 또 붙였습니다. 명령은 지금 상태를 보지 않고 시킨 일만 하기 때문입니다. 이렇게 할 일을 순서대로 적는 방식이 명령형 스크립트입니다.

설정 관리 도구는 할 일 대신 결과를 적게 합니다. 「app.conf 에 port=8080 줄이 있어야 한다」처럼 적습니다. 이렇게 원하는 상태를 적은 글을 선언이라 합니다. 이 방식이 선언적 설정입니다.

도구는 먼저 파일을 읽어 그 줄이 있는지 봅니다. 있으면 아무것도 안 합니다. 없을 때만 한 줄을 넣습니다. 그래서 몇 번을 돌려도 줄은 하나입니다.

몇 번을 해도 한 번 한 것과 결과가 같은 성질이 멱등성입니다. 같은 선언을 날마다 다시 돌려도 서버가 망가지지 않는 까닭이 이 성질입니다.

적힌 모습으로 맞춰 가는 순서

도구가 서버 한 대에서 하는 일은 늘 같은 순서를 밟습니다. 아래 그림이 그 순서입니다.

flowchart TD
    A["선언을 읽는다"] --> B["서버의 지금 상태를 살핀다"]
    B --> C{"둘이 같은가"}
    C -->|같다| D["아무것도 안 한다"]
    C -->|다르다| E["다른 항목만 고친다"]
    D --> F["결과를 보고한다 (바뀐 항목만 적힌다)"]
    E --> F

이 순서는 항목마다 따로 돕니다. 패키지 하나, 파일 하나, 서비스 하나를 저마다 견줍니다. 그래서 틀린 항목이 하나면 그 하나만 고칩니다. 맞는 항목은 건드리지 않습니다.

지금 상태를 원하는 상태 쪽으로 모아 가는 것을 수렴이라 합니다. 한 번 실행으로 다 맞지 않을 수도 있습니다. 패키지를 받아 오다 네트워크가 끊기면 그 항목은 틀린 채로 남습니다. 다음 실행이 그 항목을 마저 맞춥니다.

보고에는 바뀐 항목만 적힙니다. 선언을 안 고쳤는데 보고에 변경이 뜨면 누가 손으로 서버를 건드렸다는 신호입니다.

서버를 고치지 않고 무엇이 다른지만 보여 주는 실행도 있습니다. 이것을 모의 실행(dry run)이라 부릅니다. 드리프트를 찾을 때 씁니다.

밀어 넣기와 끌어오기

선언을 서버에 건네는 길은 둘입니다. 중앙에서 서버로 밀어 넣는 방식과 서버가 중앙에서 끌어오는 방식입니다.

밀어 넣기(push)는 관리하는 컴퓨터 한 대가 서버마다 접속해 선언을 적용합니다. 서버에는 따로 깔아 둘 프로그램이 없어도 됩니다. 대신 누가 실행할 때만 서버가 맞춰집니다.

끌어오기(pull)는 서버마다 에이전트를 깝니다. 에이전트는 서버에 늘 떠 있는 프로그램입니다. 정해진 간격마다 중앙에서 선언을 받아와 스스로 맞춥니다.

밀어 넣기 끌어오기
누가 시작하나 관리하는 쪽의 사람 서버의 에이전트
서버에 깔 것 원격 접속만 되면 된다 에이전트
드리프트가 되돌아가는 때 다음에 누가 실행할 때 다음 주기

이 일을 하는 도구로 앤서블 · 퍼펫 · 셰프가 널리 쓰입니다. 선언을 적는 문법은 도구마다 다릅니다.

서버를 만드는 일과 나누는 경계

설정 관리는 이미 떠 있는 서버의 안쪽을 맞춥니다. 서버 자체를 만드는 일은 맡지 않습니다. 이 소절은 서버를 만드는 단계와 설정 관리가 일을 어떻게 나누는지 봅니다.

서버·네트워크·디스크 같은 자원을 새로 만드는 일이 프로비저닝입니다. 빈 서버를 한 대 만들어 네트워크에 붙이는 데까지입니다.

이 자원을 코드로 적어 만드는 방식을 코드형 인프라라 합니다. 설정 관리가 서버 안을 글로 적는다면 코드형 인프라는 서버 바깥을 글로 적습니다.

흔한 순서는 세 단계입니다. 코드형 인프라가 빈 서버를 만듭니다. 설정 관리가 그 안에 프로그램과 파일을 채웁니다. 그 위에 애플리케이션을 배포합니다.

불변 서버는 이 순서를 바꿉니다. 한 번 띄운 서버는 고치지 않습니다. 바꿀 것이 생기면 새 서버를 띄워 옛 서버와 갈아 끼웁니다.

이 방식에서 설정 관리는 서버가 아니라 머신 이미지를 맞춥니다. 머신 이미지는 운영체제와 프로그램을 미리 깔아 둔 서버의 틀입니다. 설정 관리로 이 틀을 한 번 맞춥니다. 서버는 전부 그 틀로 띄웁니다.

flowchart TD
    subgraph "고쳐 쓰는 서버"
        P1["빈 서버를 만든다"] --> C1["설정 관리가 서버 안을 맞춘다"]
        C1 --> R1["바꿀 것이 생기면 설정 관리를 다시 돌린다"]
    end
    subgraph "갈아 끼우는 서버"
        C2["설정 관리가 머신 이미지를 맞춘다"] --> P2["그 이미지로 서버를 띄운다"]
        P2 --> R2["바꿀 것이 생기면 새 이미지로 갈아 끼운다"]
    end

위쪽 길에서는 설정 관리가 서버가 살아 있는 내내 돕니다. 아래쪽 길에서는 이미지를 만들 때 한 번만 돕니다. 떠 있는 서버를 고치지 않으니 드리프트가 생길 틈이 줄어듭니다.

쓸 때와 안 쓸 때

설정 관리가 제값을 하는 때는 오래 사는 서버가 여럿일 때입니다. 몇 달씩 켜 둔 채 고쳐 쓰는 서버는 드리프트가 쌓일 시간이 깁니다.

서버를 자주 새로 띄우고 버린다면 쓸 일이 줄어듭니다. 머신 이미지나 컨테이너 이미지로 갈아 끼우면 떠 있는 서버를 맞출 일이 없습니다. 이때는 이미지를 만드는 단계에서만 씁니다.

컨테이너는 프로그램과 그 프로그램이 쓰는 파일을 한데 묶어 따로 떼어 돌리는 단위입니다. 컨테이너 이미지는 그 묶음을 찍어 내는 틀입니다. 서버를 통째로 갈지 않고 이 틀만 바꿔 프로그램을 갈아 끼웁니다.

서버가 한두 대뿐이면 계산이 달라집니다. 선언을 적고 도구를 익히는 수고가 손으로 맞추는 수고보다 클 수 있습니다.

치르는 대가

첫째 대가는 적어 둔 것만 지켜진다는 것입니다. 선언에 없는 파일이 바뀌면 도구는 모릅니다. 선언에서 항목을 지워도 서버에서 그것이 대개 저절로 지워지지 않습니다. 「없어야 한다」고 따로 적어야 지워집니다.

둘째, 선언도 코드처럼 다뤄야 합니다. 시험하지 않은 선언은 틀린 설정을 백 대에 한꺼번에 퍼뜨립니다. 손으로 고칠 때는 한 대에서 멈췄을 실수입니다.

셋째, 도구마다 선언을 적는 문법과 낱말이 따로 있습니다. 이것을 익히는 데 시간이 듭니다.

넷째, 설정에는 비밀번호나 인증 키도 섞입니다. 이것을 선언 파일에 평문으로 두면 저장소를 읽는 누구나 봅니다. 그래서 시크릿 관리를 따로 붙입니다.

같은 이름으로 부르는 다른 일

설정 관리라는 이름은 서버 말고도 두 분야에서 쓰입니다. 다루는 대상이 다르니 문맥을 보고 가려 읽어야 합니다.

소프트웨어 공학에서는 이 이름이 개발 산출물의 변경을 통제하는 일을 가리킵니다. 우리말로는 흔히 형상 관리라고 옮깁니다. 소스 코드, 문서, 빌드 결과물 가운데 어느 버전끼리 한 묶음으로 내보냈는지를 기록합니다.

이때 기준으로 삼는 묶음이 베이스라인입니다. 베이스라인 뒤의 변경은 요청과 승인을 거쳐 들어갑니다. 기준을 적어 두고 거기서 벗어난 것을 잡는다는 생각은 서버 쪽 설정 관리와 같습니다.

애플리케이션 쪽에서는 프로그램이 읽는 설정 값을 다루는 일을 이렇게 부르기도 합니다. 개발 환경과 운영 환경마다 다른 접속 주소가 그런 값입니다. 환경 변수가 이쪽에 듭니다.

기능 플래그(기능을 켜고 끄는 값)도 여기에 듭니다. 재시작 없이 값을 바꾸는 동적 설정도 그렇습니다.

관련 항목

설정 관리가 맞추는 서버 안의 구성 요소

서버 · 패키지 · 설정 파일 · 데몬 · 사용자 계정 · 파일 권한

설정 관리를 하는 도구

앤서블 · 퍼펫 · 셰프 · 솔트스택 · CFEngine

설정 관리가 기대는 성질과 원칙

멱등성 · 선언적 설정 · 명령형 스크립트 · 원하는 상태 · 수렴

설정 관리가 막으려는 장애

구성 드리프트 · 눈송이 서버 · 설정 오류 · 토일

설정 관리가 선언 파일을 적고 나르는 수단

SSH · 에이전트 · YAML · 템플릿 엔진 · 버전관리 · 코드 리뷰 · 시크릿 관리

설정 관리와 일을 나누는 인프라 방식

코드형 인프라 · 프로비저닝 · 테라폼 · 불변 서버 · 머신 이미지 · Packer · 컨테이너 · 컨테이너 이미지 · GitOps

설정 관리가 속하는 상위 분야

인프라 · 데브옵스 · 릴리스 엔지니어링 · SRE · 시스템 관리

설정 관리라는 이름을 나눠 쓰는 다른 분야의 개념

소프트웨어 공학 · 베이스라인 · 변경 관리 · 환경 변수 · 기능 플래그 · 동적 설정

다른 이름: configuration management · 구성 관리 · 형상 관리