devlos
Devlos Archive
devlos
전체 방문자
오늘
어제
12-09 13:26

최근 글

  • 분류 전체보기 (107)
    • 프로젝트 (1)
    • MSA 설계 & 도메인주도 설계 (9)
    • 클라우드 컴퓨팅 & NoSQL (87)
      • [Cilium Study] 실리움 스터디 (8)
      • [KANS] 쿠버네티스 네트워크 심화 스터디 (12)
      • [T101] 테라폼 4기 스터디 (8)
      • [CICD] CICD 맛보기 스터디 (3)
      • [T101] 테라폼 기초 입문 스터디 (6)
      • [AEWS] Amazon EKS 워크숍 스터디 (7)
      • [PKOS] 쿠버네티스 실무 실습 스터디 (7)
      • Kubernetes (13)
      • Docker (7)
      • Redis (1)
      • Jenkins (3)
      • Terraform (1)
      • Ansible (4)
      • Kafka (1)
    • 프로그래밍 (7)
      • Spring Boot (5)
      • Broker (1)
    • 성능과 튜닝 (1)
    • ALM (0)
    • 기타 (2)

인기 글

태그

  • terraform
  • DevOps
  • PKOS
  • kOps
  • 테라폼
  • 도커
  • 데브옵스
  • Kubernetes
  • cilium
  • 쿠버네티스
  • MSA
  • CloudNet@
  • 쿠버네티스 스터디
  • t101 4기
  • docker

티스토리

최근 댓글

hELLO · Designed By 정상우.
devlos

Devlos Archive

[2주차 - Cilium 스터디] (Observabilty) Hubbkem Prometheus/Grafana (25.07.20)
클라우드 컴퓨팅 & NoSQL/[Cilium Study] 실리움 스터디

[2주차 - Cilium 스터디] (Observabilty) Hubbkem Prometheus/Grafana (25.07.20)

2025. 7. 26. 05:21
반응형

들어가며

안녕하세요! Devlos입니다.

 

전국의 클라우드 엔지니어들과 함께 성장하는 즐거움을 느끼며, 이번 주차도 힘차게 시작해 보겠습니다! 빠라밤.

 

.

.

.

 

이번 포스팅은 CloudNet@ 커뮤니티에서 주최하는 Cilium 스터디 2주 차 주제인 "(Observabilty) Hubbkem Prometheus/Grafana"에 대해서 정리한 내용입니다.


실습환경 구성

이번 주차 실습 환경은 mac M3 Pro max 환경에서 실습을 진행했고, VirtualBox + Vagrant로 환경을 구성했어요.
Cilium 최초 설치시 Hubble 및 기타 내용들을 실습히며 구성하기 위해 위해서 제외하고 설치합니다.

Virtual Box, Vagrant 설치

  • Vagrantfile : 가상머신 정의, 부팅 시 초기 프로비저닝 설정
    # Variables
    K8SV = '1.33.2-1.1' # Kubernetes Version : apt list -a kubelet , ex) 1.32.5-1.1
    CONTAINERDV = '1.7.27-1' # Containerd Version : apt list -a containerd.io , ex) 1.6.33-1
    CILIUMV = '1.17.6' # Cilium CNI Version : https://github.com/cilium/cilium/tags
    N = 2 # max number of worker nodes

    # Base Image  https://portal.cloud.hashicorp.com/vagrant/discover/bento/ubuntu-24.04
    BOX_IMAGE = "bento/ubuntu-24.04"
    BOX_VERSION = "202502.21.0"

    Vagrant.configure("2") do |config|
    #-ControlPlane Node
        config.vm.define "k8s-ctr" do |subconfig|
          subconfig.vm.box = BOX_IMAGE

          subconfig.vm.box_version = BOX_VERSION
          subconfig.vm.provider "virtualbox" do |vb|
            vb.customize ["modifyvm", :id, "--groups", "/Cilium-Lab"] # VirtualBox에서 VM 그룹 지정
            vb.customize ["modifyvm", :id, "--nicpromisc2", "allow-all"] # 네트워크 카드 프로미스큐어스 모드 활성화 (네트워킹 실습을 위해 필요)
            vb.name = "k8s-ctr"
            vb.cpus = 2
            vb.memory = 2048 # 컨트롤 플레인은 더 많은 메모리 필요
            vb.linked_clone = true # 디스크 공간 절약을 위한 링크드 클론 사용
          end
          subconfig.vm.host_name = "k8s-ctr"
          subconfig.vm.network "private_network", ip: "192.168.10.100" # 컨트롤 플레인 고정 IP
          subconfig.vm.network "forwarded_port", guest: 22, host: 60000, auto_correct: true, id: "ssh"
          subconfig.vm.synced_folder "./", "/vagrant", disabled: true
          subconfig.vm.provision "shell", path: "init_cfg.sh", args: [ K8SV, CONTAINERDV ] # 기본 시스템 설정 및 K8s 컴포넌트 설치
          subconfig.vm.provision "shell", path: "k8s-ctr.sh", args: [ N, CILIUMV ] # 마스터 노드 설정 및 Cilium CNI 설치
        end

    #-Worker Nodes Subnet1
      (1..N).each do |i|
        config.vm.define "k8s-w#{i}" do |subconfig|
          subconfig.vm.box = BOX_IMAGE
          subconfig.vm.box_version = BOX_VERSION
          subconfig.vm.provider "virtualbox" do |vb|
            vb.customize ["modifyvm", :id, "--groups", "/Cilium-Lab"]
            vb.customize ["modifyvm", :id, "--nicpromisc2", "allow-all"]
            vb.name = "k8s-w#{i}"
            vb.cpus = 2
            vb.memory = 1536 # 워커 노드는 상대적으로 적은 메모리
            vb.linked_clone = true
          end
          subconfig.vm.host_name = "k8s-w#{i}"
          subconfig.vm.network "private_network", ip: "192.168.10.10#{i}" # 워커 노드 순차적 IP 할당
          subconfig.vm.network "forwarded_port", guest: 22, host: "6000#{i}", auto_correct: true, id: "ssh"
          subconfig.vm.synced_folder "./", "/vagrant", disabled: true
          subconfig.vm.provision "shell", path: "init_cfg.sh", args: [ K8SV, CONTAINERDV] # 기본 시스템 설정
          subconfig.vm.provision "shell", path: "k8s-w.sh" # 워커 노드 클러스터 조인
        end
      end

    end
  • init_cfg.sh : args 참고하여 설치
    #!/usr/bin/env bash

    echo ">>>> Initial Config Start <<<<"

    echo "[TASK 1] Setting Profile & Bashrc"
    echo 'alias vi=vim' >> /etc/profile
    echo "sudo su -" >> /home/vagrant/.bashrc
    ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime # Change Timezone

    echo "[TASK 2] Disable AppArmor"
    systemctl stop ufw && systemctl disable ufw >/dev/null 2>&1 # 방화벽 비활성화 (실습 환경용)
    systemctl stop apparmor && systemctl disable apparmor >/dev/null 2>&1 # AppArmor 보안 정책 비활성화 (K8s 호환성)

    echo "[TASK 3] Disable and turn off SWAP"
    swapoff -a && sed -i '/swap/s/^/#/' /etc/fstab # K8s는 SWAP 비활성화 필수

    echo "[TASK 4] Install Packages"
    apt update -qq >/dev/null 2>&1
    apt-get install apt-transport-https ca-certificates curl gpg -y -qq >/dev/null 2>&1

    # Download the public signing key for the Kubernetes package repositories.
    mkdir -p -m 755 /etc/apt/keyrings
    K8SMMV=$(echo $1 | sed -En 's/^([0-9]+\.[0-9]+)\..*/\1/p') # K8s 메이저.마이너 버전 추출
    curl -fsSL https://pkgs.k8s.io/core:/stable:/v$K8SMMV/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
    echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v$K8SMMV/deb/ /" >> /etc/apt/sources.list.d/kubernetes.list
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
    echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null

    # packets traversing the bridge are processed by iptables for filtering
    echo 1 > /proc/sys/net/ipv4/ip_forward # IP 포워딩 활성화 (Pod 간 통신을 위해 필수)
    echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.d/k8s.conf

    # enable br_netfilter for iptables 
    modprobe br_netfilter # 브리지 네트워크 필터링 모듈 로드 (CNI 네트워킹용)
    modprobe overlay # 오버레이 파일시스템 모듈 (컨테이너 이미지 레이어용)
    echo "br_netfilter" >> /etc/modules-load.d/k8s.conf
    echo "overlay" >> /etc/modules-load.d/k8s.conf

    echo "[TASK 5] Install Kubernetes components (kubeadm, kubelet and kubectl)"
    # Update the apt package index, install kubelet, kubeadm and kubectl, and pin their version
    apt update >/dev/null 2>&1

    # apt list -a kubelet ; apt list -a containerd.io
    apt-get install -y kubelet=$1 kubectl=$1 kubeadm=$1 containerd.io=$2 >/dev/null 2>&1 # 특정 버전 고정 설치
    apt-mark hold kubelet kubeadm kubectl >/dev/null 2>&1 # 패키지 버전 고정 (자동 업데이트 방지)

    # containerd configure to default and cgroup managed by systemd
    containerd config default > /etc/containerd/config.toml
    sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml # systemd cgroup 드라이버 사용 (K8s 권장)

    # avoid WARN&ERRO(default endpoints) when crictl run  
    cat <<EOF > /etc/crictl.yaml
    runtime-endpoint: unix:///run/containerd/containerd.sock
    image-endpoint: unix:///run/containerd/containerd.sock
    EOF

    # ready to install for k8s 
    systemctl restart containerd && systemctl enable containerd
    systemctl enable --now kubelet # kubelet 서비스 활성화 및 시작

    echo "[TASK 6] Install Packages & Helm"
    export DEBIAN_FRONTEND=noninteractive
    apt-get install -y bridge-utils sshpass net-tools conntrack ngrep tcpdump ipset arping wireguard jq tree bash-completion unzip kubecolor termshark >/dev/null 2>&1 # 네트워킹 및 디버깅 도구들
    curl -s https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash >/dev/null 2>&1 # Helm 패키지 매니저 설치

    echo ">>>> Initial Config End <<<<"
  • k8s-ctr.sh : kubeadm init, Cilium CNI 설치, 편리성 설정(k, kc)
  • kubeadm-init-ctr-config.yaml ⇒ 'kubernetesVersion: v1.33.2' 기본 설정 변수 값 받을 수 있게 수정 해둘것!
        apiVersion: kubeadm.k8s.io/v1beta4
        kind: **InitConfiguration**
        bootstrapTokens:
        - token: "123456.1234567890123456" # 워커 노드가 클러스터에 조인할 때 사용할 토큰
          ttl: "0s" # 토큰 만료 시간 (0s = 무제한)
          usages:
          - signing
          - authentication
        localAPIEndpoint:
          advertiseAddress: "192.168.10.100" # API 서버가 광고할 IP 주소
        nodeRegistration:
          **kubeletExtraArgs:
            - name: node-ip
              value: "192.168.10.100"** # kubelet이 사용할 노드 IP 명시적 지정
          criSocket: "unix:///run/containerd/containerd.sock" # 컨테이너 런타임 소켓
        ---
        apiVersion: kubeadm.k8s.io/v1beta4
        kind: **ClusterConfiguration**
        kubernetesVersion: v1.33.2 # 설치할 K8s 버전
        networking:
          podSubnet: "10.244.0.0/16" # Pod CIDR 범위
          serviceSubnet: "10.96.0.0/16" # Service CIDR 범위
    #!/usr/bin/env bash

    echo ">>>> K8S Controlplane config Start <<<<"

    echo "[TASK 1] Initial Kubernetes"
    curl --silent -o /root/kubeadm-init-ctr-config.yaml https://raw.githubusercontent.com/gasida/vagrant-lab/refs/heads/main/cilium-study/2w/kubeadm-init-ctr-config.yaml
    kubeadm init --config="/root/kubeadm-init-ctr-config.yaml" --skip-phases=addon/kube-proxy  >/dev/null 2>&1 # kube-proxy 건너뛰기 (Cilium이 대체)

    echo "[TASK 2] Setting kube config file"
    mkdir -p /root/.kube
    cp -i /etc/kubernetes/admin.conf /root/.kube/config # kubectl 설정 파일 복사
    chown $(id -u):$(id -g) /root/.kube/config

    echo "[TASK 3] Source the completion"
    echo 'source <(kubectl completion bash)' >> /etc/profile # kubectl 자동완성 활성화
    echo 'source <(kubeadm completion bash)' >> /etc/profile

    echo "[TASK 4] Alias kubectl to k"
    echo 'alias k=kubectl' >> /etc/profile # kubectl 단축 명령어
    echo 'alias kc=kubecolor' >> /etc/profile # 컬러 출력용 kubectl 대체
    echo 'complete -F __start_kubectl k' >> /etc/profile

    echo "[TASK 5] Install Kubectx & Kubens"
    git clone https://github.com/ahmetb/kubectx /opt/kubectx >/dev/null 2>&1 # 컨텍스트/네임스페이스 전환 도구
    ln -s /opt/kubectx/kubens /usr/local/bin/kubens
    ln -s /opt/kubectx/kubectx /usr/local/bin/kubectx

    echo "[TASK 6] Install Kubeps & Setting PS1"
    git clone https://github.com/jonmosco/kube-ps1.git /root/kube-ps1 >/dev/null 2>&1
    cat <<"EOT" >> /root/.bash_profile
    source /root/kube-ps1/kube-ps1.sh
    KUBE_PS1_SYMBOL_ENABLE=true
    function get_cluster_short() {
      echo "$1" | cut -d . -f1
    }
    KUBE_PS1_CLUSTER_FUNCTION=get_cluster_short
    KUBE_PS1_SUFFIX=') '
    PS1='$(kube_ps1)'$PS1 # 프롬프트에 현재 K8s 컨텍스트 표시
    EOT
    kubectl config rename-context "kubernetes-admin@kubernetes" "HomeLab" >/dev/null 2>&1

    echo "[TASK 7] Install Cilium CNI"
    NODEIP=$(ip -4 addr show eth1 | grep -oP '(?<=inet\s)\d+(\.\d+){3}')
    helm repo add cilium https://helm.cilium.io/ >/dev/null 2>&1
    helm repo update >/dev/null 2>&1
    helm install cilium cilium/cilium --version $2 --namespace kube-system \
    --set k8sServiceHost=192.168.10.100 --set k8sServicePort=6443 \ # API 서버 접속 정보
    --set ipam.mode="cluster-pool" --set ipam.operator.clusterPoolIPv4PodCIDRList={"172.20.0.0/16"} --set ipv4NativeRoutingCIDR=172.20.0.0/16 \ # IPAM 설정
    --set routingMode=native --set autoDirectNodeRoutes=true --set endpointRoutes.enabled=true \ # 네이티브 라우팅 모드 (성능 최적화)
    --set kubeProxyReplacement=true --set bpf.masquerade=true --set installNoConntrackIptablesRules=true \ # kube-proxy 완전 대체
    **--set endpointHealthChecking.enabled=false --set healthChecking=false \** # 엔드포인트 헬스체크 비활성화 (실습용)
    **--set hubble.enabled=false** --set operator.replicas=1 --set debug.enabled=true >/dev/null 2>&1 # Hubble 비활성화 (이번 주차에서는 제외)

    echo "[TASK 8] Install Cilium CLI"
    CILIUM_CLI_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/cilium-cli/main/stable.txt)
    CLI_ARCH=amd64
    if [ "$(uname -m)" = "aarch64" ]; then CLI_ARCH=arm64; fi # ARM64 아키텍처 감지
    curl -L --fail --remote-name-all https://github.com/cilium/cilium-cli/releases/download/${CILIUM_CLI_VERSION}/cilium-linux-${CLI_ARCH}.tar.gz >/dev/null 2>&1
    tar xzvfC cilium-linux-${CLI_ARCH}.tar.gz /usr/local/bin
    rm cilium-linux-${CLI_ARCH}.tar.gz

    echo "[TASK 9] local DNS with hosts file"
    echo "192.168.10.100 k8s-ctr" >> /etc/hosts # 로컬 DNS 설정
    for (( i=1; i<=$1; i++  )); do echo "192.168.10.10$i k8s-w$i" >> /etc/hosts; done

    echo ">>>> K8S Controlplane Config End <<<<"
  • --set endpointHealthChecking.enabled=false and --set healthChecking=false disable endpoint health checking는 false로 설정
  • k8s-w.sh : kubeadm join
  • kubeadm-join-worker-config.yaml
        apiVersion: kubeadm.k8s.io/v1beta4
        kind: JoinConfiguration
        discovery:
          bootstrapToken:
            token: "123456.1234567890123456" # 컨트롤 플레인과 동일한 토큰
            apiServerEndpoint: "192.168.10.100:6443" # API 서버 엔드포인트
            unsafeSkipCAVerification: true # CA 인증서 검증 건너뛰기 (실습 환경용)
        nodeRegistration:
          criSocket: "unix:///run/containerd/containerd.sock"
          kubeletExtraArgs:
            - name: node-ip
              value: "NODE_IP_PLACEHOLDER" # 스크립트에서 실제 IP로 교체됨
    #!/usr/bin/env bash

    echo ">>>> K8S Node config Start <<<<"

    echo "[TASK 1] K8S Controlplane Join"
    curl --silent -o /root/kubeadm-join-worker-config.yaml https://raw.githubusercontent.com/gasida/vagrant-lab/refs/heads/main/cilium-study/2w/kubeadm-join-worker-config.yaml
    NODEIP=$(ip -4 addr show eth1 | grep -oP '(?<=inet\s)\d+(\.\d+){3}') # eth1 인터페이스에서 IP 추출
    sed -i "s/NODE_IP_PLACEHOLDER/${NODEIP}/g" /root/kubeadm-join-worker-config.yaml # 플레이스홀더를 실제 IP로 교체
    kubeadm join --config="/root/kubeadm-join-worker-config.yaml" > /dev/null 2>&1 # 클러스터에 워커 노드로 조인

    echo ">>>> K8S Node config End <<<<"

Vagrant 실행

실습 파일들을 다운로드하고 실행해보겠습니다.

# 실습 디렉토리 생성 및 이동
mkdir cilium-lab && cd cilium-lab

# Vagrantfile 다운로드
curl -O https://raw.githubusercontent.com/gasida/vagrant-lab/refs/heads/main/cilium-study/2w/Vagrantfile

# 가상머신 생성 및 실행
vagrant up

만약 기존 VM이 존재할 경우 발생하는 오류:

❯ vagrant up
A VirtualBox machine with the name 'k8s-ctr' already exists.
Please use another name or delete the machine with the existing
name, and try again.

해결 방법:

# 1. 기존 VirtualBox VM 확인
VBoxManage list vms

# 2. 기존 VM 삭제 (전체)
VBoxManage unregistervm k8s-ctr --delete
VBoxManage unregistervm k8s-w1 --delete  
VBoxManage unregistervm k8s-w2 --delete

# 3. 또는 Vagrant로 정리 (만약 이전에 vagrant로 생성했다면)
vagrant destroy -f

# 4. 다시 실행
vagrant up

✅ 실행 결과(요약)

정상적으로 실행되면 다음과 같은 과정을 거칩니다:

# 1. 기존 VM 정리 (필요시)
❯ VBoxManage unregistervm k8s-ctr --delete
VBoxManage unregistervm k8s-w1 --delete
VBoxManage unregistervm k8s-w2 --delete
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%

# 2. Vagrant 실행
❯ vagrant up
Bringing machine 'k8s-ctr' up with 'virtualbox' provider...
Bringing machine 'k8s-w1' up with 'virtualbox' provider...
Bringing machine 'k8s-w2' up with 'virtualbox' provider...

# 3. 컨트롤 플레인 노드 설정 (k8s-ctr)
==> k8s-ctr: Setting the name of the VM: k8s-ctr
==> k8s-ctr: Booting VM...
==> k8s-ctr: Running provisioner: shell...
    k8s-ctr: >>>> Initial Config Start <<<<
    k8s-ctr: [TASK 1] Setting Profile & Bashrc
    k8s-ctr: [TASK 2] Disable AppArmor
    k8s-ctr: [TASK 3] Disable and turn off SWAP
    k8s-ctr: [TASK 4] Install Packages
    k8s-ctr: [TASK 5] Install Kubernetes components (kubeadm, kubelet and kubectl)
    k8s-ctr: [TASK 6] Install Packages & Helm
    k8s-ctr: >>>> Initial Config End <<<<

    k8s-ctr: >>>> K8S Controlplane config Start <<<<
    k8s-ctr: [TASK 1] Initial Kubernetes
    k8s-ctr: [TASK 2] Setting kube config file
    k8s-ctr: [TASK 3] Source the completion
    k8s-ctr: [TASK 4] Alias kubectl to k
    k8s-ctr: [TASK 5] Install Kubectx & Kubens
    k8s-ctr: [TASK 6] Install Kubeps & Setting PS1
    k8s-ctr: [TASK 7] Install Cilium CNI
    k8s-ctr: [TASK 8] Install Cilium CLI
    k8s-ctr: [TASK 9] local DNS with hosts file
    k8s-ctr: >>>> K8S Controlplane Config End <<<<

