Kubernetes 구성

Kubernetes 구성 (Configuration)

Cilium을 Kubernetes에서 운영할 때 cilium-config ConfigMap에서 조정할 수 있는 여러 옵션과 CNI 구성에 대해 설명해요. 디버그 모드, IPv4/IPv6, 모니터 집계, eBPF 상태 정리 등의 옵션을 다뤄요.

출처: Configuration

본문

ConfigMap 옵션 (ConfigMap Options)

ConfigMap에는 선호에 따라 구성할 수 있는 여러 옵션이 있어요:

  • debug - Cilium을 전체 디버그 모드로 실행하도록 설정해요. 상세 로깅을 활성화하고 eBPF 프로그램이 cilium-dbg monitor의 출력에 더 많은 가시성 이벤트를 내보내도록 구성해요.

  • enable-ipv4 - IPv4 주소 지정 지원 활성화.

  • enable-ipv6 - IPv6 주소 지정 지원 활성화.

  • clean-cilium-bpf-state - 시작 시 파일시스템에서 모든 eBPF 상태를 제거해요. 엔드포인트는 같은 IP 주소로 복원되지만 진행 중인 연결은 잠시 중단될 수 있고 로드 밸런싱 결정은 유실되어, 로드밸런서를 통한 활성 연결은 끊겨요. 모든 eBPF 상태는 원래 소스(예: Kubernetes 또는 kvstore)에서 재구성돼요. 이 옵션은 eBPF 맵 관련 심각한 문제를 완화하는 데 사용할 수 있어요. 데몬 재시작 후에는 이 옵션을 다시 꺼야 해요.

  • clean-cilium-state - 모든 Cilium 상태를 제거해요. 복구 불가능한 정보(예: 모든 엔드포인트 상태)와 복구 가능한 상태(예: 파일시스템에 pin된 eBPF 상태, CNI 구성 파일, 라이브러리 코드, 링크, 라우트 등)를 모두 포함해요. 이 작업은 되돌릴 수 없어요. 현재 Cilium이 관리하는 기존 엔드포인트는 이전처럼 계속 동작할 수 있지만, Cilium이 더 이상 관리하지 않게 되어 경고 없이 중단될 수 있어요. 이 작업을 사용한 후에는 새 Cilium 인스턴스가 관리할 수 있도록 엔드포인트를 삭제하고 다시 연결해야 해요.

  • monitor-aggregation - cilium-dbg monitor에서 추적 이벤트를 병합해서 활성 흐름의 주기적 업데이트나 L4 연결 상태 변경을 포함한 패킷만 포함하도록 해요. 유효한 옵션은 none, low, medium, maximum이에요.

    • none - 수신·송신 패킷마다 추적 이벤트 생성.
    • low - 송신 패킷마다 추적 이벤트 생성.
    • medium - 새 연결마다, 패킷 방향에서 이전에 보지 못한 TCP 플래그가 포함된 패킷마다, 평균적으로 monitor-aggregation-interval마다 한 번씩 송신 패킷에 대한 추적 이벤트를 생성해요(간격 동안 패킷이 보인다고 가정). 각 방향은 TCP 플래그와 보고 간격을 별도로 추적해요. Cilium이 패킷을 드롭하면 드롭된 패킷당 하나의 이벤트를 내보내요.
    • maximum - 가장 공격적인 집계 수준의 별칭이에요. 현재 monitor-aggregation을 medium으로 설정한 것과 동일해요.

    소켓 로드 밸런싱이 활성화되면 이 집계 수준은 소켓 변환 이벤트에도 적용돼요:

    • none - 모든 소켓 추적 이벤트 내보내기.
    • lowest/low - 역방향(recv) 소켓 추적 이벤트 억제.
    • medium/maximum - connect 시스템 콜에 대해서만 소켓 추적 이벤트 내보내기.
  • monitor-aggregation-interval - 추적 이벤트를 보고할 간격을 정의해요. monitor-aggregation 수준이 medium 이상인 경우에만 적용돼요. 새 패킷이 간격마다 최소 한 번 보내진다고 가정하면, 간격 동안 평균적으로 하나의 이벤트가 전송되도록 보장해요.

  • preallocate-bpf-maps - 맵 항목의 선할당은 맵의 항목에 대한 사전 메모리 할당 비용을 대가로 패킷당 지연 시간을 줄여줘요. 지연 시간에 최적화하려면 true로 설정하세요. 이 값을 수정하면 다음 Cilium 시작 중 활성 연결이 있는 엔드포인트의 연결성이 일시적으로 중단될 수 있어요.

