콘텐츠로 이동

계획을 정책으로 검사하기

malmok plan -o json은 계획을 문서로 출력합니다. 노드에서 무엇이든 바뀌기 전에 정책 엔진이 그 계획을 판정할 수 있습니다.

v0.96.6부터 제공

-o json 플래그와 policy/ 규칙은 v0.96.6에 들어왔습니다. 그 이전 릴리스에는 없습니다. 변경 이력과 설치 안내를 참고하십시오.

왜 계획인가

계획은 첫 변경 단계 직전의 마지막 산출물이며, 문서와 실측한 노드 상태의 순수 함수입니다. 여기서 거절하면 다시 실행하면 그만이고, 나중에 거절하면 절반만 지어진 클러스터가 남습니다.

계획은 문서와 같지 않습니다. cluster.yaml은 요청한 것을 적고, 계획은 실제로 설치될 것을 적습니다. 노드가 감당하지 못해 강등된 항목까지 포함해서 말입니다. 문서를 대상으로 쓴 규칙은 그 차이를 볼 수 없습니다.

실행

malmok plan -f cluster.yaml -o json | conftest test -

json 모드에서는 stdout에 계획만 나갑니다. 사람이 읽는 것 — 확정된 설정, 사전 점검 결과, 계획 표 — 은 전부 stderr로 가므로 파이프가 오염되지 않으면서 진행 상황도 그대로 보입니다.

계획에는 실제 노드가 필요합니다. plan은 사전 점검을 먼저 돌리고, 아무도 보지 않은 머신을 가정해 계획하는 것을 거부합니다. 따라서 이 검사는 현장에서 설치 직전에 하는 것이고, 아직 존재하지 않는 클러스터를 상대로 CI에서 돌릴 수는 없습니다.

--validate-only와 -o json을 함께 쓰면 거부합니다. 그 시점에는 계획이 없고, 빈 문서를 내보내면 여기가 아니라 파이프 건너편에서 터집니다.

종료 코드

plan은 사전 점검이 설치를 막을 때, 노드에 하나도 닿지 못했을 때, 그리고 문서가 요청한 구성을 강등해야 하는데 --approve가 없을 때 0이 아닌 값으로 끝납니다. json 모드에서는 마지막 검사보다 먼저 문서를 씁니다. 명령이 진행을 거부하더라도 파이프라인은 판정할 계획을 받습니다.

규칙이 말하는 것

규칙은 policy/에 있고, 주장의 종류로 나뉩니다. 둘은 같은 성격이 아닙니다.

deny — 계획이 스스로 모순인 경우. 사이트가 무엇에 합의했든 성립하므로 막을 값어치가 있는 쪽입니다:

규칙 무엇을 잡는가
기록되지 않은 데이터플레인 변경 actual이 requested와 다른데 이를 기록한 downgrade가 없음
기록되지 않은 스토리지 변경 스토리지 드라이버에 대한 동일 사안
근거 없는 강등 자신을 촉발한 프로브를 대지 못하는 downgrade
근거 없는 노드 제외 프로브 근거 없이 클러스터에서 빠지는 노드
빈 계획 노드가 하나도 없는 계획. 검사할 것이 없어 다른 규칙을 전부 통과함

앞의 둘이 중요한 이유는 감사 추적이 이 도구의 목적이기 때문입니다. 반년 뒤 질문은 "계약서에는 Cilium인데 왜 이 클러스터는 Traefik인가"이고, 기록되지 않은 대체는 답할 말이 없습니다.

warn — 판단의 주인이 따로 있는 경우. 제대로 기록된 강등은 결함이 아닙니다. 그것을 보이게 만들고 승인받게 하는 것이 이 도구의 일입니다. 이 사이트가 그것을 받아들일지는 말목과 함께 배포되는 규칙이 알 수 없으므로, 정하지 않고 알립니다:

  • 모든 강등 — 코드·대체 내용·사유와 함께
  • 클러스터에 합류하지 않게 되는 노드

직접 규칙 추가하기

policy/에 .rego 파일을 더 넣으면 됩니다. 같은 main 패키지에서 돌기 때문에 추가한 deny가 위의 규칙들과 함께 적용됩니다.

사이트 규칙은 보통 여기 있는 것들과 반대 모양입니다. "계획이 스스로 모순이다"가 아니라 "이 계약은 그 결과를 허용하지 않는다"입니다. 데이터플레인 고정이 가장 흔합니다:

package main

import rego.v1

deny contains msg if {
    input.actual.dataplane != "cilium-gw"
    msg := sprintf("이 사이트는 cilium-gw를 요구하는데 계획은 %q를 설치합니다", [input.actual.dataplane])
}

규칙 검증

규칙도 코드이므로 코드처럼 테스트합니다:

conftest verify

CI가 모든 푸시에서 conftest 버전을 고정한 채 이것을 돌립니다. 정책 언어가 규칙 아래에서 바뀌면 아무도 쓴 적 없는 문법 오류로 드러납니다.

예시 계획을 conftest test에 통과시키는 대신 rego 단위 테스트를 쓴 이유는, 실패해야 하는 픽스처는 명령을 0이 아닌 값으로 끝내기 때문입니다. 그러면 초록색 검사를 만들기 위해 어떤 문서에서는 종료 코드를 뒤집고 어떤 문서에서는 그대로 두어야 합니다.

CI가 검사하지 않는 것

CI는 규칙을 규칙끼리 검증합니다. 생성된 계획에 대고 돌리지는 않습니다. 계획은 실제 노드의 함수이고 CI에는 노드가 없기 때문입니다. 내부적으로 일관된 규칙도 실제 클러스터에 대해서는 틀릴 수 있으므로, 의존하기 전에 현장에서 파이프를 한 번 돌려보십시오.