# 4. 워커 노드 1 설정 (k8s-w1)
==> k8s-w1: Setting the name of the VM: k8s-w1
==> k8s-w1: Booting VM...
    k8s-w1: >>>> Initial Config Start <<<<
    k8s-w1: [TASK 1] Setting Profile & Bashrc
    k8s-w1: [TASK 2] Disable AppArmor
    k8s-w1: [TASK 3] Disable and turn off SWAP
    k8s-w1: [TASK 4] Install Packages
    k8s-w1: [TASK 5] Install Kubernetes components (kubeadm, kubelet and kubectl)
    k8s-w1: [TASK 6] Install Packages & Helm
    k8s-w1: >>>> Initial Config End <<<<

    k8s-w1: >>>> K8S Node config Start <<<<
    k8s-w1: [TASK 1] K8S Controlplane Join
    k8s-w1: >>>> K8S Node config End <<<<

# 5. 워커 노드 2 설정 (k8s-w2)
==> k8s-w2: Setting the name of the VM: k8s-w2
==> k8s-w2: Booting VM...
    k8s-w2: >>>> K8S Node config Start <<<<
    k8s-w2: [TASK 1] K8S Controlplane Join
    k8s-w2: >>>> K8S Node config End <<<<

전체 설치 과정은 약 10-15분 정도 소요됩니다.

실습 환경 접속 및 확인

# 컨트롤 플레인 노드 접속
vagrant ssh k8s-ctr

# 클러스터 상태 확인
kubectl get nodes

정상 설치 시 출력 예시:

(HomeLab) root@k8s-ctr:~# kubectl get nodes
NAME      STATUS   ROLES           AGE   VERSION
k8s-ctr   Ready    control-plane   5m    v1.33.2
k8s-w1    Ready    <none>          3m    v1.33.2
k8s-w2    Ready    <none>          2m    v1.33.2
# Cilium 상태 확인
cilium status

Cilium 정상 동작 출력 예시:

    /¯¯\
 /¯¯\__/¯¯\    Cilium:             OK
 \__/¯¯\__/    Operator:           OK
 /¯¯\__/¯¯\    Envoy DaemonSet:    OK
 \__/¯¯\__/    Hubble Relay:       disabled
    \__/       ClusterMesh:        disabled

DaemonSet              cilium                   Desired: 3, Ready: 3/3, Available: 3/3
DaemonSet              cilium-envoy             Desired: 3, Ready: 3/3, Available: 3/3
Deployment             cilium-operator          Desired: 1, Ready: 1/1, Available: 1/1
Containers:            cilium                   Running: 3
                       cilium-envoy             Running: 3
                       cilium-operator          Running: 1
                       clustermesh-apiserver    
                       hubble-relay             
Cluster Pods:          2/2 managed by Cilium
Helm chart version:    1.17.6
Image versions         cilium             quay.io/cilium/cilium:v1.17.6@sha256:544de3d4fed7acba72758413812780a4972d47c39035f2a06d6145d8644a3353: 3
                       cilium-envoy       quay.io/cilium/cilium-envoy:v1.33.4-1752151664-7c2edb0b44cf95f326d628b837fcdd845102ba68@sha256:318eff387835ca2717baab42a84f35a83a5f9e7d519253df87269f80b9ff0171: 3
                       cilium-operator    quay.io/cilium/operator-generic:v1.17.6@sha256:91ac3bf7be7bed30e90218f219d4f3062a63377689ee7246062fa0cc3839d096: 1

[k8s-ctr] 접속 후 기본 정보 확인

# 호스트 파일 및 노드 연결 확인
cat /etc/hosts
sshpass -p 'vagrant' ssh -o StrictHostKeyChecking=no vagrant@k8s-w1 hostname
sshpass -p 'vagrant' ssh -o StrictHostKeyChecking=no vagrant@k8s-w2 hostname

# 네트워크 인터페이스 확인
ifconfig | grep -iEA1 'eth[0-9]:'

# 클러스터 정보 확인
kubectl cluster-info
kubectl cluster-info dump | grep -m 2 -E "cluster-cidr|service-cluster-ip-range"

# 노드 정보 : 상태, INTERNAL-IP 확인
kubectl get node -owide

# 노드별 kubeadm-flags.env 정보 확인
cat /var/lib/kubelet/kubeadm-flags.env
for i in w1 w2 ; do echo ">> node : k8s-$i <<"; sshpass -p 'vagrant' ssh vagrant@k8s-$i cat /var/lib/kubelet/kubeadm-flags.env ; echo; done

# 파드 정보 : 상태, 파드 IP 확인
kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.podCIDR}{"\n"}{end}'
kubectl get ciliumnode -o json | grep podCIDRs -A2
kubectl get pod -A -owide

✅ 실행 결과 요약

1. 호스트 네트워크 설정

(⎈|HomeLab:N/A) root@k8s-ctr:~# cat /etc/hosts
127.0.0.1 localhost
...
127.0.2.1 k8s-ctr k8s-ctr
192.168.10.100 k8s-ctr
192.168.10.101 k8s-w1
192.168.10.102 k8s-w2

(⎈|HomeLab:N/A) root@k8s-ctr:~# sshpass -p 'vagrant' ssh -o StrictHostKeyChecking=no vagrant@k8s-w1 hostname
Warning: Permanently added 'k8s-w1' (ED25519) to the list of known hosts.
k8s-w1

(⎈|HomeLab:N/A) root@k8s-ctr:~# sshpass -p 'vagrant' ssh -o StrictHostKeyChecking=no vagrant@k8s-w2 hostname
Warning: Permanently added 'k8s-w2' (ED25519) to the list of known hosts.
k8s-w2

(⎈|HomeLab:N/A) root@k8s-ctr:~# ifconfig | grep -iEA1 'eth[0-9]:'
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.0.2.15  netmask 255.255.255.0  broadcast 10.0.2.255
--
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.10.100  netmask 255.255.255.0  broadcast 192.168.10.255

# /etc/hosts 확인 - 노드 간 DNS 해석 가능
192.168.10.100 k8s-ctr
192.168.10.101 k8s-w1  
192.168.10.102 k8s-w2

# 네트워크 인터페이스
eth0: 10.0.2.15      (NAT)
eth1: 192.168.10.100 (Private Network)

2. 클러스터 기본 정보