Cilium ConfigMap과 cilium-etcd-secrets Secret에서 수행하는 모든 변경은, 기존 Cilium 파드를 재시작해야 최신 구성을 적용받을 수 있어요.

Attention ConfigMap에서 키나 값을 업데이트할 때, 변경 사항이 클러스터의 모든 노드에 전파되는 데 최대 2분이 걸릴 수 있어요. 자세한 내용은 공식 Kubernetes 문서를 참고하세요: Mounted ConfigMaps are updated automatically

다음 ConfigMap은 etcd 클러스터가 2개 노드(node-1, node-2)에서 TLS 및 클라이언트-서버 인증을 활성화한 채 실행되는 예시예요.

apiVersion: v1
kind: ConfigMap
metadata:
  name: cilium-config
  namespace: kube-system
data:
  # The kvstore configuration is used to enable use of a kvstore for state
  # storage.
  kvstore: etcd
  kvstore-opt: '{"etcd.config": "/var/lib/etcd-config/etcd.config"}'

  # This etcd-config contains the etcd endpoints of your cluster. If you use
  # TLS please make sure you follow the tutorial in https://cilium.link/etcd-config
  etcd-config: |-
    ---
    endpoints:
      - https://node-1:31079
      - https://node-2:31079
    #
    # In case you want to use TLS in etcd, uncomment the 'trusted-ca-file' line
    # and create a kubernetes secret by following the tutorial in
    # https://cilium.link/etcd-config
    trusted-ca-file: '/var/lib/etcd-secrets/etcd-client-ca.crt'
    #
    # In case you want client to server authentication, uncomment the following
    # lines and create a kubernetes secret by following the tutorial in
    # https://cilium.link/etcd-config
    key-file: '/var/lib/etcd-secrets/etcd-client.key'
    cert-file: '/var/lib/etcd-secrets/etcd-client.crt'

  # If you want to run cilium in debug mode change this value to true
  debug: "false"
  enable-ipv4: "true"
  # If you want to clean cilium state; change this value to true
  clean-cilium-state: "false"

CNI

제공된 DaemonSet을 통해 Cilium을 배포할 때 CNI 구성은 자동으로 처리돼요. cilium 파드는 시작 시 적절한 CNI 구성 파일을 생성해 디스크에 작성해요.

Note CNI 설치가 제대로 동작하려면 kubelet 작업이 워커 노드의 호스트 파일시스템에서 실행 중이거나, /etc/cni/net.d와 /opt/cni/bin 디렉터리가 kubelet이 실행 중인 컨테이너에 마운트되어야 해요. 이는 Volumes 마운트로 달성할 수 있어요.

CNI 자동 설치는 다음과 같이 수행돼요:

  1. /etc/cni/net.d와 /opt/cni/bin 디렉터리가 호스트 파일시스템에서 Cilium이 실행 중인 파드로 마운트돼요.
  2. 바이너리 cilium-cni가 /opt/cni/bin에 설치돼요. cilium-cni라는 이름의 기존 바이너리는 덮어써져요.
  3. 파일 /etc/cni/net.d/05-cilium.conflist가 작성돼요.

CNI 구성 조정 (Adjusting CNI configuration)