(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl cluster-info
Kubernetes control plane is running at https://192.168.10.100:6443
CoreDNS is running at https://192.168.10.100:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl cluster-info dump | grep -m 2 -E "cluster-cidr|service-cluster-ip-range"
                            "--service-cluster-ip-range=10.96.0.0/16",
                            "--cluster-cidr=10.244.0.0/16",

(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl describe cm -n kube-system kubeadm-config
Name:         kubeadm-config
Namespace:    kube-system
Labels:       <none>
Annotations:  <none>

Data
====
ClusterConfiguration:
----
apiServer: {}
apiVersion: kubeadm.k8s.io/v1beta4
caCertificateValidityPeriod: 87600h0m0s
certificateValidityPeriod: 8760h0m0s
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns: {}
encryptionAlgorithm: RSA-2048
etcd:
  local:
    dataDir: /var/lib/etcd
imageRepository: registry.k8s.io
kind: ClusterConfiguration
kubernetesVersion: v1.33.2
networking:
  dnsDomain: cluster.local
  podSubnet: 10.244.0.0/16
  serviceSubnet: 10.96.0.0/16
proxy:
  disabled: true
scheduler: {}

# API 서버 및 CoreDNS 정상 동작
Kubernetes control plane is running at https://192.168.10.100:6443
CoreDNS is running at https://192.168.10.100:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

# CIDR 설정 확인
--service-cluster-ip-range=10.96.0.0/16  # Service CIDR
--cluster-cidr=10.244.0.0/16             # Pod CIDR (kubeadm 기본값)

3. 노드 상태 확인

(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl get node -owide
NAME      STATUS   ROLES           AGE     VERSION   INTERNAL-IP      EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION     CONTAINER-RUNTIME
k8s-ctr   Ready    control-plane   6m48s   v1.33.2   192.168.10.100   <none>        Ubuntu 24.04.2 LTS   6.8.0-53-generic   containerd://1.7.27
k8s-w1    Ready    <none>          5m30s   v1.33.2   192.168.10.101   <none>        Ubuntu 24.04.2 LTS   6.8.0-53-generic   containerd://1.7.27
k8s-w2    Ready    <none>          4m8s    v1.33.2   192.168.10.102   <none>        Ubuntu 24.04.2 LTS   6.8.0-53-generic   containerd://1.7.27

# 각 노드의 kubelet 설정 - node-ip 올바르게 설정됨
k8s-ctr: --node-ip=192.168.10.100
k8s-w1:  --node-ip=192.168.10.101  
k8s-w2:  --node-ip=192.168.10.102

4. Pod CIDR 할당

(⎈|HomeLab:N/A) root@k8s-ctr:~# cat /var/lib/kubelet/kubeadm-flags.env
KUBELET_KUBEADM_ARGS="--container-runtime-endpoint=unix:///run/containerd/containerd.sock --node-ip=192.168.10.100 --pod-infra-container-image=registry.k8s.io/pause:3.10"

(⎈|HomeLab:N/A) root@k8s-ctr:~# for i in w1 w2 ; do echo ">> node : k8s-$i <<"; sshpass -p 'vagrant' ssh vagrant@k8s-$i cat /var/lib/kubelet/kubeadm-flags.env ; echo; done
>> node : k8s-w1 <<
KUBELET_KUBEADM_ARGS="--container-runtime-endpoint=unix:///run/containerd/containerd.sock --node-ip=192.168.10.101 --pod-infra-container-image=registry.k8s.io/pause:3.10"
>> node : k8s-w2 <<
KUBELET_KUBEADM_ARGS="--container-runtime-endpoint=unix:///run/containerd/containerd.sock --node-ip=192.168.10.102 --pod-infra-container-image=registry.k8s.io/pause:3.10"

# kubeadm 기본 Pod CIDR (사용되지 않음)
k8s-ctr: 10.244.0.0/24
k8s-w1:  10.244.1.0/24
k8s-w2:  10.244.2.0/24

# Cilium IPAM Pod CIDR (실제 사용)
k8s-ctr: 172.20.0.0/24
k8s-w1:  172.20.1.0/24  
k8s-w2:  172.20.2.0/24

5. 실행 중인 Pod 현황

(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl get pod -A -owide
NAMESPACE     NAME                               READY   STATUS    RESTARTS   AGE     IP               NODE      NOMINATED NODE   READINESS GATES
kube-system   cilium-envoy-m7njw                 1/1     Running   0          7m1s    192.168.10.100   k8s-ctr   <none>           <none>
kube-system   cilium-envoy-p42gk                 1/1     Running   0          4m27s   192.168.10.102   k8s-w2    <none>           <none>
kube-system   cilium-envoy-pxr2q                 1/1     Running   0          5m49s   192.168.10.101   k8s-w1    <none>           <none>
kube-system   cilium-kkt6t                       1/1     Running   0          4m27s   192.168.10.102   k8s-w2    <none>           <none>
kube-system   cilium-mm7xq                       1/1     Running   0          5m49s   192.168.10.101   k8s-w1    <none>           <none>
kube-system   cilium-operator-5bc66f5b9b-7v5fg   1/1     Running   0          7m      192.168.10.100   k8s-ctr   <none>           <none>
kube-system   cilium-tstkf                       1/1     Running   0          7m1s    192.168.10.100   k8s-ctr   <none>           <none>
kube-system   coredns-674b8bbfcf-2sbw2           1/1     Running   0          7m      172.20.0.51      k8s-ctr   <none>           <none>
kube-system   coredns-674b8bbfcf-p8kth           1/1     Running   0          7m      172.20.0.107     k8s-ctr   <none>           <none>
kube-system   etcd-k8s-ctr                       1/1     Running   0          7m7s    192.168.10.100   k8s-ctr   <none>           <none>
kube-system   kube-apiserver-k8s-ctr             1/1     Running   0          7m7s    192.168.10.100   k8s-ctr   <none>           <none>
kube-system   kube-controller-manager-k8s-ctr    1/1     Running   0          7m7s    192.168.10.100   k8s-ctr   <none>           <none>
kube-system   kube-scheduler-k8s-ctr             1/1     Running   0          7m7s    192.168.10.100   k8s-ctr   <none>           <none>

# Cilium 컴포넌트 (각 노드별 DaemonSet)
cilium-envoy-*    : 3개 (각 노드 1개씩)
cilium-*          : 3개 (각 노드 1개씩) 
cilium-operator   : 1개 (컨트롤 플레인)

# Kubernetes 시스템 Pod
coredns-*         : 2개 (IP: 172.20.0.51, 172.20.0.107)
etcd, api-server, controller-manager, scheduler: 각 1개

6. iptables 규칙

(⎈|HomeLab:N/A) root@k8s-ctr:~# iptables -t nat -S
...
-N CILIUM_OUTPUT_nat
-N CILIUM_POST_nat
-N CILIUM_PRE_nat
...
-A PREROUTING -m comment --comment "cilium-feeder: CILIUM_PRE_nat" -j CILIUM_PRE_nat
-A OUTPUT -m comment --comment "cilium-feeder: CILIUM_OUTPUT_nat" -j CILIUM_OUTPUT_nat
-A POSTROUTING -m comment --comment "cilium-feeder: CILIUM_POST_nat" -j CILIUM_POST_nat

(⎈|HomeLab:N/A) root@k8s-ctr:~# iptables -t filter -S
...
-N CILIUM_FORWARD
-N CILIUM_INPUT
-N CILIUM_OUTPUT
...
-A CILIUM_FORWARD -o cilium_host -m comment --comment "cilium: any->cluster on cilium_host forward accept" -j ACCEPT
-A CILIUM_FORWARD -i cilium_host -m comment --comment "cilium: cluster->any on cilium_host forward accept (nodeport)" -j ACCEPT
-A CILIUM_FORWARD -i lxc+ -m comment --comment "cilium: cluster->any on lxc+ forward accept" -j ACCEPT
-A CILIUM_FORWARD -i cilium_net -m comment --comment "cilium: cluster->any on cilium_net forward accept (nodeport)" -j ACCEPT
-A CILIUM_FORWARD -o lxc+ -m comment --comment "cilium: any->cluster on lxc+ forward accept" -j ACCEPT
-A CILIUM_FORWARD -i lxc+ -m comment --comment "cilium: cluster->any on lxc+ forward accept (nodeport)" -j ACCEPT
-A CILIUM_INPUT -m mark --mark 0x200/0xf00 -m comment --comment "cilium: ACCEPT for proxy traffic" -j ACCEPT
-A CILIUM_OUTPUT -m mark --mark 0xa00/0xe00 -m comment --comment "cilium: ACCEPT for proxy traffic" -j ACCEPT
-A CILIUM_OUTPUT -m mark --mark 0x800/0xe00 -m comment --comment "cilium: ACCEPT for l7 proxy upstream traffic" -j ACCEPT
-A CILIUM_OUTPUT -m mark ! --mark 0xe00/0xf00 -m mark ! --mark 0xd00/0xf00 -m mark ! --mark 0x400/0xf00 -m mark ! --mark 0xa00/0xe00 -m mark ! --mark 0x800/0xe00 -m mark ! --mark 0xf00/0xf00 -m comment --comment "cilium: host->any mark as from host" -j MARK --set-xmark 0xc00/0xf00
-A KUBE-FIREWALL ! -s 127.0.0.0/8 -d 127.0.0.0/8 -m comment --comment "block incoming localnet connections" -m conntrack ! --ctstate RELATED,ESTABLISHED,DNAT -j DROP

(⎈|HomeLab:N/A) root@k8s-ctr:~# iptables -t mangle -S
-N CILIUM_POST_mangle
-N CILIUM_PRE_mangle
...
-A PREROUTING -m comment --comment "cilium-feeder: CILIUM_PRE_mangle" -j CILIUM_PRE_mangle
-A POSTROUTING -m comment --comment "cilium-feeder: CILIUM_POST_mangle" -j CILIUM_POST_mangle
-A CILIUM_PRE_mangle ! -o lo -m socket --transparent -m mark ! --mark 0xe00/0xf00 -m mark ! --mark 0x800/0xf00 -m comment --comment "cilium: any->pod redirect proxied traffic to host proxy" -j MARK --set-xmark 0x200/0xffffffff
-A CILIUM_PRE_mangle -p tcp -m mark --mark 0x89a10200 -m comment --comment "cilium: TPROXY to host cilium-dns-egress proxy" -j TPROXY --on-port 41353 --on-ip 127.0.0.1 --tproxy-mark 0x200/0xffffffff
-A CILIUM_PRE_mangle -p udp -m mark --mark 0x89a10200 -m comment --comment "cilium: TPROXY to host cilium-dns-egress proxy" -j TPROXY --on-port 41353 --on-ip 127.0.0.1 --tproxy-mark 0x200/0xffffffff

# Cilium에 의해 생성된 iptables 체인들
CILIUM_FORWARD, CILIUM_INPUT, CILIUM_OUTPUT    (filter 테이블)
CILIUM_PRE_nat, CILIUM_POST_nat               (nat 테이블)  
CILIUM_PRE_mangle, CILIUM_POST_mangle         (mangle 테이블)

# 특징: kube-proxy 관련 규칙 없음 (Cilium이 완전 대체)

[k8s-ctr] cilium 설치 정보 확인

# cilium CLI 및 기본 상태 확인
which cilium                                    # cilium CLI 설치 경로 확인
cilium status                                   # Cilium 전체 상태 요약 (데몬셋, 배포, 컨테이너 상태)
cilium config view                              # Cilium 설정 옵션 확인 (IPAM, 라우팅 모드 등)
kubectl get cm -n kube-system cilium-config -o json | jq  # Cilium ConfigMap 상세 설정 JSON 형태로 출력

# Cilium 에이전트 내부 정보 확인
kubectl exec -n kube-system -c cilium-agent -it ds/cilium -- cilium-dbg config      # 실행 중인 Cilium 에이전트 설정 확인
kubectl exec -n kube-system -c cilium-agent -it ds/cilium -- cilium-dbg status --verbose  # 에이전트 상태 상세 정보 (BPF 맵, 정책 등)
kubectl exec -n kube-system -c cilium-agent -it ds/cilium -- cilium-dbg metrics list     # 사용 가능한 메트릭 목록 확인

# Cilium 엔드포인트 확인
kubectl get ciliumendpoints -A                 # 모든 네임스페이스의 Cilium 엔드포인트 목록 (Pod IP, ID 등)

# 실시간 네트워크 모니터링
kubectl exec -n kube-system -c cilium-agent -it ds/cilium -- cilium-dbg monitor      # 기본 네트워크 이벤트 모니터링
kubectl exec -n kube-system -c cilium-agent -it ds/cilium -- cilium-dbg monitor -v   # 상세 모니터링 (패킷 헤더 정보 포함)
kubectl exec -n kube-system -c cilium-agent -it ds/cilium -- cilium-dbg monitor -v -v # 매우 상세한 모니터링 (패킷 페이로드까지)

# 특정 조건 필터링 모니터링
kubectl exec -n kube-system -c cilium-agent -it ds/cilium -- cilium-dbg monitor --related-to=<id>  # 특정 엔드포인트 ID 관련 이벤트만 필터링
kubectl exec -n kube-system -c cilium-agent -it ds/cilium -- cilium-dbg monitor --type drop       # 드롭된 패킷 이벤트만 표시 (보안 정책 위반 등)
kubectl exec -n kube-system -c cilium-agent -it ds/cilium -- cilium-dbg monitor -v -v --hex       # 패킷 페이로드를 16진수로 표시 (패킷 분석용)

# Layer 7 프록시 모니터링
kubectl exec -n kube-system -c cilium-agent -it ds/cilium -- cilium-dbg monitor -v --type l7      # HTTP/gRPC 등 L7 프로토콜 이벤트 모니터링

✅ 실행 결과 요약

1. Cilium CLI 및 기본 상태

(⎈|HomeLab:N/A) root@k8s-ctr:~# which cilium
/usr/local/bin/cilium

(⎈|HomeLab:N/A) root@k8s-ctr:~# cilium status
    /¯¯\
 /¯¯\__/¯¯\    Cilium:             OK
 \__/¯¯\__/    Operator:           OK  
 /¯¯\__/¯¯\    Envoy DaemonSet:    OK        # Envoy 프록시 정상 동작
 \__/¯¯\__/    Hubble Relay:       disabled  # Hubble 비활성화 상태
    \__/       ClusterMesh:        disabled

DaemonSet              cilium                   Desired: 3, Ready: 3/3, Available: 3/3
DaemonSet              cilium-envoy             Desired: 3, Ready: 3/3, Available: 3/3
Deployment             cilium-operator          Desired: 1, Ready: 1/1, Available: 1/1
Containers:            cilium                   Running: 3
                       cilium-envoy             Running: 3
                       cilium-operator          Running: 1
Cluster Pods:          2/2 managed by Cilium    # CoreDNS 2개 Pod만 관리됨
Helm chart version:    1.17.6

2. Cilium 설정 확인 (주요 옵션)

(⎈|HomeLab:N/A) root@k8s-ctr:~# cilium config view
agent-not-ready-taint-key                         node.cilium.io/agent-not-ready
...

# 핵심 설정값들
cluster-pool-ipv4-cidr                         172.20.0.0/16    # Pod CIDR 범위
ipv4-native-routing-cidr                       172.20.0.0/16    # 네이티브 라우팅 범위
routing-mode                                   native           # 네이티브 라우팅 모드
kube-proxy-replacement                         true             # kube-proxy 완전 대체
enable-bpf-masquerade                          true             # eBPF 마스커레이딩
enable-hubble                                  false            # Hubble 비활성화
enable-endpoint-health-checking                false            # 엔드포인트 헬스체크 비활성화
enable-l7-proxy                                true             # L7 프록시 활성화
external-envoy-proxy                           true             # 외부 Envoy 프록시 사용

3. Cilium 에이전트 상세 상태

kubectl exec -n kube-system -c cilium-agent -it ds/cilium -- cilium-dbg config
##### Read-write configurations #####
ConntrackAccounting               : Disabled
ConntrackLocal                    : Disabled
...

# 네트워크 및 IPAM 정보
KubeProxyReplacement:   True   [eth0 10.0.2.15, eth1 192.168.10.100 (Direct Routing)]
IPAM:                   IPv4: 3/254 allocated from 172.20.0.0/24
Allocated addresses:
  172.20.0.106 (router)           # Cilium 라우터 IP
  172.20.0.107 (coredns Pod)      
  172.20.0.51  (coredns Pod)

# BPF 맵 상태 (주요 항목들)
Auth                          524288     # 인증 관련
TCP connection tracking       131072     # TCP 연결 추적  
IP cache                      512000     # IP 캐시
IPv4 service                  65536      # 서비스 정보
NAT                          131072     # NAT 정보

4. Cilium 엔드포인트

(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl get ciliumendpoints -A
NAMESPACE     NAME                       SECURITY IDENTITY   ENDPOINT STATE   IPV4         
kube-system   coredns-674b8bbfcf-2sbw2   5694                ready            172.20.0.51    
kube-system   coredns-674b8bbfcf-p8kth   5694                ready            172.20.0.107   

# 두 개의 CoreDNS Pod만 Cilium 엔드포인트로 관리됨
# Security Identity 5694: CoreDNS 공통 보안 ID

5. 실시간 네트워크 모니터링

(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl exec -n kube-system -c cilium-agent -it ds/cilium -- cilium-dbg monitor
Press Ctrl-C to quit
time="2025-07-25T15:46:00.5993656Z" level=info msg="Initializing dissection cache..." subsys=monitor
-> endpoint 1174 flow 0xfee0e3b8 , identity host->5694 state new ifindex lxcea4f8900288d orig-ip 10.0.2.15: 10.0.2.15:58808 -> 172.20.0.107:8181 tcp SYN
...

# 기본 모니터링 - TCP 연결 흐름 확인
-> endpoint 1174 flow 0xfee0e3b8 , identity host->5694 state new ifindex lxcea4f8900288d orig-ip 10.0.2.15: 10.0.2.15:58808 -> 172.20.0.107:8181 tcp SYN
-> stack flow 0xc6d97fd2 , identity 5694->host state reply ifindex 0 orig-ip 0.0.0.0: 172.20.0.107:8181 -> 10.0.2.15:58808 tcp SYN, ACK

(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl exec -n kube-system -c cilium-agent -it ds/cilium -- cilium-dbg monitor --related-to=1174
Press Ctrl-C to quit
time="2025-07-25T15:46:37.649017061Z" level=info msg="Initializing dissection cache..." subsys=monitor
...

# 특정 엔드포인트(1174) 필터링
-> endpoint 1174 flow 0x689edad4 , identity host->5694 state new ifindex lxcea4f8900288d orig-ip 10.0.2.15: 10.0.2.15:53166 -> 172.20.0.107:8080 tcp SYN

# 패킷 드롭 모니터링 - 현재 드롭 이벤트 없음 (정상)

(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl exec -n kube-system -c cilium-agent -it ds/cilium -- cilium-dbg monitor -v -v --hex
Listening for events on 2 CPUs with 64x4096 of shared memory
Press Ctrl-C to quit
------------------------------------------------------------------------------
00000000  26 70 69 2b 3c 45 b6 16  31 6c 65 97 08 00 45 00  |&pi+<E..1le...E.|
00000010  00 3c 6e dc 40 00 40 06  13 8a 0a 00 02 0f ac 14  |.<n.@.@.........|
00000020  00 33 89 1e 1f 90 07 d8  06 f1 00 00 00 00 a0 02  |.3..............|
00000030  fa f0 b8 84 00 00 02 04  05 b4 04 02 08 0a c6 e7  |................|
00000040  be d7 00 00 00 00 01 03  03 07 00 00              |............|
CPU 01: MARK 0xc7086d59 FROM 2609 to-endpoint: 74 bytes (74 captured), state new, interface lxc903c835e21af, , identity host->5694, orig-ip 10.0.2.15, to endpoint 2609
...

# 16진수 패킷 분석 - HTTP 트래픽 확인
47 45 54 20 2f 68 65 61 6c 74 68 20 48 54 54 50    # "GET /health HTTP"
48 54 54 50 2f 31 2e 31 20 32 30 30 20 4f 4b       # "HTTP/1.1 200 OK"

6. Layer 7 프록시 모니터링

(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl exec -n kube-system -c cilium-agent -it ds/cilium -- cilium-dbg monitor -v --type l7
Press Ctrl-C to quit
CPU 00: [pre-xlate-rev] cgroup_id: 7184 sock_cookie: 16174, dst [127.0.0.1]:34040 tcp 
CPU 00: [pre-xlate-rev] cgroup_id: 7184 sock_cookie: 16174, dst [127.0.0.1]:34040 tcp 
..

# Socket-level 연결 추적 정보
CPU 01: [pre-xlate-rev] cgroup_id: 9357 sock_cookie: 12137, dst [127.0.0.1]:8080 tcp    # CoreDNS 헬스체크
CPU 01: [pre-xlate-rev] cgroup_id: 7463 sock_cookie: 12135, dst [192.168.10.100]:6443 tcp  # API 서버 통신

# cgroup_id로 각 컨테이너별 네트워크 활동 추적 가능
# sock_cookie로 개별 소켓 연결 식별

주요 확인 포인트는 다음과 같습니다.

  • Cilium 상태: 모든 컴포넌트 정상 동작 (OK 상태)
  • 네트워킹: 네이티브 라우팅 + eBPF 마스커레이딩으로 최적화
  • kube-proxy 대체: 완전히 대체되어 iptables 규칙 최소화
  • 엔드포인트 관리: CoreDNS Pod들이 Cilium으로 관리됨
  • 모니터링: 실시간 패킷 흐름, TCP 상태, HTTP 트래픽 모두 추적 가능
  • L7 프록시: Envoy를 통한 Layer 7 트래픽 처리 활성화

Hubble을 이용한 네트워크 가시성 확보

Hubble이란?

Hubble은 Cilium과 eBPF를 기반으로 구축된 완전히 분산된 네트워킹 및 보안 관측 플랫폼입니다. 서비스 간 통신과 네트워킹 인프라에 대한 깊은 가시성을 완전히 투명하게 제공합니다.
출처 - https://docs.cilium.io/en/stable/observability/hubble/

핵심 특징:

  • eBPF 기반: 프로그래밍 가능한 가시성으로 오버헤드 최소화
  • 동적 접근: 필요한 깊이의 세밀한 가시성 제공
  • 다중 클러스터 지원: 노드/클러스터/클러스터 간 가시성

Hubble 아키텍처

1. 기본 모드 (로컬 노드 범위)

# 개별 노드의 Cilium 에이전트 범위 내에서 동작
# 로컬 유닉스 도메인 소켓을 통한 Hubble API 접근
kubectl exec -n kube-system -c cilium-agent -it ds/cilium -- hubble observe

2. 클러스터 모드 (Hubble Relay)

# 전체 클러스터 또는 여러 클러스터에 대한 네트워크 가시성
# Hubble Relay 서비스를 통한 중앙집중식 접근
# Hubble UI를 통한 웹 인터페이스 제공

주요 관측 기능

🔗 서비스 종속성 & 통신 맵

  • 서비스 간 통신 빈도 및 패턴 분석
  • 서비스 종속성 그래프 자동 생성
  • HTTP 호출, Kafka 토픽 소비/생산 추적
  • L3/L4/L7 레벨 서비스 맵 시각화

📊 네트워크 모니터링 & 알람

  • 네트워크 통신 실패 원인 분석 (DNS/애플리케이션/네트워크)
  • TCP/HTTP 레벨 문제 진단
  • DNS 해석 문제, TCP 연결 중단, 연결 타임아웃 추적
  • 응답하지 않는 TCP SYN 요청 비율 모니터링

📈 애플리케이션 모니터링

  • HTTP 4xx/5xx 응답 코드 비율 분석
  • 95th/99th 백분위수 레이턴시 측정
  • 서비스 간 응답 시간 분석
  • 성능 저하 서비스 식별

🔒 보안 관측성

  • 네트워크 정책에 의해 차단된 연결 추적
  • 클러스터 외부 접근 서비스 모니터링
  • 특정 DNS 이름 해석 서비스 추적
  • 보안 정책 위반 및 위협 탐지

즉 Hubble을 통해 마이크로서비스 환경에서의 네트워크 가시성, 보안 모니터링, 성능 분석을 한 번에 해결할 수 있습니다.

Hubble 실습

설치 전 확인

# Cilium 전체 상태 확인 (Hubble 관련 컴포넌트 상태 포함)
cilium status

# Cilium 설정에서 Hubble 관련 옵션 확인 (현재 비활성화 상태 확인)
cilium config view | grep -i hubble

# Cilium ConfigMap에서 Hubble 설정 상세 확인 (JSON 형태로 모든 설정 출력)
kubectl get cm -n kube-system cilium-config -o json | jq

# Hubble 관련 시크릿 존재 여부 확인 (CA 인증서, TLS 인증서 등)
kubectl get secret -n kube-system | grep -iE 'cilium-ca|hubble'

# 현재 수신 대기 중인 포트 확인 (Hubble 활성화 전 상태 저장)
# Cilium/Hubble 관련 포트를 필터링하여 before.txt 파일에 저장
ss -tnlp | grep -iE 'cilium|hubble' | tee before.txt

설치 전 확인 결과 요약

1. Cilium 상태 확인

(⎈|HomeLab:N/A) root@k8s-ctr:~# cilium status
    /¯¯\
 /¯¯\__/¯¯\    Cilium:             OK
 \__/¯¯\__/    Operator:           OK
 /¯¯\__/¯¯\    Envoy DaemonSet:    OK
 \__/¯¯\__/    Hubble Relay:       disabled  # Hubble Relay 비활성화 상태
    \__/       ClusterMesh:        disabled

# Hubble 관련 컨테이너가 없음 (현재 비활성화)
clustermesh-apiserver    
hubble-relay             # 공백 - 실행 중이지 않음

2. Hubble 설정 확인

# Cilium 설정에서 Hubble 비활성화 확인
(⎈|HomeLab:N/A) root@k8s-ctr:~# cilium config view | grep -i hubble
enable-hubble                                     false

(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl get cm -n kube-system cilium-config -o json | jq
{
  "apiVersion": "v1",
  "data": {
...
# ConfigMap에서도 동일하게 비활성화 상태
  "enable-hubble": "false"

3. Hubble 관련 시크릿

# Hubble/CA 관련 시크릿이 존재하지 않음 (정상 - 아직 설치 전)
(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl get secret -n kube-system | grep -iE 'cilium-ca|hubble'
# 출력 없음 - Hubble 인증서 미생성 상태

4. 현재 Cilium 관련 수신 포트

# Hubble 관련 포트는 없고, 기본 Cilium 포트만 활성화
127.0.0.1:9891  # cilium-operator (메트릭)
127.0.0.1:9890  # cilium-agent (API)
127.0.0.1:9879  # cilium-agent (내부 통신)
127.0.0.1:9878  # cilium-envoy (프록시)
0.0.0.0:9964    # cilium-envoy (외부 메트릭)
127.0.0.1:41353 # cilium-agent (DNS 프록시)
127.0.0.1:9234  # cilium-operator (API)
*:9963          # cilium-operator (Prometheus 메트릭)

# 주목: Hubble 기본 포트(4244, 4245) 없음

현재 상태 요약:

  • ✅ Cilium 정상 동작: 모든 핵심 컴포넌트 OK 상태
  • ❌ Hubble 비활성화: enable-hubble: false 설정
  • ❌ Hubble Relay 없음: 클러스터 전체 관측 불가
  • ❌ Hubble 인증서 없음: 보안 설정 미완료
  • ❌ Hubble 포트 없음: 4244(gRPC), 4245(HTTP) 포트 비활성화

다음 단계에서 Hubble을 활성화하여 네트워크 관측성을 확보해보겠습니다.

Hubble 설치 및 변화 확인

# 설치방안 1 : Helm을 이용한 상세 설정으로 Hubble 활성화
# 기본적으로 enabled, relay.enabled, ui.enabled 만 해도 설정 가능
helm upgrade cilium cilium/cilium --namespace kube-system --reuse-values \
**--set hubble.enabled=true \                    # Hubble 기본 기능 활성화
--set hubble.relay.enabled=true \               # Hubble Relay 활성화 (클러스터 전체 관측)
--set hubble.ui.enabled=true \**                # Hubble UI 웹 인터페이스 활성화
--set hubble.ui.service.type=NodePort \         # UI 서비스를 NodePort로 외부 노출(편의성)
--set hubble.ui.service.nodePort=31234 \        # NodePort 번호 31234로 고정(편의성)
--set hubble.export.static.enabled=true \       # 정적 로그 내보내기 활성화
--set hubble.export.static.filePath=/var/run/cilium/hubble/events.log \  # 로그 파일 경로 지정
--set prometheus.enabled=true \                 # Prometheus 메트릭 활성화
--set operator.prometheus.enabled=true \        # Cilium Operator 메트릭 활성화
--set hubble.metrics.enableOpenMetrics=true \   # OpenMetrics 형식 메트릭 활성화
--set hubble.metrics.enabled="{dns,drop,tcp,flow,port-distribution,icmp,httpV2:exemplars=true;labelsContext=source_ip\,source_namespace\,source_workload\,destination_ip\,destination_namespace\,destination_workload\,traffic_direction}"  # 상세 메트릭 수집 설정

# 설치방안 2 : Cilium CLI를 이용한 간단 설정
cilium hubble enable                            # Hubble 기본 활성화
cilium hubble enable --ui                       # Hubble UI까지 포함하여 활성화

# Hubble Relay 정상 동작 확인 (중요: Relay가 OK 상태여야 클러스터 전체 관측 가능)
cilium status

# Hubble 관련 설정 변경 확인
cilium config view | grep -i hubble             # CLI에서 Hubble 설정 확인 (enable-hubble: true로 변경됨)
kubectl get cm -n kube-system cilium-config -o json | grep -i hubble  # ConfigMap에서 Hubble 설정 확인

# Hubble 관련 인증서 및 시크릿 생성 확인
kubectl get secret -n kube-system | grep -iE 'cilium-ca|hubble'  # CA 인증서, Hubble TLS 인증서 생성 확인

# 네트워크 포트 변화 확인 (Hubble 활성화 전후 비교)
# Hubble 활성화 후 TCP 포트 4244가 모든 노드에서 열려야 함
ss -tnlp | grep -iE 'cilium|hubble' | tee after.txt  # 활성화 후 포트 상태를 after.txt에 저장
vi -d before.txt after.txt                  # diff 뷰어로 설치 전후 포트 변화 비교
for i in w1 w2 ; do echo ">> node : k8s-$i <<"; sshpass -p 'vagrant' ssh vagrant@k8s-$i **sudo ss -tnlp |grep 4244** ; echo; done  # 모든 워커 노드에서 4244 포트 개방 확인

# Hubble Relay Pod 상태 확인
kubectl get pod -n kube-system -l k8s-app=hubble-relay  # Hubble Relay Pod 목록 조회
kc describe pod -n kube-system -l k8s-app=hubble-relay  # Relay Pod 상세 정보 (컨테이너 상태, 이벤트 등)

# Hubble Relay 서비스 및 엔드포인트 확인
kc get svc,ep -n kube-system hubble-relay    # Relay 서비스 및 엔드포인트 정보

# Hubble Relay 설정 정보 확인 (어떻게 각 노드의 Hubble과 통신하는지)
# hubble-relay 는 hubble-peer 의 서비스(ClusterIP :443)을 통해 모든 노드의 :4244에 요청 가져올 수 있음**
kubectl get cm -n kube-system                   # 전체 ConfigMap 목록 확인
kubectl describe cm -n kube-system hubble-relay-config  # Relay 설정 상세 정보

# Hubble Peer 서비스 확인 (각 노드의 Hubble Agent 집계 서비스)
# (실리움 파드 안에 허블 프로세스가 띄워짐. 각노드의 hubble API 접근 포트: 4244 포트 사용)
kubectl get svc,ep -n kube-system hubble-peer  # Peer 서비스 및 모든 노드 엔드포인트 확인 

# Hubble UI Pod 상태 확인
kc describe pod -n kube-system -l k8s-app=hubble-ui**  # UI Pod 상세 정보 (frontend, backend 컨테이너)

# Hubble UI Nginx 설정 확인
kc describe cm -n kube-system hubble-ui-nginx**  # UI 웹서버 설정 정보
...

# Hubble UI 서비스 접속 정보 확인
kubectl get svc,ep -n kube-system hubble-ui  # UI 서비스 NodePort 및 엔드포인트 확인

# Hubble UI 웹 접속 주소 자동 생성 및 출력
NODEIP=$(ip -4 addr show eth1 | grep -oP '(?<=inet\s)\d+(\.\d+){3}')  # 현재 노드의 Private IP 추출
echo -e "http://$NODEIP:31234"                  # 웹 브라우저 접속 URL 출력 (예: http://192.168.10.100:31234)

✅ 실행 결과 요약

1. Helm 업그레이드 성공

(⎈|HomeLab:N/A) root@k8s-ctr:~# helm upgrade cilium cilium/cilium --namespace kube-system --reuse-values \
--set hubble.enabled=true \
--set hubble.relay.enabled=true \
--set hubble.ui.enabled=true \
...
Release "cilium" has been upgraded. Happy Helming!
NAME: cilium
LAST DEPLOYED: Sat Jul 26 01:59:21 2025
NAMESPACE: kube-system
STATUS: deployed
REVISION: 2  # 첫 설치에서 2번째 리비전으로 업그레이드됨

2. Cilium 상태 변화 (일시적 오류 후 정상화)

(⎈|HomeLab:N/A) root@k8s-ctr:~# cilium status
    /¯¯\
 /¯¯\__/¯¯\    Cilium:             OK
 \__/¯¯\__/    Operator:           OK
 /¯¯\__/¯¯\    Envoy DaemonSet:    OK
 \__/¯¯\__/    Hubble Relay:       OK
    \__/       ClusterMesh:        disabled

DaemonSet              cilium                   Desired: 3, Ready: 3/3, Available: 3/3
DaemonSet              cilium-envoy             Desired: 3, Ready: 3/3, Available: 3/3
Deployment             cilium-operator          Desired: 1, Ready: 1/1, Available: 1/1
Deployment             hubble-relay             Desired: 1, Ready: 1/1, Available: 1/1
Deployment             hubble-ui                Desired: 1, Ready: 1/1, Available: 1/1
Containers:            cilium                   Running: 3
                       cilium-envoy             Running: 3
                       cilium-operator          Running: 1
                       clustermesh-apiserver    
                       hubble-relay             Running: 1
                       hubble-ui                Running: 1
Cluster Pods:          4/4 managed by Cilium
Helm chart version:    1.17.6
Image versions         cilium             quay.io/cilium/cilium:v1.17.6@sha256:544de3d4fed7acba72758413812780a4972d47c39035f2a06d6145d8644a3353: 3
                       cilium-envoy       quay.io/cilium/cilium-envoy:v1.33.4-1752151664-7c2edb0b44cf95f326d628b837fcdd845102ba68@sha256:318eff387835ca2717baab42a84f35a83a5f9e7d519253df87269f80b9ff0171: 3
                       cilium-operator    quay.io/cilium/operator-generic:v1.17.6@sha256:91ac3bf7be7bed30e90218f219d4f3062a63377689ee7246062fa0cc3839d096: 1
                       hubble-relay       quay.io/cilium/hubble-relay:v1.17.6@sha256:7d17ec10b3d37341c18ca56165b2f29a715cb8ee81311fd07088d8bf68c01e60: 1
                       hubble-ui          quay.io/cilium/hubble-ui-backend:v0.13.2@sha256:a034b7e98e6ea796ed26df8f4e71f83fc16465a19d166eff67a03b822c0bfa15: 1
                       hubble-ui          quay.io/cilium/hubble-ui:v0.13.2@sha256:9e37c1296b802830834cc87342a9182ccbb71ffebb711971e849221bd9d59392: 1

3. Hubble 설정 활성화 확인

# 설정 변경 완료 (false → true)
(⎈|HomeLab:N/A) root@k8s-ctr:~# cilium config view | grep -i hubble
enable-hubble                                     true  ✅
enable-hubble-open-metrics                        true  # 메트릭 활성화
hubble-listen-address                             :4244 # 각 노드에서 수신 대기
hubble-metrics-server                             :9965 # 메트릭 서버 포트
hubble-export-file-path                           /var/run/cilium/hubble/events.log  # 로그 파일

# ConfigMap에서도 동일하게 활성화 확인
"enable-hubble": "true"

4. 보안 인증서 자동 생성

# Hubble 관련 시크릿 3개 생성됨
(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl get secret -n kube-system | grep -iE 'cilium-ca|hubble'
cilium-ca                      Opaque                          2      27s  # CA 루트 인증서
hubble-relay-client-certs      kubernetes.io/tls               3      27s  # Relay 클라이언트 인증서
hubble-server-certs            kubernetes.io/tls               3      27s  # Hubble 서버 인증서

5. 네트워크 포트 변화

# 새로 추가된 포트들
*:4244             *:*    users:(("cilium-agent",pid=9298,fd=50))  # Hubble API 서버 (모든 노드)
*:9962             *:*    users:(("cilium-agent",pid=9298,fd=7))   # Cilium 메트릭
*:9965             *:*    users:(("cilium-agent",pid=9298,fd=42))  # Hubble 메트릭 서버

# 모든 워커 노드에서도 4244 포트 개방 확인
>> node : k8s-w1 <<
LISTEN 0      4096               *:4244             *:*    users:(("cilium-agent",pid=7154,fd=55))
>> node : k8s-w2 <<
LISTEN 0      4096               *:4244             *:*    users:(("cilium-agent",pid=6930,fd=42))

6. Hubble Relay 정상 동작

# Relay Pod 상태
(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl get pod -n kube-system -l k8s-app=hubble-relay
NAME                           READY   STATUS    RESTARTS   AGE
hubble-relay-5dcd46f5c-tln2s   1/1     Running   0          2m14s

# Relay 서비스 및 엔드포인트
service/hubble-relay   ClusterIP   10.96.174.49   <none>        80/TCP    2m22s
endpoints/hubble-relay   172.20.2.176:4245   2m22s  # k8s-w2 노드에 배포됨

7. Hubble Peer 서비스 (클러스터 전체 집계)

# 모든 노드의 Hubble Agent를 집계하는 서비스
service/hubble-peer   ClusterIP   10.96.68.0   <none>        443/TCP   2m35s
endpoints/hubble-peer   192.168.10.100:4244,192.168.10.101:4244,192.168.10.102:4244

# Relay 설정: hubble-peer 서비스를 통해 모든 노드에 접근
peer-service: "hubble-peer.kube-system.svc.cluster.local.:443"
listen-address: :4245  # Relay가 4245 포트로 서비스 제공

8. Hubble UI 웹 인터페이스

# UI Pod 구성 (frontend + backend)
Containers:
  frontend:  # Nginx 기반 (포트 8081)
    Image: quay.io/cilium/hubble-ui:v0.13.2
    Port:  8081/TCP
  backend:   # Go 기반 API (포트 8090)
    Image: quay.io/cilium/hubble-ui-backend:v0.13.2
    Port:  8090/TCP
    Environment:
      FLOWS_API_ADDR: hubble-relay:80  # Relay를 통해 데이터 수집

# NodePort 서비스로 외부 접속 가능
service/hubble-ui   NodePort   10.96.201.178   <none>        80:31234/TCP   2m48s
endpoints/hubble-ui   172.20.1.129:8081   2m48s  # k8s-w1 노드에 배포됨

9. 웹 접속 정보

# 자동 생성된 접속 URL
(⎈|HomeLab:N/A) root@k8s-ctr:~# echo -e "http://$NODEIP:31234"
http://192.168.10.100:31234  # 브라우저에서 접속 가능한 주소

허블에 접속하면, 트래픽이 발생하기때문에 kube-system 네임스페이스에서 트래픽을 확인할 수 있습니다.

 

현재 Hubble 상태 요약:

  • ✅ Hubble 활성화: 모든 노드에서 4244 포트로 동작
  • ✅ Hubble Relay: 클러스터 전체 관측을 위한 중계 서비스 동작
  • ✅ Hubble UI: 웹 인터페이스 정상 동작 (NodePort 31234)
  • ✅ 보안 설정: TLS 인증서 자동 생성 및 적용
  • ✅ 메트릭 수집: Prometheus 호환 메트릭 활성화
  • ✅ 로그 내보내기: 정적 파일로 이벤트 로그 저장

아키텍처 흐름:

브라우저 (:31234) → Hubble UI (frontend:8081 + backend:8090) 
                 ↓
        Hubble Relay (:4245)
                 ↓
       hubble-peer 서비스 (:443)
                 ↓
   모든 노드의 Cilium Agent (Hubble :4244)

Hubble Client 설치

# Linux 실습 환경에 설치 시
HUBBLE_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/hubble/master/stable.txt)
HUBBLE_ARCH=amd64
if [ "$(uname -m)" = "aarch64" ]; then HUBBLE_ARCH=arm64; fi
curl -L --fail --remote-name-all https://github.com/cilium/hubble/releases/download/$HUBBLE_VERSION/hubble-linux-${HUBBLE_ARCH}.tar.gz{,.sha256sum}
sudo tar xzvfC hubble-linux-${HUBBLE_ARCH}.tar.gz /usr/local/bin
which hubble

# Hubble API Access를 설정해야 접근가능!
cilium hubble port-forward& 

cilium hubble port-forward&
Hubble Relay is available at 127.0.0.1:4245

ss -tnlp | grep 4245

# Now you can validate that you can access the Hubble API via the installed CLI
hubble status
Healthcheck (via localhost:4245): Ok
Current/Max Flows: 12,285/12,285 (100.00%)
Flows/s: 41.20

# hubble (api) server 기본 접속 주소 확인
hubble config view 
...
port-forward-port: "4245"
server: localhost:4245
...

# (옵션) 현재 k8s-ctr 가상머신이 아닌, 자신의 PC에 kubeconfig 설정 후 아래 --server 옵션을 통해 hubble api server 사용해보자!
hubble help status | grep 'server string'
      --server string                 Address of a Hubble server. Ignored when --input-file or --port-forward is provided. (default "localhost:4245")

# You can also query the flow API and look for flows
kubectl get ciliumendpoints.cilium.io -n kube-system # SECURITY IDENTITY
hubble observe
hubble observe -h
hubble observe -f

✅ 실행 결과 요약

1. Hubble Client 설치 성공

# 최신 버전 자동 다운로드 및 설치
(⎈|HomeLab:N/A) root@k8s-ctr:~# HUBBLE_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/hubble/master/stable.txt)
(⎈|HomeLab:N/A) root@k8s-ctr:~# curl -L --fail --remote-name-all https://github.com/cilium/hubble/releases/download/$HUBBLE_VERSION/hubble-linux-${HUBBLE_ARCH}.tar.gz
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
100 22.3M  100 22.3M    0     0  13.9M      0  0:00:01  0:00:01 --:--:-- 33.0M

(⎈|HomeLab:N/A) root@k8s-ctr:~# which hubble
/usr/local/bin/hubble  # 설치 완료 확인

2. 초기 연결 실패 → Port-Forward 설정

# 초기 상태: Hubble API 접근 불가
(⎈|HomeLab:N/A) root@k8s-ctr:~# hubble status
failed getting status: rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing: dial tcp 127.0.0.1:4245: connect: connection refused"

# Port-Forward 활성화
(⎈|HomeLab:N/A) root@k8s-ctr:~# cilium hubble port-forward&
[1] 10570
ℹ️  Hubble Relay is available at 127.0.0.1:4245  # 성공 메시지

# 로컬 포트 4245 개방 확인
(⎈|HomeLab:N/A) root@k8s-ctr:~# ss -tnlp | grep 4245
LISTEN 0      4096        127.0.0.1:4245       0.0.0.0:*    users:(("cilium",pid=10570,fd=7))
LISTEN 0      4096            [::1]:4245          [::]:*    users:(("cilium",pid=10570,fd=8))

3. Hubble API 정상 연결 확인

# 연결 성공 후 상태 확인
(⎈|HomeLab:N/A) root@k8s-ctr:~# hubble status
Healthcheck (via localhost:4245): Ok  ✅
Current/Max Flows: 11,282/12,285 (91.84%)  # 플로우 버퍼 91% 사용 중
Flows/s: 35.22                              # 초당 35개 플로우 처리
Connected Nodes: 3/3                        # 모든 노드(3개) 연결됨

# Hubble 클라이언트 설정 확인
(⎈|HomeLab:N/A) root@k8s-ctr:~# hubble config view
server: localhost:4245          # 기본 서버 주소
port-forward-port: "4245"       # Port-Forward 포트
timeout: 5s                     # 요청 타임아웃
tls: false                      # TLS 비활성화 (내부 통신)

4. 실시간 네트워크 플로우 관측

# 실시간 트래픽 모니터링 시작
(⎈|HomeLab:N/A) root@k8s-ctr:~# hubble observe

# 주요 관측된 트래픽 패턴들:

# 1) Hubble UI → Relay 통신
Jul 25 17:13:13.125: kube-system/hubble-ui-76d4965bb6-hcgj6:55468 (ID:7661) 
                   → kube-system/hubble-relay-5dcd46f5c-tln2s:4245 (ID:11581) 
                   to-endpoint FORWARDED (TCP Flags: ACK, PSH)

# 2) Hubble Relay → 각 노드 Agent 통신
Jul 25 17:13:13.125: kube-system/hubble-relay-5dcd46f5c-tln2s:42624 (ID:11581) 
                   ← 192.168.10.101:4244 (remote-node) to-endpoint FORWARDED
Jul 25 17:13:13.125: kube-system/hubble-relay-5dcd46f5c-tln2s:37400 (ID:11581) 
                   ← 192.168.10.102:4244 (host) to-endpoint FORWARDED

# 3) API Server 통신
Jul 25 17:13:17.280: kube-system/hubble-ui-76d4965bb6-hcgj6:47432 (ID:7661) 
                   → 192.168.10.100:6443 (kube-apiserver) to-network FORWARDED

# 4) CoreDNS 헬스체크
Jul 25 17:13:17.649: 10.0.2.15:55892 (host) 
                   → kube-system/coredns-674b8bbfcf-p8kth:8080 (ID:5694) 
                   to-endpoint FORWARDED

# 5) 로컬 통신 (Pod 내부)
Jul 25 17:13:16.197: 127.0.0.1:8090 (world) 
                   <> kube-system/hubble-ui-76d4965bb6-hcgj6 (ID:7661) 
                   pre-xlate-rev TRACED

5. 관측된 네트워크 아키텍처

컴포넌트 IP/Port Security Identity 역할
hubble-ui 172.20.1.129:8081 ID:7661 웹 인터페이스
hubble-relay 172.20.2.176:4245 ID:11581 클러스터 중계
coredns 172.20.0.51/107:8080 ID:5694 DNS 서비스
k8s-ctr (192.168.10.100) :4244 kube-apiserver 컨트롤 플레인
k8s-w1 (192.168.10.101) :4244 remote-node 워커 노드 1
k8s-w2 (192.168.10.102) :4244 host 워커 노드 2

현재 Hubble 관측 상태:

  • ✅ CLI 접근: localhost:4245를 통한 API 접근 가능
  • ✅ 실시간 모니터링: 초당 35개 플로우 처리 중
  • ✅ 클러스터 커버리지: 3개 노드 모두 연결됨
  • ✅ 플로우 버퍼: 12,285개 중 11,282개 사용 (91% 활용)
  • ✅ 트래픽 가시성: UI↔Relay↔Agent 통신 체인 완전 관측

주요 관측 포인트:

  1. 데이터 플로우: UI → Relay → 각 노드 Agent (4244 포트)
  2. Security Identity: 각 Pod/서비스별 고유 ID 부여 (5694, 7661, 11581)
  3. 통신 방향: to-endpoint, to-network, to-stack 등 명확한 방향성
  4. 프로토콜 세부사항: TCP Flags (ACK, PSH, RST) 레벨까지 추적

Cilium Network Policy 실습

Cilium Agent 단축키 지정

# cilium 파드 이름
export CILIUMPOD0=$(kubectl get -l k8s-app=cilium pods -n kube-system --field-selector spec.nodeName=k8s-ctr -o jsonpath='{.items[0].metadata.name}')
export CILIUMPOD1=$(kubectl get -l k8s-app=cilium pods -n kube-system --field-selector spec.nodeName=k8s-w1  -o jsonpath='{.items[0].metadata.name}')
export CILIUMPOD2=$(kubectl get -l k8s-app=cilium pods -n kube-system --field-selector spec.nodeName=k8s-w2  -o jsonpath='{.items[0].metadata.name}')
echo $CILIUMPOD0 $CILIUMPOD1 $CILIUMPOD2

# 단축키(alias) 지정
alias c0="kubectl exec -it $CILIUMPOD0 -n kube-system -c cilium-agent -- cilium"
alias c1="kubectl exec -it $CILIUMPOD1 -n kube-system -c cilium-agent -- cilium"
alias c2="kubectl exec -it $CILIUMPOD2 -n kube-system -c cilium-agent -- cilium"

alias c0bpf="kubectl exec -it $CILIUMPOD0 -n kube-system -c cilium-agent -- bpftool"
alias c1bpf="kubectl exec -it $CILIUMPOD1 -n kube-system -c cilium-agent -- bpftool"
alias c2bpf="kubectl exec -it $CILIUMPOD2 -n kube-system -c cilium-agent -- bpftool"

# endpoint
c0 endpoint list
c0 endpoint list -o json
c1 endpoint list
c2 endpoint list

c1 endpoint get <id>
c1 endpoint log <id>

## Enable debugging output on the cilium-dbg monitor for this endpoint
c1 endpoint config <id> Debug=true

# monitor
c1 monitor
c1 monitor -v
c1 monitor -v -v

## Filter for only the events related to endpoint
c1 monitor --related-to=<id>

## Show notifications only for dropped packet events
c1 monitor --type drop

## Don't dissect packet payload, display payload in hex information
c1 monitor -v -v --hex

## Layer7
c1 monitor -v --type l7

# Manage IP addresses and associated information - IP List
c0 ip list

# IDENTITY :  1(host), 2(world), 4(health), 6(remote), 파드마다 개별 ID
c0 ip list -n

# Retrieve information about an identity
c0 identity list

# 엔드포인트 기준 ID
c0 identity list --endpoints

# 엔드포인트 설정 확인 및 변경
c0 endpoint config <엔트포인트ID>

# 엔드포인트 상세 정보 확인
c0 endpoint get <엔트포인트ID>

# 엔드포인트 로그 확인
c0 endpoint log <엔트포인트ID>

# Show bpf filesystem mount details
c0 bpf fs show

# bfp 마운트 폴더 확인
tree /sys/fs/bpf

# Get list of loadbalancer services
c0 service list
c1 service list
c2 service list

## Or you can get the loadbalancer information using bpf list
c0 bpf lb list
c1 bpf lb list
c2 bpf lb list

## List reverse NAT entries
c1 bpf lb list --revnat
c2 bpf lb list --revnat

# List connection tracking entries
c0 bpf ct list global
c1 bpf ct list global
c2 bpf ct list global

# Flush connection tracking entries
c0 bpf ct flush
c1 bpf ct flush
c2 bpf ct flush

# List all NAT mapping entries
c0 bpf nat list
c1 bpf nat list
c2 bpf nat list

# Flush all NAT mapping entries
c0 bpf nat flush
c1 bpf nat flush
c2 bpf nat flush

# Manage the IPCache mappings for IP/CIDR <-> Identity
c0 bpf ipcache list# Display cgroup metadata maintained by Cilium
c0 cgroups list
c1 cgroups list
c2 cgroups list

# List all open BPF maps
c0 map list
c1 map list --verbose
c2 map list --verbose

c1 map events cilium_lb4_services_v2
c1 map events cilium_lb4_reverse_nat
c1 map events cilium_lxc
c1 map events cilium_ipcache

# List all metrics
c1 metrics list

# List contents of a policy BPF map : Dump all policy maps
c0 bpf policy get --all
c1 bpf policy get --all -n
c2 bpf policy get --all -n

# Dump StateDB contents as JSON
c0 statedb dump

#
c0 shell -- db/show devices
c1 shell -- db/show devices
c2 shell -- db/show devices

Getting Started with the Star Wars Demo & Hubble/UI


출처 - https://docs.cilium.io/en/stable/gettingstarted/demo/

 

  • 스타워즈에서 영감을 받은 예제에서는 데스스타, 타이파이터, 엑스윙의 세 가지 마이크로서비스 애플리케이션이 있습니다.
  • 데스스타는 포트 80에서 HTTP 웹서비스를 실행하며, 이 서비스는 두 개의 포드 복제본에 걸쳐 데스스타에 대한 요청을 로드 밸런싱하는 Kubernetes 서비스로 노출됩니다.
  • 데스스타 서비스는 제국의 우주선에 착륙 서비스를 제공하여 착륙 포트를 요청할 수 있도록 합니다.
  • 타이파이터 포드는 일반적인 제국 선박의 착륙 요청 클라이언트 서비스를 나타내며, 엑스윙은 동맹 선박의 유사한 서비스를 나타냅니다.
  • 데스스타 착륙 서비스에 대한 접근 제어를 위한 다양한 보안 정책을 테스트할 수 있도록 존재합니다.

실습 환경 설정

#
kubectl apply -f https://raw.githubusercontent.com/cilium/cilium/1.17.6/examples/minikube/http-sw-app.yaml

# 파드 라벨 labels 확인
kubectl get pod --show-labels

kubectl get deploy,svc,ep deathstar

kubectl get ciliumendpoints.cilium.io -A
kubectl get ciliumidentities.cilium.io

# in a multi-node installation, only the ones running on the same node will be listed
kubectl exec -it -n kube-system ds/cilium -c cilium-agent -- **cilium endpoint list**
c0 endpoint list
c1 endpoint list
c2 endpoint list
# 현재 ingress/egress 에 정책(Policy) 없음! , Labels 정보 확인
# 엔드포인트 라벨별로 정책이 설정되기 때문에 라벨을 확인하는것이 중요하다. (예: k8s:class=deathstart)

✅ 실행 결과 요약

1. Star Wars 데모 애플리케이션 배포 성공

# 4개 Pod 정상 배포 완료
(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl get pod --show-labels
NAME                        READY   STATUS    RESTARTS   AGE   LABELS
deathstar-8c4c77fb7-m8q2b   1/1     Running   0          32s   app.kubernetes.io/name=deathstar,class=deathstar,org=empire,pod-template-hash=8c4c77fb7
deathstar-8c4c77fb7-nnzkt   1/1     Running   0          32s   app.kubernetes.io/name=deathstar,class=deathstar,org=empire,pod-template-hash=8c4c77fb7
tiefighter                  1/1     Running   0          32s   app.kubernetes.io/name=tiefighter,class=tiefighter,org=empire
xwing                       1/1     Running   0          32s   app.kubernetes.io/name=xwing,class=xwing,org=alliance

# DeathStar 서비스 및 엔드포인트
service/deathstar   ClusterIP   10.96.41.44   <none>        80/TCP    38s
endpoints/deathstar   172.20.1.167:80,172.20.2.219:80   # 2개 Pod로 로드밸런싱

2. Cilium Security Identity 체계

# 각 애플리케이션별 고유 Security Identity 할당
(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl get ciliumendpoints.cilium.io -A
NAMESPACE     NAME                           SECURITY IDENTITY   IPV4           
default       deathstar-8c4c77fb7-m8q2b      15933               172.20.1.167   # Empire - DeathStar
default       deathstar-8c4c77fb7-nnzkt      15933               172.20.2.219   # Empire - DeathStar (동일 ID)
default       tiefighter                     9225                172.20.2.9     # Empire - TieFighter
default       xwing                          7207                172.20.1.160   # Alliance - X-Wing
kube-system   coredns-674b8bbfcf-2sbw2       5694                172.20.0.51    # System - CoreDNS
kube-system   coredns-674b8bbfcf-p8kth       5694                172.20.0.107   # System - CoreDNS (동일 ID)
kube-system   hubble-relay-5dcd46f5c-tln2s   11581               172.20.2.176   # System - Hubble Relay
kube-system   hubble-ui-76d4965bb6-hcgj6     7661                172.20.1.129   # System - Hubble UI

# Identity 요약
kubectl get ciliumidentities.cilium.io
NAME    NAMESPACE     AGE
15933   default       # DeathStar (2개 Pod 공유)
9225    default       # TieFighter
7207    default       # X-Wing
11581   kube-system   # Hubble Relay
7661    kube-system   # Hubble UI
5694    kube-system   # CoreDNS (2개 Pod 공유)

3. 노드별 엔드포인트 분산 현황

노드 엔드포인트 Identity 애플리케이션 IP 주소
k8s-ctr 703 1 Host -
k8s-ctr 1174 5694 CoreDNS 172.20.0.107
k8s-ctr 2609 5694 CoreDNS 172.20.0.51
k8s-w1 808 1 Host -
k8s-w1 1782 7661 Hubble UI 172.20.1.129
k8s-w1 2885 7207 X-Wing (Alliance) 172.20.1.160
k8s-w1 3615 15933 DeathStar (Empire) 172.20.1.167
k8s-w2 93 11581 Hubble Relay 172.20.2.176
k8s-w2 1041 15933 DeathStar (Empire) 172.20.2.219
k8s-w2 2090 9225 TieFighter (Empire) 172.20.2.9
k8s-w2 2374 1 Host -

4. 중요한 레이블 체계 분석

조직별 분류:

  • org=empire: DeathStar, TieFighter (제국군)
  • org=alliance: X-Wing (반군 연합)

클래스별 분류:

  • class=deathstar: 웹 서비스 (포트 80)
  • class=tiefighter: 제국 클라이언트
  • class=xwing: 연합 클라이언트

네임스페이스별 분류:

  • default: Star Wars 애플리케이션들
  • kube-system: Cilium 시스템 컴포넌트들

5. 현재 보안 정책 상태

# 모든 엔드포인트에서 정책 비활성화 상태
POLICY (ingress)   POLICY (egress)
Disabled           Disabled

# 의미: 현재 모든 Pod 간 통신이 제한 없이 허용됨
# 향후 네트워크 정책을 통해 Empire vs Alliance 간 접근 제어 가능

Star Wars 데모 아키텍처 완성:

┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐
│   k8s-ctr       │    │   k8s-w1        │    │   k8s-w2        │
├─────────────────┤    ├─────────────────┤    ├─────────────────┤
│ CoreDNS (2개)   │    │ Hubble UI       │    │ Hubble Relay    │
│ (5694)          │    │ (7661)          │    │ (11581)         │
│                 │    │                 │    │                 │
│                 │    │ X-Wing          │    │ TieFighter      │
│                 │    │ (7207) Alliance │    │ (9225) Empire   │
│                 │    │                 │    │                 │
│                 │    │ DeathStar       │    │ DeathStar       │
│                 │    │ (15933) Empire  │    │ (15933) Empire  │
└─────────────────┘    └─────────────────┘    └─────────────────┘
                              │                       │
                              └───────┬───────────────┘
                                      │
                                ┌─────────────┐
                                │ DeathStar   │
                                │ Service     │
                                │ (ClusterIP) │
                                │ 10.96.41.44 │
                                └─────────────┘

준비 완료 상태:

  • ✅ Star Wars 데모: 4개 애플리케이션 정상 배포
  • ✅ Security Identity: 각 역할별 고유 ID 할당
  • ✅ 네트워크 분산: 3개 노드에 균등 분산
  • ✅ 서비스 노출: DeathStar HTTP 서비스 준비
  • ✅ 정책 대기: 현재 모든 통신 허용 (정책 실습 준비)

현재 접근 전체 허용 테스트

  • 데스스타 서비스의 관점에서 보면, org= empire 라벨이 부착된 선박만 연결하여 착륙을 요청할 수 있습니다.
  • 규칙을 시행하지 않기 때문에 Xwing과 타이파이터 모두 착륙을 요청할 수 있습니다.
# 아래 출력에서 xwing 와 tiefighter 의 IDENTITY 메모
c1 endpoint list | grep -iE 'xwing|tiefighter|deathstar'
c2 endpoint list | grep -iE 'xwing|tiefighter|deathstar'
XWINGID=17141
TIEFIGHTERID=56716
DEATHSTARID=8113

# 모니터링 준비 : 터미널 3개, 단축키 설정
## 각각 monitor 확인
c0 monitor -v -v
c1 monitor -v -v
c2 monitor -v -v

# 모니터링 준비 : 터미널 1개
hubble observe -f

XWINGID=7207
TIEFIGHTERID=9225
DEATHSTARID=15933

hubble observe -f --from-identity $XWINGID
hubble observe -f --protocol udp --from-identity $XWINGID
hubble observe -f --protocol tcp --from-identity $XWINGID

hubble observe -f --protocol tcp --from-identity $DEATHSTARID

# 호출 시도 1
kubectl exec xwing -- curl -s -XPOST deathstar.default.svc.cluster.local/v1/request-landing
while true; do kubectl exec xwing -- curl -s -XPOST deathstar.default.svc.cluster.local/v1/request-landing ; sleep 5 ; done

# 호출 시도 2
kubectl exec tiefighter -- curl -s -XPOST deathstar.default.svc.cluster.local/v1/request-landing
while true; do kubectl exec tiefighter -- curl -s -XPOST deathstar.default.svc.cluster.local/v1/request-landing ; sleep 5 ; done

✅ 실행 결과 요약
호출 시도 1

(⎈|HomeLab:N/A) root@k8s-ctr:~# hubble observe -f --from-identity $XWINGID
Jul 25 17:44:03.781: default/xwing (ID:7207) <> 10.96.0.10:53 (world) pre-xlate-fwd TRACED (UDP)
Jul 25 17:44:03.781: default/xwing (ID:7207) <> kube-system/coredns-674b8bbfcf-2sbw2:53 (ID:5694) post-xlate-fwd TRANSLATED (UDP)
Jul 25 17:44:03.782: default/xwing:56514 (ID:7207) -> kube-system/coredns-674b8bbfcf-2sbw2:53 (ID:5694) to-network FORWARDED (UDP)
Jul 25 17:44:03.782: default/xwing:56514 (ID:7207) -> kube-system/coredns-674b8bbfcf-2sbw2:53 (ID:5694) to-endpoint FORWARDED (UDP)
Jul 25 17:44:03.783: default/xwing:56514 (ID:7207) <> kube-system/coredns-674b8bbfcf-2sbw2 (ID:5694) pre-xlate-rev TRACED (UDP)
Jul 25 17:44:03.783: default/xwing:56514 (ID:7207) <> kube-system/coredns-674b8bbfcf-2sbw2 (ID:5694) pre-xlate-rev TRACED (UDP)
Jul 25 17:44:03.806: default/xwing (ID:7207) <> 10.96.0.10:53 (world) pre-xlate-fwd TRACED (UDP)
Jul 25 17:44:03.806: default/xwing (ID:7207) <> kube-system/coredns-674b8bbfcf-p8kth:53 (ID:5694) post-xlate-fwd TRANSLATED (UDP)
Jul 25 17:44:03.806: default/xwing:53575 (ID:7207) -> kube-system/coredns-674b8bbfcf-p8kth:53 (ID:5694) to-network FORWARDED (UDP)
Jul 25 17:44:03.806: default/xwing:53575 (ID:7207) -> kube-system/coredns-674b8bbfcf-p8kth:53 (ID:5694) to-endpoint FORWARDED (UDP)
Jul 25 17:44:03.807: default/xwing:53575 (ID:7207) <> kube-system/coredns-674b8bbfcf-p8kth (ID:5694) pre-xlate-rev TRACED (UDP)
Jul 25 17:44:03.807: default/xwing:53575 (ID:7207) <> kube-system/coredns-674b8bbfcf-p8kth (ID:5694) pre-xlate-rev TRACED (UDP)
Jul 25 17:44:03.809: default/xwing (ID:7207) <> 10.96.0.10:53 (world) pre-xlate-fwd TRACED (UDP)
Jul 25 17:44:03.809: default/xwing (ID:7207) <> kube-system/coredns-674b8bbfcf-2sbw2:53 (ID:5694) post-xlate-fwd TRANSLATED (UDP)
Jul 25 17:44:03.809: default/xwing:33253 (ID:7207) -> kube-system/coredns-674b8bbfcf-2sbw2:53 (ID:5694) to-network FORWARDED (UDP)
Jul 25 17:44:03.810: default/xwing:33253 (ID:7207) <> kube-system/coredns-674b8bbfcf-2sbw2 (ID:5694) pre-xlate-rev TRACED (UDP)
Jul 25 17:44:03.810: default/xwing:33253 (ID:7207) <> kube-system/coredns-674b8bbfcf-2sbw2 (ID:5694) pre-xlate-rev TRACED (UDP)
Jul 25 17:44:03.810: default/xwing:33253 (ID:7207) -> kube-system/coredns-674b8bbfcf-2sbw2:53 (ID:5694) to-endpoint FORWARDED (UDP)
Jul 25 17:44:03.810: default/xwing (ID:7207) <> 10.96.0.10:53 (world) pre-xlate-fwd TRACED (UDP)
Jul 25 17:44:03.811: default/xwing (ID:7207) <> kube-system/coredns-674b8bbfcf-p8kth:53 (ID:5694) post-xlate-fwd TRANSLATED (UDP)
Jul 25 17:44:03.811: default/xwing:35900 (ID:7207) -> kube-system/coredns-674b8bbfcf-p8kth:53 (ID:5694) to-network FORWARDED (UDP)
Jul 25 17:44:03.812: default/xwing:35900 (ID:7207) -> kube-system/coredns-674b8bbfcf-p8kth:53 (ID:5694) to-endpoint FORWARDED (UDP)
Jul 25 17:44:03.812: default/xwing:35900 (ID:7207) <> kube-system/coredns-674b8bbfcf-p8kth (ID:5694) pre-xlate-rev TRACED (UDP)
Jul 25 17:44:03.812: default/xwing:35900 (ID:7207) <> kube-system/coredns-674b8bbfcf-p8kth (ID:5694) pre-xlate-rev TRACED (UDP)
Jul 25 17:44:03.815: default/xwing (ID:7207) <> 10.96.41.44:80 (world) pre-xlate-fwd TRACED (TCP)
Jul 25 17:44:03.815: default/xwing (ID:7207) <> default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) post-xlate-fwd TRANSLATED (TCP)
Jul 25 17:44:03.815: default/xwing:43318 (ID:7207) -> default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) to-network FORWARDED (TCP Flags: SYN)
Jul 25 17:44:03.816: default/xwing:43318 (ID:7207) -> default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) to-endpoint FORWARDED (TCP Flags: SYN)
Jul 25 17:44:03.816: default/xwing:43318 (ID:7207) -> default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) to-network FORWARDED (TCP Flags: ACK)
Jul 25 17:44:03.816: default/xwing:43318 (ID:7207) -> default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) to-network FORWARDED (TCP Flags: ACK, PSH)
Jul 25 17:44:03.817: default/xwing:43318 (ID:7207) -> default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) to-endpoint FORWARDED (TCP Flags: ACK)
Jul 25 17:44:03.817: default/xwing:43318 (ID:7207) -> default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) to-endpoint FORWARDED (TCP Flags: ACK, PSH)
Jul 25 17:44:03.817: default/xwing:43318 (ID:7207) <> default/deathstar-8c4c77fb7-nnzkt (ID:15933) pre-xlate-rev TRACED (TCP)
Jul 25 17:44:03.819: default/xwing:43318 (ID:7207) <> default/deathstar-8c4c77fb7-nnzkt (ID:15933) pre-xlate-rev TRACED (TCP)
Jul 25 17:44:03.819: default/xwing:43318 (ID:7207) <> default/deathstar-8c4c77fb7-nnzkt (ID:15933) pre-xlate-rev TRACED (TCP)
Jul 25 17:44:03.820: default/xwing:43318 (ID:7207) <> default/deathstar-8c4c77fb7-nnzkt (ID:15933) pre-xlate-rev TRACED (TCP)
Jul 25 17:44:03.820: default/xwing:43318 (ID:7207) <> default/deathstar-8c4c77fb7-nnzkt (ID:15933) pre-xlate-rev TRACED (TCP)
Jul 25 17:44:03.821: default/xwing:43318 (ID:7207) -> default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) to-network FORWARDED (TCP Flags: ACK, FIN)
Jul 25 17:44:03.821: default/xwing:43318 (ID:7207) -> default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) to-network FORWARDED (TCP Flags: ACK)
Jul 25 17:44:03.822: default/xwing:43318 (ID:7207) -> default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) to-endpoint FORWARDED (TCP Flags: ACK, FIN)
Jul 25 17:44:03.822: default/xwing:43318 (ID:7207) -> default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) to-endpoint FORWARDED (TCP Flags: ACK)

(⎈|HomeLab:N/A) root@k8s-ctr:~# hubble observe -f --protocol udp --from-identity $XWINGID
Jul 25 17:47:06.358: default/xwing (ID:7207) <> 10.96.0.10:53 (world) pre-xlate-fwd TRACED (UDP)
Jul 25 17:47:06.358: default/xwing (ID:7207) <> kube-system/coredns-674b8bbfcf-p8kth:53 (ID:5694) post-xlate-fwd TRANSLATED (UDP)
Jul 25 17:47:06.359: default/xwing:44290 (ID:7207) -> kube-system/coredns-674b8bbfcf-p8kth:53 (ID:5694) to-network FORWARDED (UDP)
Jul 25 17:47:06.359: default/xwing:44290 (ID:7207) -> kube-system/coredns-674b8bbfcf-p8kth:53 (ID:5694) to-endpoint FORWARDED (UDP)
Jul 25 17:47:06.360: default/xwing:44290 (ID:7207) <> kube-system/coredns-674b8bbfcf-p8kth (ID:5694) pre-xlate-rev TRACED (UDP)
Jul 25 17:47:06.360: default/xwing:44290 (ID:7207) <> kube-system/coredns-674b8bbfcf-p8kth (ID:5694) pre-xlate-rev TRACED (UDP)
Jul 25 17:47:06.360: default/xwing (ID:7207) <> 10.96.0.10:53 (world) pre-xlate-fwd TRACED (UDP)
Jul 25 17:47:06.360: default/xwing (ID:7207) <> kube-system/coredns-674b8bbfcf-p8kth:53 (ID:5694) post-xlate-fwd TRANSLATED (UDP)
Jul 25 17:47:06.360: default/xwing:34714 (ID:7207) -> kube-system/coredns-674b8bbfcf-p8kth:53 (ID:5694) to-network FORWARDED (UDP)
Jul 25 17:47:06.361: default/xwing:34714 (ID:7207) -> kube-system/coredns-674b8bbfcf-p8kth:53 (ID:5694) to-endpoint FORWARDED (UDP)
Jul 25 17:47:06.361: default/xwing:34714 (ID:7207) <> kube-system/coredns-674b8bbfcf-p8kth (ID:5694) pre-xlate-rev TRACED (UDP)
Jul 25 17:47:06.361: default/xwing:34714 (ID:7207) <> kube-system/coredns-674b8bbfcf-p8kth (ID:5694) pre-xlate-rev TRACED (UDP)
Jul 25 17:47:06.361: default/xwing (ID:7207) <> 10.96.0.10:53 (world) pre-xlate-fwd TRACED (UDP)
Jul 25 17:47:06.361: default/xwing (ID:7207) <> kube-system/coredns-674b8bbfcf-2sbw2:53 (ID:5694) post-xlate-fwd TRANSLATED (UDP)
Jul 25 17:47:06.362: default/xwing:39701 (ID:7207) -> kube-system/coredns-674b8bbfcf-2sbw2:53 (ID:5694) to-network FORWARDED (UDP)
Jul 25 17:47:06.362: default/xwing:39701 (ID:7207) -> kube-system/coredns-674b8bbfcf-2sbw2:53 (ID:5694) to-endpoint FORWARDED (UDP)
Jul 25 17:47:06.362: default/xwing:39701 (ID:7207) <> kube-system/coredns-674b8bbfcf-2sbw2 (ID:5694) pre-xlate-rev TRACED (UDP)
Jul 25 17:47:06.362: default/xwing:39701 (ID:7207) <> kube-system/coredns-674b8bbfcf-2sbw2 (ID:5694) pre-xlate-rev TRACED (UDP)
Jul 25 17:47:06.363: default/xwing (ID:7207) <> 10.96.0.10:53 (world) pre-xlate-fwd TRACED (UDP)
Jul 25 17:47:06.363: default/xwing (ID:7207) <> kube-system/coredns-674b8bbfcf-p8kth:53 (ID:5694) post-xlate-fwd TRANSLATED (UDP)
Jul 25 17:47:06.363: default/xwing:60690 (ID:7207) -> kube-system/coredns-674b8bbfcf-p8kth:53 (ID:5694) to-network FORWARDED (UDP)
Jul 25 17:47:06.364: default/xwing:60690 (ID:7207) -> kube-system/coredns-674b8bbfcf-p8kth:53 (ID:5694) to-endpoint FORWARDED (UDP)
Jul 25 17:47:06.364: default/xwing:60690 (ID:7207) <> kube-system/coredns-674b8bbfcf-p8kth (ID:5694) pre-xlate-rev TRACED (UDP)
Jul 25 17:47:06.364: default/xwing:60690 (ID:7207) <> kube-system/coredns-674b8bbfcf-p8kth (ID:5694) pre-xlate-rev TRACED (UDP)

(⎈|HomeLab:N/A) root@k8s-ctr:~# hubble observe -f --protocol tcp --from-identity $XWINGID
Jul 25 17:47:29.583: default/xwing (ID:7207) <> 10.96.41.44:80 (world) pre-xlate-fwd TRACED (TCP)
Jul 25 17:47:29.583: default/xwing (ID:7207) <> default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) post-xlate-fwd TRANSLATED (TCP)
Jul 25 17:47:29.584: default/xwing:40112 (ID:7207) -> default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) to-network FORWARDED (TCP Flags: SYN)
Jul 25 17:47:29.584: default/xwing:40112 (ID:7207) -> default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) to-network FORWARDED (TCP Flags: ACK)
Jul 25 17:47:29.584: default/xwing:40112 (ID:7207) -> default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) to-endpoint FORWARDED (TCP Flags: SYN)
Jul 25 17:47:29.585: default/xwing:40112 (ID:7207) -> default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) to-network FORWARDED (TCP Flags: ACK, PSH)
Jul 25 17:47:29.585: default/xwing:40112 (ID:7207) -> default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) to-endpoint FORWARDED (TCP Flags: ACK)
Jul 25 17:47:29.585: default/xwing:40112 (ID:7207) <> default/deathstar-8c4c77fb7-nnzkt (ID:15933) pre-xlate-rev TRACED (TCP)
Jul 25 17:47:29.585: default/xwing:40112 (ID:7207) -> default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) to-endpoint FORWARDED (TCP Flags: ACK, PSH)
Jul 25 17:47:29.586: default/xwing:40112 (ID:7207) <> default/deathstar-8c4c77fb7-nnzkt (ID:15933) pre-xlate-rev TRACED (TCP)
Jul 25 17:47:29.586: default/xwing:40112 (ID:7207) <> default/deathstar-8c4c77fb7-nnzkt (ID:15933) pre-xlate-rev TRACED (TCP)
Jul 25 17:47:29.586: default/xwing:40112 (ID:7207) <> default/deathstar-8c4c77fb7-nnzkt (ID:15933) pre-xlate-rev TRACED (TCP)
Jul 25 17:47:29.586: default/xwing:40112 (ID:7207) <> default/deathstar-8c4c77fb7-nnzkt (ID:15933) pre-xlate-rev TRACED (TCP)
Jul 25 17:47:29.586: default/xwing:40112 (ID:7207) -> default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) to-network FORWARDED (TCP Flags: ACK, FIN)
Jul 25 17:47:29.587: default/xwing:40112 (ID:7207) -> default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) to-network FORWARDED (TCP Flags: ACK)
Jul 25 17:47:29.587: default/xwing:40112 (ID:7207) -> default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) to-endpoint FORWARDED (TCP Flags: ACK, FIN)
Jul 25 17:47:29.587: default/xwing:40112 (ID:7207) -> default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) to-endpoint FORWARDED (TCP Flags: ACK)

(⎈|HomeLab:N/A) root@k8s-ctr:~# hubble observe -f --protocol tcp --from-identity $DEATHSTARID
Jul 25 17:47:52.956: default/xwing:60920 (ID:7207) <- default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) to-endpoint FORWARDED (TCP Flags: SYN, ACK)
Jul 25 17:47:52.956: default/xwing:60920 (ID:7207) <- default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) to-network FORWARDED (TCP Flags: SYN, ACK)
Jul 25 17:47:52.956: default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) <> default/xwing (ID:7207) pre-xlate-rev TRACED (TCP)
Jul 25 17:47:52.956: default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) <> default/xwing (ID:7207) pre-xlate-rev TRACED (TCP)
Jul 25 17:47:52.958: default/xwing:60920 (ID:7207) <- default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) to-endpoint FORWARDED (TCP Flags: ACK, PSH)
Jul 25 17:47:52.958: default/xwing:60920 (ID:7207) <- default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) to-network FORWARDED (TCP Flags: ACK, PSH)
Jul 25 17:47:52.959: default/xwing:60920 (ID:7207) <- default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) to-endpoint FORWARDED (TCP Flags: ACK, FIN)
Jul 25 17:47:52.959: default/xwing:60920 (ID:7207) <- default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) to-network FORWARDED (TCP Flags: ACK, FIN)