CNI 구성 파일은 cilium 파드가 자동으로 작성하고 유지관리해요. agent가 초기화를 마치고 파드 샌드박스 생성을 처리할 준비가 된 후에 작성돼요. 또한 agent는 기본적으로 다른 CNI 구성 파일을 제거해요.

CNI 구성 관리를 조정하는 여러 Helm 변수가 있어요. 전체 설명은 helm 문서를 참고하세요. 간단히 요약하면:

Helm variable Description Default
cni.customConf Disable CNI configuration management false
cni.exclusive Remove other CNI configuration files true
cni.install Install CNI configuration and binaries true

자체 커스텀 CNI 구성 파일을 제공하려면, 디스크에 있거나 configMap으로 제공되는 cni 템플릿 파일의 경로를 전달하면 돼요. 이를 구성하는 Helm 옵션은 다음과 같아요:

Helm variable Description
cni.readCniConf Path (inside the agent) to a source CNI configuration file
cni.configMap Name of a ConfigMap containing a source CNI configuration file
cni.configMapKey Install CNI configuration and binaries

이 Helm 변수들은 더 작은 set의 cilium ConfigMap 키로 변환돼요:

ConfigMap key Description
write-cni-conf-when-ready Path to write the CNI configuration file
read-cni-conf Path to read the source CNI configuration file
cni-exclusive Whether or not to remove other CNI configuration files

CRD 검증 (CRD Validation)

커스텀 리소스 검증은 Kubernetes 1.8.0부터 도입됐어요. Kubernetes 1.8.0에서는 여전히 alpha 기능, Kubernetes 1.9.0에서는 beta 기능으로 간주돼요.

Cilium v1.0.0-rc3부터 Cilium은 검증 스키마가 포함된 Cilium Network Policy(CNP) Resource Definition을 생성하거나, 존재하면 업데이트해요. 이를 통해 CiliumNetworkPolicy가 리소스 가져오기 시점에 kube-apiserver에서 검증되어, 가져올 때 직접적인 피드백을 제공할 수 있어요.

이 기능을 활성화하려면 kube-apiserver를 시작할 때 --feature-gates=CustomResourceValidation=true 플래그를 설정해야 해요. Cilium 자체는 이 기능을 자동으로 활용하며 추가 플래그가 필요 없어요.

Note 검증기가 포함된 Cilium v1.0.0-rc3로 업데이트하기 전에 잘못된 CNP가 있는 경우, kube-apiserver 검증기는 Cilium이 그 잘못된 CNP를 Cilium 노드 상태로 업데이트하는 것을 막아요. Cilium 로그에서 unable to update CNP, retrying...을 확인하면 Cilium v1.0.0-rc3 업데이트 후 어떤 Cilium Network Policy가 잘못된 것으로 간주되는지 판단할 수 있어요.

CNP 리소스 정의에 검증 스키마가 포함되어 있는지 확인하려면 다음 명령을 실행하세요:

$ kubectl get crd ciliumnetworkpolicies.cilium.io -o json | grep -A 12 openAPIV3Schema
        "openAPIV3Schema": {
            "oneOf": [
                {
                    "required": [
                        "spec"
                    ]
                },
                {
                    "required": [
                        "specs"
                    ]
                }
            ],

사용자가 스키마에 맞지 않는 정책을 작성하면 Kubernetes가 다음과 같은 오류를 반환해요:

cat <<EOF > ./bad-cnp.yaml
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
  name: my-new-cilium-object
spec:
  description: "Policy to test multiple rules in a single file"
  endpointSelector:
    matchLabels:
      app: details
      track: stable
      version: v1
  ingress:
  - fromEndpoints:
    - matchLabels:
        app: reviews
        track: stable
        version: v1
    toPorts:
    - ports:
      - port: '65536'
        protocol: TCP
      rules:
        http:
        - method: GET
          path: "/health"
EOF

kubectl create -f ./bad-cnp.yaml
...
spec.ingress.toPorts.ports.port in body should match '^(6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|6[0-4][0-9]{3}|[1-5][0-9]{4}|[0-9]{1,4})$'

이 경우 정책의 포트가 0-65535 범위를 벗어났어요.

systemd로 BPFFS 마운트 (Mounting BPFFS with systemd)

systemd가 파일시스템을 마운트하는 방식 때문에, 마운트 지점 경로는 유닛 파일 이름에 반영되어야 해요.

cat <<EOF | sudo tee /etc/systemd/system/sys-fs-bpf.mount
[Unit]
Description=Cilium BPF mounts
Documentation=https://docs.cilium.io/
DefaultDependencies=no
Before=local-fs.target umount.target
After=swap.target

[Mount]
What=bpffs
Where=/sys/fs/bpf
Type=bpf
Options=rw,nosuid,nodev,noexec,relatime,mode=700

[Install]
WantedBy=multi-user.target
EOF

컨테이너 런타임 (Container Runtimes)

CRIO

CRIO를 사용하려면 아래 지침을 사용하세요.

Helm 저장소를 설정하세요:

Helm Repository OCI Registry

helm repo add cilium https://helm.cilium.io/

Cilium 차트는 OCI 레지스트리(Quay.io 및 Docker Hub)에서도 사용할 수 있어요. 설정이 필요 없으며 oci:// URL로 직접 설치할 수 있어요.

차트 서명 검증과 digest 기반 설치를 포함한 자세한 내용은 OCI Registry section을 참고하세요.

Note Helm 플래그 --set bpf.autoMount.enabled=false는 설정에 따라 필요하지 않을 수 있어요. 자세한 내용은 Common CRIO issues를 참고하세요.

Helm Repository OCI Registry

helm install cilium cilium/cilium --version 1.20.2 \
   --namespace kube-system
helm install cilium oci://quay.io/cilium/charts/cilium 1.20.2 \
   --namespace kube-system

CRI-O는 새 CNI 플러그인이 설치된 것을 자동으로 감지하지 않으므로, Cilium CNI 구성을 감지하도록 CRI-O 데몬을 재시작해야 해요.

먼저 Cilium이 실행 중인지 확인하세요:

$ kubectl get pods -n kube-system -o wide
NAME               READY     STATUS    RESTARTS   AGE       IP          NODE
cilium-mqtdz       1/1       Running   0          3m       10.0.2.15   minikube

그 후 CRI-O를 재시작할 수 있어요:

minikube ssh -- sudo systemctl restart crio

Common CRIO issues

일부 CRI-O 환경은 파드에 bpf 파일시스템을 자동으로 마운트하는데, Cilium은 --set bpf.autoMount.enabled=false가 설정되면 이를 피해요. 그러나 일부 CRI-O 환경은 bpf 파일시스템을 자동으로 마운트하지 않아서 Cilium이 다음 메시지를 출력하게 해요:

level=warning msg="BPF system config check: NOT OK." error="CONFIG_BPF kernel parameter is required" subsys=linux-datapath
level=warning msg="================================= WARNING ==========================================" subsys=bpf
level=warning msg="BPF filesystem is not mounted. This will lead to network disruption when Cilium pods" subsys=bpf
level=warning msg="are restarted. Ensure that the BPF filesystem is mounted in the host." subsys=bpf
level=warning msg="https://docs.cilium.io/en/stable/operations/system_requirements/#mounted-ebpf-filesystem" subsys=bpf
level=warning msg="==================================================================================== " subsys=bpf
level=info msg="Mounting BPF filesystem at /sys/fs/bpf" subsys=bpf

CRI-O 환경에서 Cilium 파드 로그에 이 경고가 보이면, Helm 설정에서 --set bpf.autoMount.enabled=false 플래그를 제거하고 Cilium을 재배포하세요.

더 알아보기 (Learn more)