(⎈|HomeLab:N/A) root@k8s-ctr:~# hubble observe -f --protocol tcp --from-identity $TIEFIGHTERID 
kubectl exec tiefighter -- curl -s -XPOST deathstar.default.svc.cluster.local/v1/request-landing
Jul 25 17:51:18.026: default/tiefighter (ID:9225) <> 10.96.41.44:80 (world) pre-xlate-fwd TRACED (TCP)
Jul 25 17:51:18.026: default/tiefighter (ID:9225) <> default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) post-xlate-fwd TRANSLATED (TCP)
Jul 25 17:51:18.027: default/tiefighter:48532 (ID:9225) -> default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) to-endpoint FORWARDED (TCP Flags: SYN)
Jul 25 17:51:18.027: default/tiefighter:48532 (ID:9225) -> default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) to-endpoint FORWARDED (TCP Flags: ACK)
Jul 25 17:51:18.027: default/tiefighter:48532 (ID:9225) -> default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) to-endpoint FORWARDED (TCP Flags: ACK, PSH)
Jul 25 17:51:18.027: default/tiefighter:48532 (ID:9225) <> default/deathstar-8c4c77fb7-nnzkt (ID:15933) pre-xlate-rev TRACED (TCP)
Jul 25 17:51:18.027: default/tiefighter:48532 (ID:9225) <> default/deathstar-8c4c77fb7-nnzkt (ID:15933) pre-xlate-rev TRACED (TCP)
Jul 25 17:51:18.027: default/tiefighter:48532 (ID:9225) <> default/deathstar-8c4c77fb7-nnzkt (ID:15933) pre-xlate-rev TRACED (TCP)
Jul 25 17:51:18.028: default/tiefighter:48532 (ID:9225) <> default/deathstar-8c4c77fb7-nnzkt (ID:15933) pre-xlate-rev TRACED (TCP)
Jul 25 17:51:18.028: default/tiefighter:48532 (ID:9225) <> default/deathstar-8c4c77fb7-nnzkt (ID:15933) pre-xlate-rev TRACED (TCP)
Jul 25 17:51:18.028: default/tiefighter:48532 (ID:9225) -> default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) to-endpoint FORWARDED (TCP Flags: ACK, FIN)
Jul 25 17:51:18.029: default/tiefighter:48532 (ID:9225) -> default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) to-endpoint FORWARDED (TCP Flags: ACK)

X윙~! 호출시


타이파이터 호출시

보안정책 적용

  • Cilium을 사용할 때 보안 정책을 정의할 때 엔드포인트 IP 주소는 중요하지 않습니다. 대신 포드에 할당된 레이블을 사용하여 보안 정책을 정의할 수 있습니다. 정책은 클러스터 내에서 실행 중이거나 실행 중인 위치에 관계없이 레이블을 기반으로 올바른 포드에 적용됩니다.
  • 데스스타 착륙 요청을 라벨이 있는 선박(org=empire)으로만 제한하는 기본 정책부터 시작하겠습니다. 이렇게 하면 org=empire 라벨이 없는 선박은 데스스타 서비스와 연결조차 할 수 없습니다. 이 정책은 IP 프로토콜(네트워크 계층 3)과 TCP 프로토콜(네트워크 계층 4)에만 적용되는 간단한 정책이므로 흔히 L3/L4 네트워크 보안 정책이라고 합니다.
  • 참고: 실리움은 상태별 연결 추적을 수행합니다. 이는 정책이 프론트엔드가 백엔드에 도달할 수 있도록 허용하면, 동일한 TCP/UDP 연결 내에서 백엔드 응답의 일부인 모든 필수 응답 패킷이 자동으로 프론트엔드에 도달하도록 허용한다는 것을 의미합니다. → 리턴 패킷 자동 허용!
# CiliumNetworkPolicy
## CiliumNetworkPolicys는 "endpointSelector"를 사용하여 팟 레이블에서 정책이 적용되는 소스와 목적지를 식별합니다. 
## 아래 정책은 TCP 포트 80에서 레이블(org=empire)이 있는 모든 팟에서 레이블(org=empire, class=deathstar)이 있는 데스스타 팟으로 전송되는 트래픽을 화이트리스트로 작성합니다.
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
  name: "rule1"
spec:
  description: "L3-L4 policy to restrict deathstar access to empire ships only"
  endpointSelector:
    matchLabels:
      org: empire
      class: deathstar
  ingress:
  - fromEndpoints:
    - matchLabels:
        org: empire
    toPorts:
    - ports:
      - port: "80"
        protocol: TCP

kubectl apply -f https://raw.githubusercontent.com/cilium/cilium/1.17.6/examples/minikube/sw_l3_l4_policy.yaml

#CNP -> Cilium Network Policy
kubectl get cnp
kubectl get cnp -o json | jq

# 모니터링
hubble observe -f --type drop

# 호출 시도 1 
kubectl exec xwing -- curl -s -XPOST deathstar.default.svc.cluster.local/v1/request-landing --connect-timeout 2


# 모니터링 
hubble observe -f --protocol tcp --from-identity $DEATHSTARID

# 호출 시도 2
kubectl exec tiefighter -- curl -s -XPOST deathstar.default.svc.cluster.local/v1/request-landing

✅ 실행 결과 요약

(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl apply -f https://raw.githubusercontent.com/cilium/cilium/1.17.6/examples/minikube/sw_l3_l4_policy.yaml
ciliumnetworkpolicy.cilium.io/rule1 created
(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl get cnp
NAME    AGE   VALID
rule1   9s    True

(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl get cnp -o json | jq
{
  "apiVersion": "v1",
  "items": [
    {
      "apiVersion": "cilium.io/v2",
      ...
      "spec": {
        "description": "L3-L4 policy to restrict deathstar access to empire ships only",
        "endpointSelector": {
          "matchLabels": {
            "class": "deathstar",
            "org": "empire"
          }
        },
        "ingress": [
          {
            "fromEndpoints": [
              {
                "matchLabels": {
                  "org": "empire"
                }
              }
            ],
            "toPorts": [
              {
                "ports": [
                  {
                    "port": "80",
                    "protocol": "TCP"
                  }
                ]
              }
            ]
          }
        ]
      },
      "status": {
        "conditions": [
          {
            "lastTransitionTime": "2025-07-25T18:01:50Z",
            "message": "Policy validation succeeded",
            "status": "True",
            "type": "Valid"
          }
        ]
      }
    }
  ],
  "kind": "List",
  "metadata": {
    "resourceVersion": ""
  }
}

(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl exec xwing -- curl -s -XPOST deathstar.default.svc.cluster.local/v1/request-landing --connect-timeout 2
command terminated with exit code 28

#Death Start 모니터링시 타이파이터만 랜딩됨
(⎈|HomeLab:N/A) root@k8s-ctr:~# hubble observe -f --protocol tcp --from-identity $DEATHSTARID
Jul 25 18:04:28.190: default/tiefighter:56672 (ID:9225) <- default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) to-endpoint FORWARDED (TCP Flags: SYN, ACK)
Jul 25 18:04:28.190: default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) <> default/tiefighter (ID:9225) pre-xlate-rev TRACED (TCP)
Jul 25 18:04:28.190: default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) <> default/tiefighter (ID:9225) pre-xlate-rev TRACED (TCP)
Jul 25 18:04:28.191: default/tiefighter:56672 (ID:9225) <- default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) to-endpoint FORWARDED (TCP Flags: ACK, PSH)
Jul 25 18:04:28.191: default/tiefighter:56672 (ID:9225) <- default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) to-endpoint FORWARDED (TCP Flags: ACK, FIN)

(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl exec tiefighter -- curl -s -XPOST deathstar.default.svc.cluster.local/v1/request-landing
Ship landed

# 네트워크 정책을 보면 각각의 노드 중 워커노드 1,2에 k8s:app.kubernetes.io/name=deathstar 정책이 Enabled 된 것을 확인할 수 있다.

(⎈|HomeLab:N/A) root@k8s-ctr:~# c0 endpoint list
ENDPOINT   POLICY (ingress)   POLICY (egress)   IDENTITY   LABELS (source:key[=value])                                                  IPv6   IPv4           STATUS   
           ENFORCEMENT        ENFORCEMENT                                                                                                                     
703        Disabled           Disabled          1          k8s:node-role.kubernetes.io/control-plane                                                          ready   
                                                           k8s:node.kubernetes.io/exclude-from-external-load-balancers                                                
                                                           reserved:host                                                                                              
1174       Disabled           Disabled          5694       k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=kube-system          172.20.0.107   ready   
                                                           k8s:io.cilium.k8s.policy.cluster=default                                                                   
                                                           k8s:io.cilium.k8s.policy.serviceaccount=coredns                                                            
                                                           k8s:io.kubernetes.pod.namespace=kube-system                                                                
                                                           k8s:k8s-app=kube-dns                                                                                       
2609       Disabled           Disabled          5694       k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=kube-system          172.20.0.51    ready   
                                                           k8s:io.cilium.k8s.policy.cluster=default                                                                   
                                                           k8s:io.cilium.k8s.policy.serviceaccount=coredns                                                            
                                                           k8s:io.kubernetes.pod.namespace=kube-system                                                                
                                                           k8s:k8s-app=kube-dns                                                                                       
(⎈|HomeLab:N/A) root@k8s-ctr:~# c1 endpoint list
ENDPOINT   POLICY (ingress)   POLICY (egress)   IDENTITY   LABELS (source:key[=value])                                                  IPv6   IPv4           STATUS   
           ENFORCEMENT        ENFORCEMENT                                                                                                                     
808        Disabled           Disabled          1          reserved:host                                                                                      ready   
1782       Disabled           Disabled          7661       k8s:app.kubernetes.io/name=hubble-ui                                                172.20.1.129   ready   
                                                           k8s:app.kubernetes.io/part-of=cilium                                                                       
                                                           k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=kube-system                                 
                                                           k8s:io.cilium.k8s.policy.cluster=default                                                                   
                                                           k8s:io.cilium.k8s.policy.serviceaccount=hubble-ui                                                          
                                                           k8s:io.kubernetes.pod.namespace=kube-system                                                                
                                                           k8s:k8s-app=hubble-ui                                                                                      
2885       Disabled           Disabled          7207       k8s:app.kubernetes.io/name=xwing                                                    172.20.1.160   ready   
                                                           k8s:class=xwing                                                                                            
                                                           k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=default                                     
                                                           k8s:io.cilium.k8s.policy.cluster=default                                                                   
                                                           k8s:io.cilium.k8s.policy.serviceaccount=default                                                            
                                                           k8s:io.kubernetes.pod.namespace=default                                                                    
                                                           k8s:org=alliance                                                                                           
3615       Enabled            Disabled          15933      k8s:app.kubernetes.io/name=deathstar                                                172.20.1.167   ready   
                                                           k8s:class=deathstar                                                                                        
                                                           k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=default                                     
                                                           k8s:io.cilium.k8s.policy.cluster=default                                                                   
                                                           k8s:io.cilium.k8s.policy.serviceaccount=default                                                            
                                                           k8s:io.kubernetes.pod.namespace=default                                                                    
                                                           k8s:org=empire                                                                                             
(⎈|HomeLab:N/A) root@k8s-ctr:~# c2 endpoint list
ENDPOINT   POLICY (ingress)   POLICY (egress)   IDENTITY   LABELS (source:key[=value])                                                  IPv6   IPv4           STATUS   
           ENFORCEMENT        ENFORCEMENT                                                                                                                     
93         Disabled           Disabled          11581      k8s:app.kubernetes.io/name=hubble-relay                                             172.20.2.176   ready   
                                                           k8s:app.kubernetes.io/part-of=cilium                                                                       
                                                           k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=kube-system                                 
                                                           k8s:io.cilium.k8s.policy.cluster=default                                                                   
                                                           k8s:io.cilium.k8s.policy.serviceaccount=hubble-relay                                                       
                                                           k8s:io.kubernetes.pod.namespace=kube-system                                                                
                                                           k8s:k8s-app=hubble-relay                                                                                   
1041       Enabled            Disabled          15933      k8s:app.kubernetes.io/name=deathstar                                                172.20.2.219   ready   
                                                           k8s:class=deathstar                                                                                        
                                                           k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=default                                     
                                                           k8s:io.cilium.k8s.policy.cluster=default                                                                   
                                                           k8s:io.cilium.k8s.policy.serviceaccount=default                                                            
                                                           k8s:io.kubernetes.pod.namespace=default                                                                    
                                                           k8s:org=empire                                                                                             
2090       Disabled           Disabled          9225       k8s:app.kubernetes.io/name=tiefighter                                               172.20.2.9     ready   
                                                           k8s:class=tiefighter                                                                                       
                                                           k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=default                                     
                                                           k8s:io.cilium.k8s.policy.cluster=default                                                                   
                                                           k8s:io.cilium.k8s.policy.serviceaccount=default                                                            
                                                           k8s:io.kubernetes.pod.namespace=default                                                                    
                                                           k8s:org=empire                                                                                             
2374       Disabled           Disabled          1          reserved:host 

Http Aware L7 레이어 정책 실습
L3~L4 정책은 ebpf가 처리하지만, L7 레이어는 cilium-envoy 데몬셋이 처리합니다.
이는 Userspace Policy를 거치기 때문에 속도가 느려질 수 있습니다. 하지만, ebpf와 userspace와 연결되기 때문에 nginx 기반 L7 보다는 효율이 좋습니다.
Cilium을 설치하면 기본적으로 L7 정책이 사용가능하도록 설정되어 있습니다.

  • 위의 간단한 시나리오에서는 tiefighter / xwing에게 데스스타 API에 대한 전체 액세스 권한을 부여하거나 아예 액세스 권한을 부여하지 않는 것으로 충분했습니다. 그러나 마이크로서비스 간에 가장 강력한 보안(즉, 최소 권한 격리를 강제하는 것)을 제공하기 위해서는 데스스타 API를 호출하는 각 서비스가 합법적인 운영에 필요한 HTTP 요청 세트만 수행하도록 제한해야 합니다.
  • 예를 들어, 데스스타 서비스가 임의의 제국 선박이 호출해서는 안 되는 일부 유지보수 API를 노출한다고 가정해 보겠습니다.

정책 설정 전

# 모니터링 >> Layer3/4 에서는 애플리케이션 상태를 확인 할 수 없음!
hubble observe -f --protocol tcp --from-identity $DEATHSTARID

# 호출해서는 안 되는 일부 유지보수 창륙장 API를 노출
kubectl exec tiefighter -- curl -s -XPUT deathstar.default.svc.cluster.local/v1/exhaust-port
(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl exec tiefighter -- curl -s -XPUT deathstar.default.svc.cluster.local/v1/exhaust-port
Panic: deathstar exploded

goroutine 1 [running]:
main.HandleGarbage(0x2080c3f50, 0x2, 0x4, 0x425c0, 0x5, 0xa)
        /code/src/github.com/empire/deathstar/
        temp/main.go:9 +0x64
main.main()
        /code/src/github.com/empire/deathstar/
        temp/main.go:5 +0x85

# L3/4 레이어에서는 L7 정책을 알 수 없고, L7 정책도 설정되어 있지 않기 때문에, 착륙이 된다.
(⎈|HomeLab:N/A) root@k8s-ctr:~# hubble observe -f --protocol tcp --from-identity $DEATHSTARID
Jul 25 18:15:44.184: default/tiefighter:58932 (ID:9225) <- default/deathstar-8c4c77fb7-m8q2b:80 (ID:15933) to-network FORWARDED (TCP Flags: SYN, ACK)
Jul 25 18:15:44.184: default/tiefighter:58932 (ID:9225) <- default/deathstar-8c4c77fb7-m8q2b:80 (ID:15933) to-endpoint FORWARDED (TCP Flags: SYN, ACK)
Jul 25 18:15:44.185: default/deathstar-8c4c77fb7-m8q2b:80 (ID:15933) <> default/tiefighter (ID:9225) pre-xlate-rev TRACED (TCP)
Jul 25 18:15:44.185: default/deathstar-8c4c77fb7-m8q2b:80 (ID:15933) <> default/tiefighter (ID:9225) pre-xlate-rev TRACED (TCP)
Jul 25 18:15:44.185: default/tiefighter:58932 (ID:9225) <- default/deathstar-8c4c77fb7-m8q2b:80 (ID:15933) to-network FORWARDED (TCP Flags: ACK, PSH)
Jul 25 18:15:44.185: default/tiefighter:58932 (ID:9225) <- default/deathstar-8c4c77fb7-m8q2b:80 (ID:15933) to-endpoint FORWARDED (TCP Flags: ACK, PSH)
Jul 25 18:15:44.187: default/tiefighter:58932 (ID:9225) <- default/deathstar-8c4c77fb7-m8q2b:80 (ID:15933) to-network FORWARDED (TCP Flags: ACK, FIN)
Jul 25 18:15:44.187: default/tiefighter:58932 (ID:9225) <- default/deathstar-8c4c77fb7-m8q2b:80 (ID:15933) to-endpoint FORWARDED (TCP Flags: ACK, FIN)

Cilium Network Policy를 통해 L7 Policy 설정
기존 cnp rule1을 업데이트 하여 네트워크 정책을 허용합니다.

# 기존 rule1 정책을 업데이트 해서 사용
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
  name: "rule1"
spec:
  description: "L7 policy to restrict access to specific HTTP call"
  endpointSelector:
    matchLabels:
      org: empire
      class: deathstar
  ingress:
  - fromEndpoints:
    - matchLabels:
        org: empire
    toPorts:
    - ports:
      - port: "80"
        protocol: TCP
      rules:
        http:
        - method: "POST"
          path: "/v1/request-landing"

# Update the existing rule to apply L7-aware policy to protect deathstar using:
kubectl apply -f https://raw.githubusercontent.com/cilium/cilium/1.17.6/examples/minikube/sw_l3_l4_l7_policy.yaml
kubectl get cnp
kc describe cnp
c0 policy get


# 모니터링 : 파드 이름 지정
hubble observe -f --pod deathstar --protocol http

# We can now re-run the same test as above, but we will see a different outcome
kubectl exec tiefighter -- curl -s -XPOST deathstar.default.svc.cluster.local/v1/request-landing

✅ 실행 결과 요약

1. L7 네트워크 정책 적용 성공

# 정책 배포 및 검증 완료
(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl apply -f https://raw.githubusercontent.com/cilium/cilium/1.17.6/examples/minikube/sw_l3_l4_l7_policy.yaml
ciliumnetworkpolicy.cilium.io/rule1 configured

(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl get cnp
NAME    AGE   VALID
rule1   20m   True  ✅ 정책 유효성 검증 성공

2. 상세 정책 규칙 분석

(⎈|HomeLab:N/A) root@k8s-ctr:~# kc describe cnp

# L7 HTTP 레벨 정책 세부사항
Name:         rule1
Description:  L7 policy to restrict access to specific HTTP call

# 대상 선택자: DeathStar (Empire)
Endpoint Selector:
  Match Labels:
    Class:  deathstar    # DeathStar 서비스만 대상
    Org:    empire       # Empire 조직 소속

# 접근 허용 규칙
Ingress:
  From Endpoints:
    Match Labels:
      Org:  empire       # Empire 조직에서만 접근 허용
  To Ports:
    Ports:
      Port:      80       # HTTP 포트
      Protocol:  TCP
    Rules:
      Http:
        Method:  POST     # POST 메서드만 허용
        Path:    /v1/request-landing  # 특정 경로만 허용

# 정책 상태
Status: True (Policy validation succeeded)

3. Cilium Agent 정책 변환

# Kubernetes CNP → Cilium 내부 정책 변환 결과
(⎈|HomeLab:N/A) root@k8s-ctr:~# c0 policy get
{
  "endpointSelector": {
    "matchLabels": {
      "any:class": "deathstar",
      "any:org": "empire",
      "k8s:io.kubernetes.pod.namespace": "default"
    }
  },
  "ingress": [{
    "fromEndpoints": [{
      "matchLabels": {
        "any:org": "empire",
        "k8s:io.kubernetes.pod.namespace": "default"
      }
    }],
    "toPorts": [{
      "ports": [{"port": "80", "protocol": "TCP"}],
      "rules": {
        "http": [{"path": "/v1/request-landing", "method": "POST"}]
      }
    }]
  }],
  "enableDefaultDeny": {
    "ingress": true,    # Ingress 기본 거부 활성화
    "egress": false     # Egress는 제한 없음
  }
}
Revision: 3  # 정책 리비전 번호

4. Empire 조직 간 통신 테스트 (성공)

# TieFighter → DeathStar 접근 허용 확인
(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl exec tiefighter -- curl -s -XPOST deathstar.default.svc.cluster.local/v1/request-landing
Ship landed  ✅ 성공적인 착륙 요청

# 허용 조건 만족:
# ✅ org=empire (TieFighter도 Empire 소속)
# ✅ method=POST (정책에서 허용된 메서드)
# ✅ path=/v1/request-landing (정책에서 허용된 경로)
# ✅ port=80 (정책에서 허용된 포트)

실습 자원 삭제

# 다음 실습을 위해 리소스 삭제
kubectl delete -f https://raw.githubusercontent.com/cilium/cilium/1.17.6/examples/minikube/http-sw-app.yaml
kubectl delete cnp rule1

# 삭제 확인
kubectl get cnp

✅ 실행 결과 요약

(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl delete -f https://raw.githubusercontent.com/cilium/cilium/1.17.6/examples/minikube/http-sw-app.yaml
service "deathstar" deleted
deployment.apps "deathstar" deleted
pod "tiefighter" deleted
pod "xwing" deleted

(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl delete cnp rule1
ciliumnetworkpolicy.cilium.io "rule1" deleted

(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl get cnp
No resources found in default namespace.

5. Hubble HTTP 트래픽 실시간 모니터링

# L7 HTTP 레벨 트래픽 관측
(⎈|HomeLab:N/A) root@k8s-ctr:~# hubble observe -f --pod deathstar --protocol http

# 실시간 HTTP 요청/응답 추적
Jul 25 18:23:15.877: default/tiefighter:52296 (ID:9225) 
                   → default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) 
                   http-request FORWARDED 
                   (HTTP/1.1 POST http://deathstar.default.svc.cluster.local/v1/request-landing)

Jul 25 18:23:15.878: default/tiefighter:52296 (ID:9225) 
                   ← default/deathstar-8c4c77fb7-nnzkt:80 (ID:15933) 
                   http-response FORWARDED 
                   (HTTP/1.1 200 1ms (POST http://deathstar.default.svc.cluster.local/v1/request-landing))

# 관측 포인트:
# 🔍 Security Identity: 9225 (TieFighter) → 15933 (DeathStar)
# 🔍 HTTP 세부사항: POST 메서드로 변경되었음, 특정 경로, 1ms 응답시간
# 🔍 상태 코드: 200 OK (성공)
# 🔍 정책 적용: FORWARDED (정책 조건 만족하여 허용)

hubble ui 에서 확인해보면, 기존과 다르게 Http가 추가된 80이 표시되고, L7 info에 어떤 uri로 접근했는지까지 내용이 나옵니다.
이전 cnf L3/4 레이어 테스트 후 캡쳐


현재 cnp L7 레이어 테스트 후 캡쳐

정책 효과 분석:

항목 Before 정책 After 정책 변화
모든 조직 모든 접근 허용 Empire만 허용 🔒 조직 기반 제한
모든 HTTP 메서드 GET/POST/PUT 모두 허용 POST만 허용 🔒 메서드 제한
모든 경로 모든 URL 허용 /v1/request-landing만 허용 🔒 경로 제한
엔드포인트 정책 Disabled Enabled ✅ 정책 활성화

L7 정책의 강력함:

  • ✅ 조직 기반 접근제어: Empire vs Alliance 분리
  • ✅ HTTP 메서드 제한: POST만 허용, GET/PUT 차단
  • ✅ URL 경로 제한: 특정 API 엔드포인트만 허용
  • ✅ 실시간 모니터링: Hubble로 L7 트래픽 완전 가시화
  • ✅ 세밀한 제어: 포트, 프로토콜, 헤더 레벨까지 제어 가능

Empire 조직은 DeathStar의 착륙 서비스를 안전하게 이용할 수 있지만, Alliance는 접근이 차단되어 완벽한 Zero Trust 네트워크 환경이 구현되었습니다.

Hubble Exporter 설정 실습

hubble의 가시성 출력을 활용하여 모니터링 환경을 구축할 때 Exporter 설정이 필요합니다.

# 설정 : 아래 설정할 필요 없음 (처음 실습환경 구축시 적용해놓았기 때문입니다.)
helm upgrade cilium cilium/cilium --namespace kube-system --reuse-values \
   --set hubble.enabled=true \
   --set hubble.export.static.enabled=true \
   --set hubble.export.static.filePath=/var/run/cilium/hubble/events.log

kubectl -n kube-system rollout status ds/cilium


# 확인
kubectl get cm -n kube-system cilium-config -o json | grep hubble-export
cilium config view | grep hubble-export

# Verify that flow logs are stored in target files
kubectl -n kube-system exec ds/cilium -- tail -f /var/run/cilium/hubble/events.log
kubectl -n kube-system exec ds/cilium -- sh -c 'tail -f /var/run/cilium/hubble/events.log' | jq

 

✅ 실행 결과 요약

1. Hubble Export 설정 확인 성공

# ConfigMap에서 Export 관련 설정 확인
(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl get cm -n kube-system cilium-config -o json | grep hubble-export
        "hubble-export-allowlist": "",           # 허용 목록 (빈 값 = 모든 플로우 허용)
        "hubble-export-denylist": "",            # 거부 목록 (빈 값 = 차단 없음)
        "hubble-export-fieldmask": "",           # 필드 마스크 (빈 값 = 모든 필드 포함)
        "hubble-export-file-max-backups": "5",   # 최대 백업 파일 개수
        "hubble-export-file-max-size-mb": "10",  # 로그 파일 최대 크기 (10MB)
        "hubble-export-file-path": "/var/run/cilium/hubble/events.log",  # 로그 파일 경로

# Cilium CLI에서 Export 설정 확인
(⎈|HomeLab:N/A) root@k8s-ctr:~# cilium config view | grep hubble-export
hubble-export-allowlist                           # 허용 목록 (공백)
hubble-export-denylist                            # 거부 목록 (공백)  
hubble-export-fieldmask                           # 필드 마스크 (공백)
hubble-export-file-max-backups                    5     # 백업 파일 5개까지 보관
hubble-export-file-max-size-mb                    10    # 파일당 10MB 제한
hubble-export-file-path                           /var/run/cilium/hubble/events.log  # 저장 경로

2. 실시간 플로우 로깅 동작 확인

# 각 Cilium Agent에서 실시간으로 생성되는 플로우 로그 확인
# JSON 형태로 모든 네트워크 이벤트가 상세히 기록됨

주요 로깅 내용:
📋 **기본 정보**: time, uuid, verdict, node_name
🌐 **네트워크 계층**: IP 주소, 포트, 프로토콜, TCP 플래그  
🔐 **보안 정보**: Security Identity, 레이블, 네임스페이스
📊 **상세 메타데이터**: Pod 이름, Workload 정보, CGroup ID
🔍 **추적 정보**: Traffic Direction, Observation Point, Interface

실시간 이벤트 예시:
- CoreDNS 헬스체크 (SOCK 레벨 추적)
- API Server ↔ CoreDNS 통신 (L3/L4 레벨)
- TCP 연결 수립/종료 (SYN, ACK, FIN 플래그)
- Socket 레벨 번역 포인트 추적

3. Export 기능 동작 원리
💾 파일 저장 방식:

  • 경로: /var/run/cilium/hubble/events.log
  • 형식: JSON Lines (각 줄이 하나의 플로우 이벤트)
  • 순환: 10MB 도달 시 자동 로테이션
  • 보관: 최대 5개 백업 파일 유지

🔄 실시간 처리:

  • 모든 네트워크 플로우가 실시간으로 기록
  • eBPF에서 캡처한 패킷 정보를 JSON으로 변환
  • SOCK, L3_L4 레벨의 다양한 이벤트 포착
  • Security Identity 기반 정책 적용 결과 추적

📊 모니터링 활용:

  • 외부 로그 수집 시스템 연동 가능 (Fluentd, Logstash 등)
  • SIEM 도구와 통합하여 보안 분석
  • 네트워크 트래픽 패턴 분석 및 이상 탐지
  • 성능 모니터링 및 트러블슈팅 지원

기타 기능

1. 성능 최적화 (Performance Tuning)

  • 공식 문서: Hubble Export 성능 최적화

Hubble Exporter의 성능에 영향을 주는 주요 설정 옵션들:

# 허용 목록 설정 (특정 플로우만 내보내기)
--set hubble.export.static.allowList='[{"source_pod":["kube-system"]}]'

# 거부 목록 설정 (특정 플로우 제외)  
--set hubble.export.static.denyList='[{"verdict":["DROPPED"]}]'

# 필드 마스킹 (불필요한 필드 제거로 성능 향상)
--set hubble.export.static.fieldMask='flow.source,flow.destination,flow.verdict'

성능 최적화 효과:

  • 📈 디스크 사용량 감소: 필요한 플로우만 저장
  • ⚡ 처리 속도 향상: 불필요한 데이터 필터링
  • 💾 메모리 최적화: 선택적 필드 처리

2. 동적 설정 관리 (Dynamic Exporter Configuration)

  • 공식 문서: 동적 내보내기 설정
  • 실습 상태: 생략 (고급 기능)

정적 설정 vs 동적 설정 비교:

구분 정적 내보내기 동적 내보내기
필터 개수 단일 필터 세트만 가능 여러 필터 동시 적용
출력 파일 하나의 파일만 생성 필터별 개별 파일 생성
설정 변경 Pod 재시작 필요 실시간 변경 가능
복잡도 간단한 설정 고급 설정 필요

동적 내보내기의 장점:

  • 실시간 설정 변경: Cilium Pod를 재시작하지 않고도 설정 변경 가능
  • 다중 출력 파일: 용도별로 로그 파일을 분리하여 저장
  • 세밀한 제어: 각 필터를 독립적으로 관리 가능

동적 설정 활성화 방법:

# ConfigMap을 통한 동적 설정 경로 지정
--set hubble.export.static.enabled=false
--set hubble.export.dynamic.config.configMapName=hubble-flowlogs-config
--set hubble.export.dynamic.config.createConfigMap=true

3. 현재 실습 환경에서 사용한 설정

# 실습에서 적용된 기본 설정
hubble-export-allowlist: ""              # 모든 플로우 허용 (필터링 없음)
hubble-export-denylist: ""               # 차단할 플로우 없음  
hubble-export-fieldmask: ""              # 모든 필드 포함
hubble-export-file-max-backups: 5        # 최대 5개 백업 파일 보관
hubble-export-file-max-size-mb: 10       # 파일당 최대 10MB 크기 제한

운영 환경 권장 설정:

# 실제 운영 환경에서 권장하는 최적화된 설정
--set hubble.export.static.allowList='[{"source_namespace":["default","production"]}]'
--set hubble.export.static.denyList='[{"verdict":["TRACED"],"source_pod":["kube-system"]}]'  
--set hubble.export.static.fieldMask='flow.time,flow.verdict,flow.source,flow.destination,flow.l4'
--set hubble.export.static.fileMaxSizeMb=50      # 더 큰 파일 크기
--set hubble.export.static.fileMaxBackups=10     # 더 많은 백업 파일

설정별 상세 설명:

  • allowList: 지정된 조건에 맞는 플로우만 로그에 기록
  • denyList: 지정된 조건에 맞는 플로우는 로그에서 제외
  • fieldMask: 로그에 포함할 필드만 선택하여 파일 크기 최적화

Hubble Exporter와 Prometheus & Grafana 연동

Prometheus & Grafana에 대한 설명은 이전 스터디 글을 참고하시기 바랍니다!
링크 - https://devlos.tistory.com/63

샘플 애플리케이션 배포 및 확인

# 샘플 애플리케이션 배포
cat << EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: webpod
spec:
  replicas: 2
  selector:
    matchLabels:
      app: webpod
  template:
    metadata:
      labels:
        app: webpod
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - sample-app
            topologyKey: "kubernetes.io/hostname"
      containers:
      - name: webpod
        image: traefik/whoami
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: webpod
  labels:
    app: webpod
spec:
  selector:
    app: webpod
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  type: ClusterIP
EOF


# k8s-ctr 노드에 curl-pod 파드 배포
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: curl-pod
  labels:
    app: curl
spec:
  nodeName: k8s-ctr
  containers:
  - name: curl
    image: nicolaka/netshoot
    command: ["tail"]
    args: ["-f", "/dev/null"]
  terminationGracePeriodSeconds: 0
EOF

# 배포 확인
kubectl get deploy,svc,ep webpod -owide
kubectl get endpointslices -l app=webpod
kubectl get ciliumendpoints
kubectl exec -it -n kube-system ds/cilium -c cilium-agent -- cilium-dbg endpoint list

# 통신 확인
kubectl exec -it curl-pod -- curl webpod | grep Hostname
kubectl exec -it curl-pod -- sh -c 'while true; do curl -s webpod | grep Hostname; sleep 1; done'

✅ 실행 결과 요약

(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl get deploy,svc,ep webpod -owide
Warning: v1 Endpoints is deprecated in v1.33+; use discovery.k8s.io/v1 EndpointSlice
NAME                     READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES           SELECTOR
deployment.apps/webpod   2/2     2            2           54s   webpod       traefik/whoami   app=webpod

NAME             TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE   SELECTOR
service/webpod   ClusterIP   10.96.166.184   <none>        80/TCP    54s   app=webpod

NAME               ENDPOINTS                         AGE
endpoints/webpod   172.20.1.179:80,172.20.2.207:80   54s

(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl get endpointslices -l app=webpod
NAME           ADDRESSTYPE   PORTS   ENDPOINTS                   AGE
webpod-97xpr   IPv4          80      172.20.1.179,172.20.2.207   58s

(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl get ciliumendpoints
NAME                      SECURITY IDENTITY   ENDPOINT STATE   IPV4           IPV6
curl-pod                  10292               ready            172.20.0.241   
webpod-697b545f57-b2xst   2460                ready            172.20.2.207   
webpod-697b545f57-ntmqj   2460                ready            172.20.1.179   

(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl exec -it -n kube-system ds/cilium -c cilium-agent -- cilium-dbg endpoint list
ENDPOINT   POLICY (ingress)   POLICY (egress)   IDENTITY   LABELS (source:key[=value])                                                  IPv6   IPv4           STATUS   
           ENFORCEMENT        ENFORCEMENT                                                                                                                     
703        Disabled           Disabled          1          k8s:node-role.kubernetes.io/control-plane                                                          ready   
                                                           k8s:node.kubernetes.io/exclude-from-external-load-balancers                                                
                                                           reserved:host                                                                                              
1174       Disabled           Disabled          5694       k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=kube-system          172.20.0.107   ready   
                                                           k8s:io.cilium.k8s.policy.cluster=default                                                                   
                                                           k8s:io.cilium.k8s.policy.serviceaccount=coredns                                                            
                                                           k8s:io.kubernetes.pod.namespace=kube-system                                                                
                                                           k8s:k8s-app=kube-dns                                                                                       
1475       Disabled           Disabled          10292      k8s:app=curl                                                                        172.20.0.241   ready   
                                                           k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=default                                     
                                                           k8s:io.cilium.k8s.policy.cluster=default                                                                   
                                                           k8s:io.cilium.k8s.policy.serviceaccount=default                                                            
                                                           k8s:io.kubernetes.pod.namespace=default                                                                    
2609       Disabled           Disabled          5694       k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=kube-system          172.20.0.51    ready   
                                                           k8s:io.cilium.k8s.policy.cluster=default                                                                   
                                                           k8s:io.cilium.k8s.policy.serviceaccount=coredns                                                            
                                                           k8s:io.kubernetes.pod.namespace=kube-system                                                                
                                                           k8s:k8s-app=kube-dns                                                                                       
(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl exec -it curl-pod -- curl webpod | grep Hostname
Hostname: webpod-697b545f57-b2xst

(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl exec -it curl-pod -- sh -c 'while true; do curl -s webpod | grep Hostname; sleep 1; done'
Hostname: webpod-697b545f57-ntmqj
Hostname: webpod-697b545f57-ntmqj
...

Prometheus & Grafana 설치
참고: Docs

Prometheus와 Grafana를 단일 배포로 포함하는 예제 배포입니다. - Youtube

  • Grafana: Cilium 대시보드가 미리 로드된 시각화 대시보드입니다.
  • Prometheus: 시계열 데이터베이스 및 모니터링 시스템입니다.
  • 이 Prometheus와 Grafana 예제 배포는 Cilium 및 Hubble 메트릭을 자동으로 수집합니다.
kubectl apply -f https://raw.githubusercontent.com/cilium/cilium/1.17.6/examples/kubernetes/addons/prometheus/monitoring-example.yaml

kubectl get deploy,pod,svc,ep -n cilium-monitoring
kubectl get cm -n cilium-monitoring

# 프로메테우스 서버 설정
kc describe cm -n cilium-monitoring prometheus

# 그라파나 서버 설정
kc describe cm -n cilium-monitoring grafana-config

# 그파라나 대시보드들 주입을 위한 설정
kc describe cm -n cilium-monitoring grafana-cilium-dashboard
kc describe cm -n cilium-monitoring grafana-hubble-dashboard

✅ 실행 결과 요약

1. Prometheus & Grafana 모니터링 스택 배포 성공

# 모니터링 관련 모든 리소스가 cilium-monitoring 네임스페이스에 배포됨
(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl get deploy,pod,svc,ep -n cilium-monitoring
NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/grafana      1/1     1            1           2m45s    # Grafana 웹 인터페이스
deployment.apps/prometheus   1/1     1            1           2m45s    # Prometheus 시계열 DB

NAME                             READY   STATUS    RESTARTS   AGE
pod/grafana-59957b9549-x7k2h     1/1     Running   0          2m45s    # Grafana Pod 정상 동작
pod/prometheus-7c8c9cbd7-mp8vz   1/1     Running   0          2m45s    # Prometheus Pod 정상 동작

NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
service/grafana      ClusterIP   10.96.89.156    <none>        3000/TCP   2m45s  # Grafana 웹 서비스
service/prometheus   ClusterIP   10.96.143.199   <none>        9090/TCP   2m45s  # Prometheus API 서비스

NAME                   ENDPOINTS          AGE
endpoints/grafana      172.20.1.45:3000   2m45s  # Grafana 엔드포인트
endpoints/prometheus   172.20.2.97:9090   2m45s  # Prometheus 엔드포인트

2. ConfigMap 구성 현황

# 총 4개의 ConfigMap으로 모니터링 설정 관리
(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl get cm -n cilium-monitoring
NAME                       DATA   AGE
grafana-cilium-dashboard   1      3m12s    # Cilium 대시보드 JSON 설정
grafana-config             1      3m12s    # Grafana 기본 설정 (데이터소스, 대시보드 경로)
grafana-hubble-dashboard   1      3m12s    # Hubble 대시보드 JSON 설정  
prometheus                 1      3m12s    # Prometheus 스크래핑 설정

3. Prometheus 설정 분석

  • 스크래핑 대상: Cilium Agent (9965), Cilium Operator (9963), Hubble (9965) 메트릭
  • 수집 간격: 기본 15초마다 메트릭 수집
  • 서비스 디스커버리: Kubernetes API를 통한 자동 타겟 발견
  • 레이블 설정: Pod, 네임스페이스, 노드별 레이블 자동 할당

4. Grafana 설정 분석

  • 데이터소스: Prometheus (http://prometheus:9090) 자동 연결
  • 대시보드: Cilium 및 Hubble 대시보드 사전 구성
  • 프로비저닝: 시작 시 자동으로 대시보드 로드
  • 접속 포트: 3000번 포트로 웹 인터페이스 제공

5. 주요 대시보드 구성

Cilium 대시보드:

  • 📊 네트워크 정책: 허용/차단된 연결 통계
  • 🔄 로드밸런싱: 서비스별 트래픽 분산 현황
  • 🛡️ 보안 상태: Security Identity별 정책 적용 상태
  • 📈 성능 메트릭: BPF 맵 사용률, 엔드포인트 상태

Hubble 대시보드:

  • 🌐 HTTP 트래픽: 요청/응답 통계, 레이턴시 (p50, p99)
  • 🔍 DNS 모니터링: 쿼리/응답 대칭성, 오류율, Top 10 쿼리
  • 📊 프로토콜 분석: HTTP/gRPC 프로토콜 사용 분포
  • ⚠️ 오류 추적: DNS 오류, 응답 누락, 문제가 있는 Pod 식별

아키텍처 흐름:

Grafana (:3000) ← Prometheus (:9090) ← Cilium/Hubble 메트릭 (:9965, :9963)
     ↓                    ↓                            ↓
웹 대시보드          시계열 데이터베이스              실시간 메트릭 수집
시각화 인터페이스     메트릭 저장 및 쿼리              eBPF 기반 관측

준비 완료 상태:

  • ✅ Prometheus: Cilium/Hubble 메트릭 자동 수집 중
  • ✅ Grafana: 사전 구성된 대시보드로 즉시 모니터링 가능
  • ✅ ConfigMap: 모든 설정이 분리되어 관리 용이
  • ✅ 서비스: ClusterIP로 클러스터 내부 접근 준비

Cilium과 Hubble metrics enabled 설정

참고 - https://docs.cilium.io/en/stable/observability/grafana/#deploy-cilium-and-hubble-with-metrics-enabled

 

  • Cilium, Hubble, and Cilium Operator는 기본적으로 메트릭을 노출하지 않습니다.
  • 이러한 서비스에 대한 메트릭을 활성화하면 이러한 구성 요소가 실행 중인 클러스터의 모든 노드에 각각 9962, 9965, 9963 포트가 열립니다.
  • Cilium, Hubble, and Cilium Operator의 메트릭은 모두 다음 헬름 값으로 서로 독립적으로 활성화할 수 있습니다
    • prometheus.enabled=true: Enables metrics for cilium-agent.
    • operator.prometheus.enabled=true: Enables metrics for cilium-operator.
    • hubble.metrics.enabled: Enables the provided list of Hubble metrics.
      • For Hubble metrics to work, Hubble itself needs to be enabled with hubble.enabled=true.
      • See Hubble exported metrics for the list of available Hubble metrics.
    • → Refer to Monitoring & Metrics for more details about the individual metrics.*

설정

# 이미 설정되어 있음
helm install cilium cilium/cilium --version 1.17.6 \
   --namespace kube-system \
   --set prometheus.enabled=true \
   --set operator.prometheus.enabled=true \
   --set hubble.enabled=true \
   --set hubble.metrics.enableOpenMetrics=true \
   --set hubble.metrics.enabled="{dns,drop,tcp,flow,port-distribution,icmp,httpV2:exemplars=true;labelsContext=source_ip\,source_namespace\,source_workload\,destination_ip\,destination_namespace\,destination_workload\,traffic_direction}"

# 호스트에 포트 정보 확인
ss -tnlp | grep -E '9962|9963|9965'

for i in w1 w2 ; do echo ">> node : k8s-$i <<"; sshpass -p 'vagrant' ssh vagrant@k8s-$i sudo ss -tnlp | grep -E '9962|9963|9965' ; echo; done

# 모니터링 네암스페이스의 서비스들 확인
kubectl get svc -n cilium-monitoring

# NodePort 설정
kubectl patch svc -n cilium-monitoring prometheus -p '{"spec": {"type": "NodePort", "ports": [{"port": 9090, "targetPort": 9090, "nodePort": 30001}]}}'
kubectl patch svc -n cilium-monitoring grafana -p '{"spec": {"type": "NodePort", "ports": [{"port": 3000, "targetPort": 3000, "nodePort": 30002}]}}'

# 확인
kubectl get svc -n cilium-monitoring

# 접속 주소 확인
echo "http://192.168.10.100:30001"  # prometheus
echo "http://192.168.10.100:30002"  # grafana

✅ 실행 결과 요약

# 각 노드별 익스포터 포트 구성 확인
# 오퍼레이터 레플리카가 1이라 Control Plane에 만 배포되어 있음
(⎈|HomeLab:N/A) root@k8s-ctr:~# ss -tnlp | grep -E '9962|9963|9965'
LISTEN 0      4096                *:9962             *:*    users:(("cilium-agent",pid=9298,fd=7)) # cilium 메트릭        
LISTEN 0      4096                *:9963             *:*    users:(("cilium-operator",pid=5512,fd=7)) # cilium-opeator 메트릭             
LISTEN 0      4096                *:9965             *:*    users:(("cilium-agent",pid=9298,fd=42)) # hubble 메트릭          

(⎈|HomeLab:N/A) root@k8s-ctr:~# for i in w1 w2 ; do echo ">> node : k8s-$i <<"; sshpass -p 'vagrant' ssh vagrant@k8s-$i sudo ss -tnlp | grep -E '9962|9963|9965' ; echo; done
>> node : k8s-w1 <<
LISTEN 0      4096               *:9965             *:*    users:(("cilium-agent",pid=7154,fd=48)) # hubble 메트릭               
LISTEN 0      4096               *:9962             *:*    users:(("cilium-agent",pid=7154,fd=7)) # cilium 메트릭                  

>> node : k8s-w2 <<
LISTEN 0      4096               *:9965             *:*    users:(("cilium-agent",pid=6930,fd=32)) # hubble 메트릭              
LISTEN 0      4096               *:9962             *:*    users:(("cilium-agent",pid=6930,fd=7))  # cilium 메트릭     

(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl get svc -n cilium-monitoring
NAME         TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE
grafana      ClusterIP   10.96.103.7   <none>        3000/TCP   10m
prometheus   ClusterIP   10.96.210.3   <none>        9090/TCP   10m

(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl patch svc -n cilium-monitoring prometheus -p '{"spec": {"type": "NodePort", "ports": [{"port": 9090, "targetPort": 9090, "nodePort": 30001}]}}'
service/prometheus patched

(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl patch svc -n cilium-monitoring grafana -p '{"spec": {"type": "NodePort", "ports": [{"port": 3000, "targetPort": 3000, "nodePort": 30002}]}}'
service/grafana patched

(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl get svc -n cilium-monitoring
NAME         TYPE       CLUSTER-IP    EXTERNAL-IP   PORT(S)          AGE
grafana      NodePort   10.96.103.7   <none>        3000:30002/TCP   10m
prometheus   NodePort   10.96.210.3   <none>        9090:30001/TCP   10m

Prometheus: http://192.168.10.100:30001 접속

Prometheus > Target 확인

Prometheus > 쿼리 예제(hubble_drop_total)

Grafana: http://192.168.10.100:30002 접속

Grafana > Cilium Metrics


Grafana > Operator


Grafana > Hubble


Grafana Hubble L7 HTTPS MEtrics By Workload

Cilium Metrics 설정 및 수집 방법 - Docs

  • Cilium metrics은 Cilium 자체의 상태, 즉 Cilium Agent, Cilium envoy, Cilium operator 프로세스에 대한 인사이트를 제공합니다.
  • 프로메테우스 메트릭이 활성화된 Cilium을 실행하려면 prometheus.enabled=true Helm 값 집합을 사용하여 Cilium을 배포하세요.
  • Cilium metrics are exported under the cilium_ Prometheus namespace.
  • Envoy metrics are exported under the envoy_ Prometheus namespace, of which the Cilium-defined metrics are exported under the envoy_cilium_ namespace.
  • Kubernetes에서 실행 및 수집할 때 포드 이름과 네임스페이스로 태그가 지정됩니다.

Layer 7 Protocol Visibility 실습

  • Monitoring Datapath State는 datapath state에 대한 성찰을 제공하지만, 기본적으로 L3/L4 패킷 이벤트에 대한 가시성만 제공합니다.
  • L7 프로토콜 가시성을 원한다면 L7 Cilium Network Policies 을 사용할 수 있습니다(레이어 7 예제 참조).
  • L7 트래픽에 대한 가시성을 활성화하려면 L7 규칙을 지정하는 CiliumNetworkPolicy를 만드세요.
  • CiliumNetworkPolicy에서 L7 규칙과 일치하는 트래픽 흐름이 Cilium에 표시되므로 최종 사용자에게 노출될 수 있습니다.
  • L7 네트워크 정책은 가시성을 가능하게 할 뿐만 아니라 포드에 들어오고 나가는 트래픽을 제한한다는 점을 기억하는 것이 중요합니다.

실습

# 반복 접속 해둔 상태
kubectl exec -it curl-pod -- sh -c 'while true; do curl -s webpod | grep Hostname; sleep 1; done'


# default 네임스페이스에 있는 Pod들의 egress(출방향) 트래픽을 제어하며, L7 HTTP 및 DNS 트래픽에 대한 가시성과 제어를 설정
## method/path 기반 필터링은 안 하지만, HTTP 요청 정보는 Envoy를 통해 기록/관찰됨
## cilium-envoy를 경유하게 됨 (DNS + HTTP 모두 L7 처리 대상)
## 이 정책이 적용되면, 명시된 egress 외의 모든 egress 트래픽은 차단됩니다 (Cilium 정책은 default-deny 모델임)
cat <<EOF | kubectl apply -f -
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
  name: "l7-visibility"
spec:
  endpointSelector:
    matchLabels:
      "k8s:io.kubernetes.pod.namespace": default  # default 네임스페이스 안의 모든 Pod에 대해 egress 정책이 적용
  egress:
  - toPorts: # 첫번째 정책!
    - ports:
      - port: "53"
        protocol: ANY  # TCP, UDP 둘 다 허용
      rules:
        dns:
        - matchPattern: "*"  # 모든 도메인 조회 허용, L7 가시성 활성화
  - toEndpoints:
    - matchLabels:
        "k8s:io.kubernetes.pod.namespace": default
    toPorts: # 두번째 정책!
    - ports:
      - port: "80"  # default 다른 파드의 HTTP TCP 80 요청 허용
        protocol: TCP
      - port: "8080"  # default 다른 파드의 HTTP TCP 8080 요청 허용
        protocol: TCP
      rules:
        http: [{}]  # 모든 HTTP 요청을 허용, L7 가시성 활성화
EOF

kubectl get cnp -o yaml


# 호출 확인 : cilium-envoy 경유 확인
kubectl exec -it curl-pod -- curl -s webpod


# 가시성 확인
hubble observe -f -t l7 -o compact
...
혹은 cilium nonitor ~

✅ 실행 결과 요약

1. L7 가시성 네트워크 정책 적용 성공

# CiliumNetworkPolicy 생성 및 검증 완료
(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl apply -f -
ciliumnetworkpolicy.cilium.io/l7-visibility created

# 정책 상태 확인
Status:
  Conditions:
    Last Transition Time: 2025-07-25T19:47:41Z
    Message:              Policy validation succeeded
    Status:               True
    Type:                 Valid

2. 정책 세부 규칙 분석

(⎈|HomeLab:N/A) root@k8s-ctr:~# cat <<EOF | kubectl apply -f -
# 적용된 정책 구조
endpointSelector:
  matchLabels:
    k8s:io.kubernetes.pod.namespace: default  # default 네임스페이스 모든 Pod 대상

egress:
  # DNS 트래픽 허용 (L7 가시성 활성화)
  - toPorts:
    - ports: [{"port": "53", "protocol": "ANY"}]  # TCP/UDP 모두 허용
      rules:
        dns: [{"matchPattern": "*"}]  # 모든 도메인 조회 허용

  # HTTP 트래픽 허용 (L7 가시성 활성화)  
  - toEndpoints:
    - matchLabels: {"k8s:io.kubernetes.pod.namespace": "default"}
    toPorts:
    - ports: [{"port": "80"}, {"port": "8080"}]  # HTTP 포트들
      rules:
        http: [{}]  # 모든 HTTP 요청 허용하되 가시성 확보

3. L7 Proxy 경유 확인

# HTTP 요청이 Envoy 프록시를 경유함을 확인
(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl exec -it curl-pod -- curl -s webpod
Hostname: webpod-697b545f57-b2xst
...
# Envoy 관련 헤더 추가됨
X-Envoy-Expected-Rq-Timeout-Ms: 3600000
X-Envoy-Internal: true
X-Forwarded-Proto: http
X-Request-Id: 6fe4abf7-aafb-48f8-9837-d597c3d806ff

4. L7 트래픽 실시간 가시성 확보

# DNS 및 HTTP 트래픽의 상세한 L7 정보 관측 가능
Jul 25 19:48:16.851: default/curl-pod:38330 (ID:10292) 
                   → kube-system/coredns-674b8bbfcf-p8kth:53 (ID:5694) 
                   dns-request proxy FORWARDED 
                   (DNS Query webpod.default.svc.cluster.local. A)

Jul 25 19:48:16.852: default/curl-pod:38330 (ID:10292) 
                   ← kube-system/coredns-674b8bbfcf-p8kth:53 (ID:5694) 
                   dns-response proxy FORWARDED 
                   (DNS Answer "10.96.166.184" TTL: 30)

Jul 25 19:48:16.855: default/curl-pod:52252 (ID:10292) 
                   → default/webpod-697b545f57-b2xst:80 (ID:2460) 
                   http-request FORWARDED 
                   (HTTP/1.1 GET http://webpod/)

Jul 25 19:48:16.859: default/curl-pod:52252 (ID:10292) 
                   ← default/webpod-697b545f57-b2xst:80 (ID:2460) 
                   http-response FORWARDED 
                   (HTTP/1.1 200 4ms)

5. L7 가시성의 핵심 기능

DNS 레벨 가시성:

  • 🔍 쿼리 추적: 도메인 조회 패턴 분석 (A, AAAA 레코드)
  • ⏱️ TTL 모니터링: DNS 캐시 수명 추적 (TTL: 30초)
  • 📊 응답 분석: 성공/실패 DNS 응답 구분

HTTP 레벨 가시성:

  • 🌐 요청/응답 쌍: HTTP 메서드, URL, 상태코드 추적
  • ⏱️ 레이턴시 측정: 응답 시간 정밀 측정 (2-4ms)
  • 🔗 연결 추적: Request ID를 통한 요청 상관관계 분석
  • 📋 헤더 분석: Envoy 프록시 메타데이터 포함

L7 정책의 중요한 특징:

  • ✅ Zero Trust: 명시되지 않은 egress 트래픽은 모두 차단
  • ✅ 프록시 경유: 모든 L7 트래픽이 cilium-envoy를 통과
  • ✅ 실시간 관측: DNS/HTTP 트랜잭션의 완전한 가시성
  • ✅ 성능 측정: 마이크로초 단위 레이턴시 측정
  • ✅ 보안 강화: L7 레벨에서의 세밀한 접근 제어

L3/L4 vs L7 가시성 비교:

구분 L3/L4 모니터링 L7 가시성
DNS IP:53 연결만 보임 도메인명, 쿼리타입, TTL 상세
HTTP IP:80 연결만 보임 URL, 메서드, 상태코드, 헤더
성능 연결 수립/종료 시간 응답 시간, 처리 지연 상세
보안 IP/포트 기반 제어 애플리케이션 레벨 제어

Security Implications & 실습

  • 레이어 7 트래픽 모니터링에는 사용자 이름, 비밀번호, 쿼리 매개변수, API 키 등 잠재적으로 민감한 정보를 처리하기 위한 보안 고려 사항이 포함됩니다.
  • By default, Hubble does not redact potentially sensitive information present in Layer 7 Hubble Flows. ⇒ *허블은 민감정보 직접 편집 X***
  • 로그에 찍히는 민감정보를 Cilium에서 가릴 수 있는 기능을 제공

참고 - https://docs.cilium.io/en/stable/observability/visibility/#security-implications

#요청 모니터링
hubble observe -f -t l7

#요청에 민감정보 포함
kubectl exec -it curl-pod -- sh -c 'curl -s webpod/?user_id=1234'
kubectl exec -it curl-pod -- sh -c 'curl -s webpod/?user_id=1234'


# 민감정보 미출력 설정
helm upgrade cilium cilium/cilium --namespace kube-system --reuse-values \
  --set extraArgs="{--hubble-redact-enabled,--hubble-redact-http-urlquery}"

#
kubectl exec -it curl-pod -- sh -c 'curl -s webpod/?user_id=1234'

#
hubble observe -f -t l7

✅ 실행 결과 요약

(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl exec -it curl-pod -- sh -c 'curl -s webpod/?user_id=1234'
Hostname: webpod-697b545f57-b2xst
IP: 127.0.0.1
IP: ::1
IP: 172.20.2.207
IP: fe80::60b4:70ff:fedb:6d
RemoteAddr: 172.20.0.241:49830
GET /?user_id=1234 HTTP/1.1
Host: webpod
User-Agent: curl/8.14.1
Accept: */*
X-Envoy-Expected-Rq-Timeout-Ms: 3600000
X-Envoy-Internal: true
X-Forwarded-Proto: http
X-Request-Id: 19917c75-4c30-47b1-9b03-4a555857109b

# 민감정보 그대로 노출됨
(⎈|HomeLab:N/A) root@k8s-ctr:~# hubble observe -f -t l7
Jul 25 19:53:37.768: default/curl-pod:50310 (ID:10292) -> kube-system/coredns-674b8bbfcf-2sbw2:53 (ID:5694) dns-request proxy FORWARDED (DNS Query webpod.default.svc.cluster.local. AAAA)
Jul 25 19:53:37.768: default/curl-pod:50310 (ID:10292) -> kube-system/coredns-674b8bbfcf-2sbw2:53 (ID:5694) dns-request proxy FORWARDED (DNS Query webpod.default.svc.cluster.local. A)
Jul 25 19:53:37.769: default/curl-pod:50310 (ID:10292) <- kube-system/coredns-674b8bbfcf-2sbw2:53 (ID:5694) dns-response proxy FORWARDED (DNS Answer  TTL: 4294967295 (Proxy webpod.default.svc.cluster.local. AAAA))
Jul 25 19:53:37.769: default/curl-pod:50310 (ID:10292) <- kube-system/coredns-674b8bbfcf-2sbw2:53 (ID:5694) dns-response proxy FORWARDED (DNS Answer "10.96.166.184" TTL: 30 (Proxy webpod.default.svc.cluster.local. A))
Jul 25 19:53:37.771: default/curl-pod:49830 (ID:10292) -> default/webpod-697b545f57-b2xst:80 (ID:2460) http-request FORWARDED (HTTP/1.1 GET http://webpod/?user_id=1234)
Jul 25 19:53:37.774: default/curl-pod:49830 (ID:10292) <- default/webpod-697b545f57-b2xst:80 (ID:2460) http-response FORWARDED (HTTP/1.1 200 3ms (GET http://webpod/?user_id=1234))

# 민감정보 미출력 설정
(⎈|HomeLab:N/A) root@k8s-ctr:~# helm upgrade cilium cilium/cilium --namespace kube-system --reuse-values \
  --set extraArgs="{--hubble-redact-enabled,--hubble-redact-http-urlquery}"
Release "cilium" has been upgraded. Happy Helming!
NAME: cilium
LAST DEPLOYED: Sat Jul 26 04:55:45 2025
NAMESPACE: kube-system
STATUS: deployed
REVISION: 3
TEST SUITE: None
NOTES:
You have successfully installed Cilium with Hubble Relay and Hubble UI.

Your release version is 1.17.6.

For any further help, visit https://docs.cilium.io/en/v1.17/gettinghelp

# 재요청
(⎈|HomeLab:N/A) root@k8s-ctr:~# kubectl exec -it curl-pod -- sh -c 'curl -s webpod/?user_id=1234'
Hostname: webpod-697b545f57-b2xst
IP: 127.0.0.1
IP: ::1
IP: 172.20.2.207
IP: fe80::60b4:70ff:fedb:6d
RemoteAddr: 172.20.0.241:52422
GET /?user_id=1234 HTTP/1.1
Host: webpod
User-Agent: curl/8.14.1
Accept: */*
X-Envoy-Expected-Rq-Timeout-Ms: 3600000
X-Envoy-Internal: true
X-Forwarded-Proto: http
X-Request-Id: 3006845a-138e-41a2-8021-d1ff0eb87452

# 민감정보 마스킹 확인
(⎈|HomeLab:N/A) root@k8s-ctr:~# hubble observe -f -t l7
Jul 25 19:56:27.558: default/curl-pod:55694 (ID:10292) -> kube-system/coredns-674b8bbfcf-p8kth:53 (ID:5694) dns-request proxy FORWARDED (DNS Query webpod.default.svc.cluster.local. A)
Jul 25 19:56:27.558: default/curl-pod:55694 (ID:10292) -> kube-system/coredns-674b8bbfcf-p8kth:53 (ID:5694) dns-request proxy FORWARDED (DNS Query webpod.default.svc.cluster.local. AAAA)
Jul 25 19:56:27.560: default/curl-pod:55694 (ID:10292) <- kube-system/coredns-674b8bbfcf-p8kth:53 (ID:5694) dns-response proxy FORWARDED (DNS Answer "10.96.166.184" TTL: 30 (Proxy webpod.default.svc.cluster.local. A))
Jul 25 19:56:27.560: default/curl-pod:55694 (ID:10292) <- kube-system/coredns-674b8bbfcf-p8kth:53 (ID:5694) dns-response proxy FORWARDED (DNS Answer  TTL: 4294967295 (Proxy webpod.default.svc.cluster.local. AAAA))
Jul 25 19:56:27.568: default/curl-pod:52422 (ID:10292) -> default/webpod-697b545f57-b2xst:80 (ID:2460) http-request FORWARDED (HTTP/1.1 GET http://webpod/)
Jul 25 19:56:27.572: default/curl-pod:52422 (ID:10292) <- default/webpod-697b545f57-b2xst:80 (ID:2460) http-response FORWARDED (HTTP/1.1 200 4ms (GET http://webpod/))

Pwru 도구

  • 패킷 추적 도구: 리눅스 커널 네트워킹 스택에서 패킷의 경로를 실시간으로 추적
  • eBPF 기반: 커널 수정 없이 안전하게 패킷 흐름을 관측
  • 네트워킹 디버깅: 패킷 드롭, 지연, 라우팅 문제 등을 세밀하게 분석
  • Cilium 생태계: Hubble과 함께 사용하여 완전한 네트워크 가시성 제공

참고

  • Packet, where are you? eBPF-based Linux kernel networking debugger : https://github.com/cilium/pwru
  • 참고: https://nuguni.tistory.com/97
  • 참고: https://cilium.io/blog/2023/03/22/packet-where-are-you/

주요 기능:

  • 🔍 패킷 추적: 특정 패킷이 커널의 어느 지점을 통과하는지 추적
  • 📊 성능 분석: 각 커널 함수에서의 처리 시간 측정
  • 🚫 드롭 분석: 패킷이 어디서 왜 드롭되는지 정확한 원인 파악
  • 🔧 실시간 디버깅: 라이브 환경에서 네트워크 문제 즉시 진단

마치며

이번 2주차에서는 Cilium과 Hubble을 통한 네트워크 관측성(Observability) 에 대해 깊이 있게 학습해보았습니다. Hubble의 설치부터 시작해서 실시간 네트워크 모니터링, L7 프로토콜 가시성, 그리고 Prometheus와 Grafana를 활용한 메트릭 수집까지 전체적인 관측 스택을 구축해볼 수 있었습니다.

 

특히 제가 너무나도 좋아하는 Star Wars 데모를 통한 CiliumNetworkPolicy 실습과 L7 가시성 확보 과정에서, 단순히 네트워크 연결 여부만 확인하던 기존 방식에서 벗어나 HTTP 요청/응답의 상세 내용, DNS 쿼리 패턴, 심지어 민감 정보 마스킹까지 다룰 수 있다는 점이 인상깊었습니다.

실습을 통해 eBPF와 Envoy 프록시가 어떻게 협력하여 마이크로서비스 환경에서의 완전한 네트워크 가시성을 제공하는지 직접 체험할 수 있었고, 이는 운영 환경에서 네트워크 문제를 해결하는 데 매우 유용한 도구가 될 것 같습니다.

 

앞으로 실무에서 서비스 메시나 마이크로서비스 아키텍처를 다룰 때, 이번에 학습한 Hubble의 관측 기능들을 적극 활용해보고 싶습니다. 특히 성능 최적화나 보안 이슈 해결 시 L7 레벨의 상세한 트래픽 분석이 큰 도움이 될 것 같다는 생각이 듭니다.

긴 글 읽어주셔서 감사합니다 :)

반응형

'클라우드 컴퓨팅 & NoSQL > [Cilium Study] 실리움 스터디' 카테고리의 다른 글

[6주차 - Cilium 스터디] Cilium ServiceMesh (25.08.17)  (0) 2025.08.23
[5주차 - Cilium 스터디] BGP Control Plane & ClusterMesh (25.08.10)  (4) 2025.08.16
[4주차 - Cilium 스터디] Networking - 노드에 파드들간 통신 2 & K8S 외부 노출 (25.08.03)  (4) 2025.08.08
[3주차 - Cilium 스터디] Networking (25.07.27)  (0) 2025.08.02
[1주차 - Cilium 스터디] Cilium 이란? (25.07.13)  (2) 2025.07.18
    devlos
    devlos
    안녕하세요, Devlos 입니다. 새로 공부 중인 지식들을 공유하고, 명확히 이해하고자 블로그를 개설했습니다 :) 여러 DEVELOPER 분들과 자유롭게 지식을 공유하고 싶어요! 방문해 주셔서 감사합니다 😀 - DEVLOS -

    티스토리툴바