Post

Cilium 8์ฃผ์ฐจ ์ •๋ฆฌ

๐Ÿ”ง ์‹ค์Šต ํ™˜๊ฒฝ ๊ตฌ์„ฑ

1. Vagrantfile ๋‹ค์šด๋กœ๋“œ ๋ฐ ๊ฐ€์ƒ๋จธ์‹  ๊ตฌ์„ฑ

1
2
curl -O https://raw.githubusercontent.com/gasida/vagrant-lab/refs/heads/main/cilium-study/8w/Vagrantfile
vagrant up

2. VM ๋ถ€ํŒ… ํƒ€์ž„์•„์›ƒ ์˜ค๋ฅ˜ ํ•ด๊ฒฐ

(1) vagrant up ์‹คํ–‰ ์ค‘ ํ•˜๊ธฐ ์˜ค๋ฅ˜ ๋ฐœ์ƒ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
....
Timed out while waiting for the machine to boot. This means that
Vagrant was unable to communicate with the guest machine within
the configured ("config.vm.boot_timeout" value) time period.

If you look above, you should be able to see the error(s) that
Vagrant had when attempting to connect to the machine. These errors
are usually good hints as to what may be wrong.

If you're using a custom box, make sure that networking is properly
working and you're able to connect to the machine. It is a common
problem that networking isn't setup properly in these boxes.
Verify that authentication configurations are also setup properly,
as well.

If the box appears to be booting properly, you may want to increase
the timeout ("config.vm.boot_timeout") value.

(2) Vagrantfile ์ˆ˜์ •

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# Variables
K8SV = '1.33.4-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.18.1' # 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 = "202508.03.0"

Vagrant.configure("2") do |config|
  # ์ „์—ญ ์„ค์ •
  config.vm.boot_timeout = 600  # 10๋ถ„์œผ๋กœ ์ฆ๊ฐ€
  config.vm.graceful_halt_timeout = 60
  
  #-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"]
      vb.customize ["modifyvm", :id, "--nicpromisc2", "allow-all"]
      vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
      vb.customize ["modifyvm", :id, "--natdnsproxy1", "on"]
      vb.name = "k8s-ctr"
      vb.cpus = 4
      vb.memory = 3072  # 3GB๋กœ ์ฆ๊ฐ€
      vb.linked_clone = true
    end
    
    subconfig.vm.host_name = "k8s-ctr"
    subconfig.vm.network "private_network", ip: "192.168.10.100"
    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: "https://raw.githubusercontent.com/gasida/vagrant-lab/refs/heads/main/cilium-study/8w/init_cfg.sh", args: [ K8SV, CONTAINERDV ]
    subconfig.vm.provision "shell", path: "https://raw.githubusercontent.com/gasida/vagrant-lab/refs/heads/main/cilium-study/8w/k8s-ctr.sh", args: [ N, CILIUMV, K8SV ]
  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.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
        vb.customize ["modifyvm", :id, "--natdnsproxy1", "on"]
        vb.name = "k8s-w#{i}"
        vb.cpus = 4
        vb.memory = 2560  # 2.5GB๋กœ ์ฆ๊ฐ€
        vb.linked_clone = true
      end
      
      subconfig.vm.host_name = "k8s-w#{i}"
      subconfig.vm.network "private_network", ip: "192.168.10.10#{i}"
      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: "https://raw.githubusercontent.com/gasida/vagrant-lab/refs/heads/main/cilium-study/8w/init_cfg.sh", args: [ K8SV, CONTAINERDV ]
      subconfig.vm.provision "shell", path: "https://raw.githubusercontent.com/gasida/vagrant-lab/refs/heads/main/cilium-study/8w/k8s-w.sh"
    end
  end
end
  • config.vm.boot_timeout = 600 (10๋ถ„)์œผ๋กœ ์ฆ๊ฐ€
  • config.vm.graceful_halt_timeout = 60 ์ถ”๊ฐ€
  • ์ปจํŠธ๋กคํ”Œ๋ ˆ์ธ ๋…ธ๋“œ(k8s-ctr) โ†’ ๋ฉ”๋ชจ๋ฆฌ 3GB๋กœ ์„ค์ •
  • ์›Œ์ปค ๋…ธ๋“œ(k8s-w1, k8s-w2) โ†’ ๋ฉ”๋ชจ๋ฆฌ 2.5GB๋กœ ์„ค์ •

(3) vagrant up ์žฌ์‹œ๋„

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
Bringing machine 'k8s-ctr' up with 'virtualbox' provider...
Bringing machine 'k8s-w1' up with 'virtualbox' provider...
Bringing machine 'k8s-w2' up with 'virtualbox' provider...
==> k8s-ctr: Cloning VM...
==> k8s-ctr: Matching MAC address for NAT networking...
==> k8s-ctr: Checking if box 'bento/ubuntu-24.04' version '202508.03.0' is up to date...
==> k8s-ctr: Setting the name of the VM: k8s-ctr
==> k8s-ctr: Clearing any previously set network interfaces...
==> k8s-ctr: Preparing network interfaces based on configuration...
    k8s-ctr: Adapter 1: nat
    k8s-ctr: Adapter 2: hostonly
==> k8s-ctr: Forwarding ports...
    k8s-ctr: 22 (guest) => 60000 (host) (adapter 1)
==> k8s-ctr: Running 'pre-boot' VM customizations...
==> k8s-ctr: Booting VM...
==> k8s-ctr: Waiting for machine to boot. This may take a few minutes...
    k8s-ctr: SSH address: 127.0.0.1:60000
    k8s-ctr: SSH username: vagrant
    k8s-ctr: SSH auth method: private key
    k8s-ctr: 
    k8s-ctr: Vagrant insecure key detected. Vagrant will automatically replace
    k8s-ctr: this with a newly generated keypair for better security.
    k8s-ctr: 
    k8s-ctr: Inserting generated public key within guest...
    k8s-ctr: Removing insecure key from the guest if it's present...
    k8s-ctr: Key inserted! Disconnecting and reconnecting using new SSH key...
==> k8s-ctr: Machine booted and ready!
==> k8s-ctr: Checking for guest additions in VM...
    k8s-ctr: The guest additions on this VM do not match the installed version of
    k8s-ctr: VirtualBox! In most cases this is fine, but in rare cases it can
    k8s-ctr: prevent things such as shared folders from working properly. If you see
    k8s-ctr: shared folder errors, please make sure the guest additions within the
    k8s-ctr: virtual machine match the version of VirtualBox you have installed on
    k8s-ctr: your host and reload your VM.
    k8s-ctr: 
    k8s-ctr: Guest Additions Version: 7.1.12
    k8s-ctr: VirtualBox Version: 7.2
==> k8s-ctr: Setting hostname...
==> k8s-ctr: Configuring and enabling network interfaces...
==> k8s-ctr: Running provisioner: shell...
    k8s-ctr: Running: /tmp/vagrant-shell20250902-480239-erzmme.sh
    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: [TASK 7] Install pwru
    k8s-ctr: >>>> Initial Config End <<<<
==> k8s-ctr: Running provisioner: shell...
    k8s-ctr: Running: /tmp/vagrant-shell20250902-480239-dnsuae.sh
    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 / Hubble CLI
    k8s-ctr: cilium
    k8s-ctr: hubble
    k8s-ctr: [TASK 9] Remove node taint
    k8s-ctr: node/k8s-ctr untainted
    k8s-ctr: [TASK 10] local DNS with hosts file
    k8s-ctr: [TASK 11] Dynamically provisioning persistent local storage with Kubernetes
    k8s-ctr: [TASK 12] Install Prometheus & Grafana
    k8s-ctr: [TASK 13] Install Metrics-server
    k8s-ctr: [TASK 14] Install k9s
    k8s-ctr: >>>> K8S Controlplane Config End <<<<
==> k8s-w1: Cloning VM...
==> k8s-w1: Matching MAC address for NAT networking...
==> k8s-w1: Checking if box 'bento/ubuntu-24.04' version '202508.03.0' is up to date...
==> k8s-w1: Setting the name of the VM: k8s-w1
==> k8s-w1: Clearing any previously set network interfaces...
==> k8s-w1: Preparing network interfaces based on configuration...
    k8s-w1: Adapter 1: nat
    k8s-w1: Adapter 2: hostonly
==> k8s-w1: Forwarding ports...
    k8s-w1: 22 (guest) => 60001 (host) (adapter 1)
==> k8s-w1: Running 'pre-boot' VM customizations...
==> k8s-w1: Booting VM...
==> k8s-w1: Waiting for machine to boot. This may take a few minutes...
    k8s-w1: SSH address: 127.0.0.1:60001
    k8s-w1: SSH username: vagrant
    k8s-w1: SSH auth method: private key
    k8s-w1: 
    k8s-w1: Vagrant insecure key detected. Vagrant will automatically replace
    k8s-w1: this with a newly generated keypair for better security.
    k8s-w1: 
    k8s-w1: Inserting generated public key within guest...
    k8s-w1: Removing insecure key from the guest if it's present...
    k8s-w1: Key inserted! Disconnecting and reconnecting using new SSH key...
==> k8s-w1: Machine booted and ready!
==> k8s-w1: Checking for guest additions in VM...
    k8s-w1: The guest additions on this VM do not match the installed version of
    k8s-w1: VirtualBox! In most cases this is fine, but in rare cases it can
    k8s-w1: prevent things such as shared folders from working properly. If you see
    k8s-w1: shared folder errors, please make sure the guest additions within the
    k8s-w1: virtual machine match the version of VirtualBox you have installed on
    k8s-w1: your host and reload your VM.
    k8s-w1: 
    k8s-w1: Guest Additions Version: 7.1.12
    k8s-w1: VirtualBox Version: 7.2
==> k8s-w1: Setting hostname...
==> k8s-w1: Configuring and enabling network interfaces...
==> k8s-w1: Running provisioner: shell...
    k8s-w1: Running: /tmp/vagrant-shell20250902-480239-takpig.sh
    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: [TASK 7] Install pwru
    k8s-w1: >>>> Initial Config End <<<<
==> k8s-w1: Running provisioner: shell...
    k8s-w1: Running: /tmp/vagrant-shell20250902-480239-9ldmc2.sh
    k8s-w1: >>>> K8S Node config Start <<<<
    k8s-w1: [TASK 1] K8S Controlplane Join
    k8s-w1: >>>> K8S Node config End <<<<
==> k8s-w2: Cloning VM...
==> k8s-w2: Matching MAC address for NAT networking...
==> k8s-w2: Checking if box 'bento/ubuntu-24.04' version '202508.03.0' is up to date...
==> k8s-w2: Setting the name of the VM: k8s-w2
==> k8s-w2: Clearing any previously set network interfaces...
==> k8s-w2: Preparing network interfaces based on configuration...
    k8s-w2: Adapter 1: nat
    k8s-w2: Adapter 2: hostonly
==> k8s-w2: Forwarding ports...
    k8s-w2: 22 (guest) => 60002 (host) (adapter 1)
==> k8s-w2: Running 'pre-boot' VM customizations...
==> k8s-w2: Booting VM...
==> k8s-w2: Waiting for machine to boot. This may take a few minutes...
    k8s-w2: SSH address: 127.0.0.1:60002
    k8s-w2: SSH username: vagrant
    k8s-w2: SSH auth method: private key
    k8s-w2: 
    k8s-w2: Vagrant insecure key detected. Vagrant will automatically replace
    k8s-w2: this with a newly generated keypair for better security.
    k8s-w2: 
    k8s-w2: Inserting generated public key within guest...
    k8s-w2: Removing insecure key from the guest if it's present...
    k8s-w2: Key inserted! Disconnecting and reconnecting using new SSH key...
==> k8s-w2: Machine booted and ready!
==> k8s-w2: Checking for guest additions in VM...
    k8s-w2: The guest additions on this VM do not match the installed version of
    k8s-w2: VirtualBox! In most cases this is fine, but in rare cases it can
    k8s-w2: prevent things such as shared folders from working properly. If you see
    k8s-w2: shared folder errors, please make sure the guest additions within the
    k8s-w2: virtual machine match the version of VirtualBox you have installed on
    k8s-w2: your host and reload your VM.
    k8s-w2: 
    k8s-w2: Guest Additions Version: 7.1.12
    k8s-w2: VirtualBox Version: 7.2
==> k8s-w2: Setting hostname...
==> k8s-w2: Configuring and enabling network interfaces...
==> k8s-w2: Running provisioner: shell...
    k8s-w2: Running: /tmp/vagrant-shell20250902-480239-t7hfv1.sh
    k8s-w2: >>>> Initial Config Start <<<<
    k8s-w2: [TASK 1] Setting Profile & Bashrc
    k8s-w2: [TASK 2] Disable AppArmor
    k8s-w2: [TASK 3] Disable and turn off SWAP
    k8s-w2: [TASK 4] Install Packages
    k8s-w2: [TASK 5] Install Kubernetes components (kubeadm, kubelet and kubectl)
    k8s-w2: [TASK 6] Install Packages & Helm
    k8s-w2: [TASK 7] Install pwru
    k8s-w2: >>>> Initial Config End <<<<
==> k8s-w2: Running provisioner: shell...
    k8s-w2: Running: /tmp/vagrant-shell20250902-480239-oir40.sh
    k8s-w2: >>>> K8S Node config Start <<<<
    k8s-w2: [TASK 1] K8S Controlplane Join
    k8s-w2: >>>> K8S Node config End <<<<

3. ๋ชจ๋‹ˆํ„ฐ๋ง ๋ฐ ๊ด€๋ฆฌ ๋„๊ตฌ ์ ‘์† ํ™•์ธ

(1) ํ”„๋กœ๋ฉ”ํ…Œ์šฐ์Šค: http://192.168.10.100:30001

(2) ๊ทธ๋ผํŒŒ๋‚˜: http://192.168.10.100:30002

(3) ํ—ˆ๋ธ” UI: http://192.168.10.100:30003/


๐Ÿ“‘ Identity

  • https://docs.cilium.io/en/stable/gettingstarted/terminology/#identity
  • ๋ชจ๋“  ์—”๋“œํฌ์ธํŠธ์— ID๊ฐ€ ํ• ๋‹น. ID๋Š” Labels ๊ณผ ํด๋Ÿฌ์Šคํ„ฐ ๋‚ด์— ์œ ์ผํ•œ ID๋กœ ๊ตฌ์„ฑ
  • ์—”๋“œํฌ์ธํŠธ์—๋Š” Security Relevant Labels์— ์ผ์น˜ํ•˜๋Š” ID๊ฐ€ ํ• ๋‹น
  • ์—”๋“œํฌ์ธํŠธ๋“ค์ด ๋™์ผํ•œ Security Relevant Labels ์‚ฌ์šฉ ์‹œ ๋™์ผํ•œ ID๋ฅผ ๊ณต์œ 

1. CiliumEndpoint ๋ฆฌ์†Œ์Šค๋กœ ์—”๋“œํฌ์ธํŠธ ํ™•์ธ

1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl get ciliumendpoints.cilium.io -n kube-system

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
NAME                              SECURITY IDENTITY   ENDPOINT STATE   IPV4           IPV6
coredns-674b8bbfcf-7xcrj          324                 ready            172.20.0.224   
coredns-674b8bbfcf-vxhtv          324                 ready            172.20.0.155   
hubble-relay-fdd49b976-g22hx      54079               ready            172.20.0.181   
hubble-ui-655f947f96-xtwg4        25043               ready            172.20.0.215   
metrics-server-5dd7b49d79-dw9x6   54044               ready            172.20.0.218   
  • ๊ฐ ํŒŒ๋“œ ๋‹จ์œ„ ์—”๋“œํฌ์ธํŠธ์™€ ํ• ๋‹น๋œ SECURITY IDENTITY, ์ƒํƒœ, IP ์ •๋ณด ํ™•์ธ ๊ฐ€๋Šฅ
  • ์˜ˆ์‹œ์—์„œ coredns ํŒŒ๋“œ 2๊ฐœ๊ฐ€ ID(324) ๋ฅผ ๊ณต์œ  โ†’ ๋™์ผํ•œ ๋ณด์•ˆ ์ •์ฑ…์„ ์ ์šฉ๋ฐ›์Œ์„ ์˜๋ฏธ

2. CiliumIdentity ๋ฆฌ์†Œ์Šค ์กฐํšŒ

1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl get ciliumidentities.cilium.io 

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
NAME    NAMESPACE            AGE
12931   local-path-storage   107m
20866   cilium-monitoring    107m
25043   kube-system          107m
324     kube-system          107m
42541   cilium-monitoring    107m
54044   kube-system          107m
54079   kube-system          107m
1
kubectl get ciliumidentities.cilium.io 54044 -o yaml | yq

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl get ciliumidentities.cilium.io 60202 -o yaml | yq
{
  "apiVersion": "cilium.io/v2",
  "kind": "CiliumIdentity",
  "metadata": {
    "creationTimestamp": "2025-09-06T05:47:17Z",
    "generation": 1,
    "labels": {
      "io.kubernetes.pod.namespace": "kube-system"
    },
    "name": "54044",
    "resourceVersion": "842",
    "uid": "f8d8931f-158c-453d-9945-589f2d9eab15"
  },
  "security-labels": {
    "k8s:app.kubernetes.io/instance": "metrics-server",
    "k8s:app.kubernetes.io/name": "metrics-server",
    "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": "metrics-server",
    "k8s:io.kubernetes.pod.namespace": "kube-system"
  }
}
  • 54044 ID๋Š” metrics-server ํŒŒ๋“œ์— ํ•ด๋‹น, Pod ๋ผ๋ฒจ ๋ฐ ์ž๋™ ๋ถ€์ฐฉ๋œ Cilium ๋ผ๋ฒจ๋“ค์ด ํ‘œ์‹œ๋จ

3. Cilium Agent์—์„œ Identity ๋ผ๋ฒจ ์ƒ์„ธ ํ™•์ธ

1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl exec -it -n kube-system ds/cilium -- cilium identity list

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
ID      LABELS
1       reserved:host
        reserved:kube-apiserver
2       reserved:world
3       reserved:unmanaged
4       reserved:health
5       reserved:init
6       reserved:remote-node
7       reserved:kube-apiserver
        reserved:remote-node
8       reserved:ingress
9       reserved:world-ipv4
10      reserved:world-ipv6
324     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=coredns
        k8s:io.kubernetes.pod.namespace=kube-system
        k8s:k8s-app=kube-dns
12931   k8s:app=local-path-provisioner
        k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=local-path-storage
        k8s:io.cilium.k8s.policy.cluster=default
        k8s:io.cilium.k8s.policy.serviceaccount=local-path-provisioner-service-account
        k8s:io.kubernetes.pod.namespace=local-path-storage
20866   k8s:app=grafana
        k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=cilium-monitoring
        k8s:io.cilium.k8s.policy.cluster=default
        k8s:io.cilium.k8s.policy.serviceaccount=default
        k8s:io.kubernetes.pod.namespace=cilium-monitoring
25043   k8s:app.kubernetes.io/name=hubble-ui
        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
42541   k8s:app=prometheus
        k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=cilium-monitoring
        k8s:io.cilium.k8s.policy.cluster=default
        k8s:io.cilium.k8s.policy.serviceaccount=prometheus-k8s
        k8s:io.kubernetes.pod.namespace=cilium-monitoring
54044   k8s:app.kubernetes.io/instance=metrics-server
        k8s:app.kubernetes.io/name=metrics-server
        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=metrics-server
        k8s:io.kubernetes.pod.namespace=kube-system
54079   k8s:app.kubernetes.io/name=hubble-relay
        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
  • Cilium Agent ๋‚ด๋ถ€์—์„œ Identity์™€ ๋ผ๋ฒจ ๋งคํ•‘ ์ •๋ณด ํ™•์ธ ๊ฐ€๋Šฅ
  • 324 ID์— coredns ๊ด€๋ จ ๋ผ๋ฒจ์ด ๋ถ™์–ด ์žˆ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Œ

4. ๋ผ๋ฒจ ๋ณ€๊ฒฝ ํ›„ Identity ์žฌํ• ๋‹น ํ™•์ธ

(1) coredns ํŒŒ๋“œ ์ดˆ๊ธฐ ์ƒํƒœ ํ™•์ธ

1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl get pod -n kube-system -l k8s-app=kube-dns --show-labels

โœ…ย ์ถœ๋ ฅ

1
2
3
NAME                       READY   STATUS    RESTARTS   AGE    LABELS
coredns-674b8bbfcf-7xcrj   1/1     Running   0          113m   k8s-app=kube-dns,pod-template-hash=674b8bbfcf
coredns-674b8bbfcf-vxhtv   1/1     Running   0          113m   k8s-app=kube-dns,pod-template-hash=674b8bbfcf
  • k8s-app=kube-dns, pod-template-hash=674b8bbfcf

(2) k9s ์ง„์ž…

(3) ๋ผ๋ฒจ ์ถ”๊ฐ€(app: testing)

(4) ์žฌ๊ธฐ๋™

(5) ์ƒˆ๋กœ์šด ๋ผ๋ฒจ ๋ฐ˜์˜ ํ™•์ธ

1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl get pod -n kube-system -l k8s-app=kube-dns --show-labels

โœ…ย ์ถœ๋ ฅ

1
2
3
NAME                      READY   STATUS    RESTARTS   AGE   LABELS
coredns-99ff8c6c4-6zg5v   1/1     Running   0          33s   app=testing,k8s-app=kube-dns,pod-template-hash=99ff8c6c4
coredns-99ff8c6c4-fpx2g   1/1     Running   0          33s   app=testing,k8s-app=kube-dns,pod-template-hash=99ff8c6c4
  • ๋Œ€๋žต 30์ดˆ ์ •๋„ ์ดํ›„, LABEL(app=testing)์ด ๋ฐ˜์˜๋˜์—ˆ๋‹ค.

(6) ์ƒˆ๋กœ์šด ID ํ• ๋‹น ํ™•์ธ

1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl exec -it -n kube-system ds/cilium -- cilium identity list

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
ID      LABELS
1       reserved:host
        reserved:kube-apiserver
2       reserved:world
3       reserved:unmanaged
4       reserved:health
5       reserved:init
6       reserved:remote-node
7       reserved:kube-apiserver
        reserved:remote-node
8       reserved:ingress
9       reserved:world-ipv4
10      reserved:world-ipv6
324     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=coredns
        k8s:io.kubernetes.pod.namespace=kube-system
        k8s:k8s-app=kube-dns
12931   k8s:app=local-path-provisioner
        k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=local-path-storage
        k8s:io.cilium.k8s.policy.cluster=default
        k8s:io.cilium.k8s.policy.serviceaccount=local-path-provisioner-service-account
        k8s:io.kubernetes.pod.namespace=local-path-storage
18194   k8s:app=testing
        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=coredns
        k8s:io.kubernetes.pod.namespace=kube-system
        k8s:k8s-app=kube-dns
20866   k8s:app=grafana
        k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=cilium-monitoring
        k8s:io.cilium.k8s.policy.cluster=default
        k8s:io.cilium.k8s.policy.serviceaccount=default
        k8s:io.kubernetes.pod.namespace=cilium-monitoring
25043   k8s:app.kubernetes.io/name=hubble-ui
        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
42541   k8s:app=prometheus
        k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=cilium-monitoring
        k8s:io.cilium.k8s.policy.cluster=default
        k8s:io.cilium.k8s.policy.serviceaccount=prometheus-k8s
        k8s:io.kubernetes.pod.namespace=cilium-monitoring
54044   k8s:app.kubernetes.io/instance=metrics-server
        k8s:app.kubernetes.io/name=metrics-server
        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=metrics-server
        k8s:io.kubernetes.pod.namespace=kube-system
54079   k8s:app.kubernetes.io/name=hubble-relay
        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
1
2
3
4
5
6
18194   k8s:app=testing
        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=coredns
        k8s:io.kubernetes.pod.namespace=kube-system
        k8s:k8s-app=kube-dns
  • ๊ธฐ์กด 324 ID ๋Œ€์‹  18194 ID๊ฐ€ ์ƒˆ๋กญ๊ฒŒ ์ƒ์„ฑ๋˜์–ด ์ ์šฉ๋จ
  • ๋ผ๋ฒจ ๋ณ€๊ฒฝ ์‹œ ID๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉฐ ๋ณด์•ˆ ์ •์ฑ…๋„ ์ž๋™์œผ๋กœ ๊ฐฑ์‹ ๋จ

5. Special Identities ํ™•์ธ

1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl exec -it -n kube-system ds/cilium -- cilium identity list

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
ID      LABELS
1       reserved:host
        reserved:kube-apiserver
2       reserved:world
3       reserved:unmanaged
4       reserved:health
5       reserved:init
6       reserved:remote-node
7       reserved:kube-apiserver
        reserved:remote-node
8       reserved:ingress
9       reserved:world-ipv4
10      reserved:world-ipv6
...
  • Cilium์€ ๋ชจ๋“  ์—”๋“œํฌ์ธํŠธ(Pod ํฌํ•จ)์— ๊ณ ์œ ํ•œ Security Identity(ID) ๋ฅผ ๋ถ€์—ฌํ•จ
  • ๊ทธ๋Ÿฌ๋‚˜ ํด๋Ÿฌ์Šคํ„ฐ ์™ธ๋ถ€ ์—”๋“œํฌ์ธํŠธ๋‚˜ Cilium์ด ์ง์ ‘ ๊ด€๋ฆฌํ•˜์ง€ ์•Š๋Š” ๋Œ€์ƒ๊ณผ์˜ ํ†ต์‹ ์„ ํ—ˆ์šฉํ•˜๊ธฐ ์œ„ํ•ด ํŠน์ˆ˜ ์˜ˆ์•ฝ ID(Reserved Identity)๋ฅผ ์ œ๊ณตํ•จ
  • ์ด๋Ÿฌํ•œ ์˜ˆ์•ฝ๋œ ID์—๋Š” reserved ์ ‘๋‘์‚ฌ๊ฐ€ ๋ถ™์Œ

๐Ÿš€ [Lab1] DNS ๊ธฐ๋ฐ˜ ๋ณด์•ˆ ์ •์ฑ…

1. ๋ฐ๋ชจ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐฐํฌ

(1) ๋ฐฐํฌ ํŒŒ์ผ ์ƒ์„ฑ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# cat << EOF > dns-sw-app.yaml
apiVersion: v1
kind: Pod
metadata:
  name: mediabot
  labels:
    org: empire
    class: mediabot
    app: mediabot
spec:
  containers:
  - name: mediabot
    image: quay.io/cilium/json-mock:v1.3.8@sha256:5aad04835eda9025fe4561ad31be77fd55309af8158ca8663a72f6abb78c2603
EOF
  • L7 Envoy Proxy๊ฐ€ ์•„๋‹Œ Cilium Agent ๋‚ด์žฅ DNS Proxy ๋กœ ๋™์ž‘ํ•˜๋Š” DNS ์ •์ฑ… ์ œ์–ด ์‹ค์Šต
  • json-mock ์ปจํ…Œ์ด๋„ˆ ๋ฐฐํฌ ํ›„ api.github.com์— ์™ธ๋ถ€ ํ†ต์‹  ํ…Œ์ŠคํŠธ
  • ๊ณต์‹ ์˜ˆ์ œ์—๋Š” app: mediabot ๋ผ๋ฒจ์ด ์—†์–ด ์ง์ ‘ ์ถ”๊ฐ€ ํ›„ ๋ฐฐํฌ

(2) ํŒŒ๋“œ ์ƒ์„ฑ

1
2
3
4
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl apply -f dns-sw-app.yaml

# ๊ฒฐ๊ณผ
pod/mediabot created
1
2
3
4
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl wait pod/mediabot --for=condition=Ready

# ๊ฒฐ๊ณผ
pod/mediabot condition met
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl exec -it -n kube-system ds/cilium -- cilium identity list
ID      LABELS
1       reserved:host
        reserved:kube-apiserver
2       reserved:world
3       reserved:unmanaged
4       reserved:health
5       reserved:init
6       reserved:remote-node
7       reserved:kube-apiserver
        reserved:remote-node
8       reserved:ingress
9       reserved:world-ipv4
10      reserved:world-ipv6
324     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=coredns
        k8s:io.kubernetes.pod.namespace=kube-system
        k8s:k8s-app=kube-dns
12931   k8s:app=local-path-provisioner
        k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=local-path-storage
        k8s:io.cilium.k8s.policy.cluster=default
        k8s:io.cilium.k8s.policy.serviceaccount=local-path-provisioner-service-account
        k8s:io.kubernetes.pod.namespace=local-path-storage
18194   k8s:app=testing
        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=coredns
        k8s:io.kubernetes.pod.namespace=kube-system
        k8s:k8s-app=kube-dns
20866   k8s:app=grafana
        k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=cilium-monitoring
        k8s:io.cilium.k8s.policy.cluster=default
        k8s:io.cilium.k8s.policy.serviceaccount=default
        k8s:io.kubernetes.pod.namespace=cilium-monitoring
25043   k8s:app.kubernetes.io/name=hubble-ui
        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
42541   k8s:app=prometheus
        k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=cilium-monitoring
        k8s:io.cilium.k8s.policy.cluster=default
        k8s:io.cilium.k8s.policy.serviceaccount=prometheus-k8s
        k8s:io.kubernetes.pod.namespace=cilium-monitoring
53288   k8s:app=mediabot
        k8s:class=mediabot
        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
54044   k8s:app.kubernetes.io/instance=metrics-server
        k8s:app.kubernetes.io/name=metrics-server
        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=metrics-server
        k8s:io.kubernetes.pod.namespace=kube-system
54079   k8s:app.kubernetes.io/name=hubble-relay
        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
  • ์†Œ์Šค Identity์— app=mediabot ๋ผ๋ฒจ ์ •์ƒ ๋ฐ˜์˜ ํ™•์ธ
1
2
3
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl get pods
NAME       READY   STATUS    RESTARTS   AGE
mediabot   1/1     Running   0          79s
  • mediabot ํŒŒ๋“œ ์ •์ƒ ๊ธฐ๋™ ํ™•์ธ

2. ์™ธ๋ถ€ ํ†ต์‹  ๋™์ž‘ ํ™•์ธ

1
2
3
4
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl exec mediabot -- curl -I -s https://api.github.com | head -1

# ๊ฒฐ๊ณผ
HTTP/2 200
1
2
3
4
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl exec mediabot -- curl -I -s --max-time 5 https://support.github.com | head -1

# ๊ฒฐ๊ณผ
HTTP/2 302


๐Ÿ”Ž DNS Egress ์ •์ฑ… ์ ์šฉ 1:mediabot ํŒŒ๋“œ๊ฐ€ api.github.com์—๋งŒ ์•ก์„ธ์Šคํ•˜๋„๋ก ํ—ˆ์šฉ

1. CiliumNetworkPolicy ์ƒ์„ฑ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# cat << EOF | kubectl apply -f -
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
  name: "fqdn"
spec:
  endpointSelector:
    matchLabels:
      org: empire
      class: mediabot
  egress:
  - toFQDNs:
    - matchName: "api.github.com"
  - toEndpoints:
    - matchLabels:
        "k8s:io.kubernetes.pod.namespace": kube-system
        "k8s:k8s-app": kube-dns
    toPorts:
    - ports:
      - port: "53"
        protocol: ANY
      rules:
        dns:
        - matchPattern: "*"
EOF

# ๊ฒฐ๊ณผ
ciliumnetworkpolicy.cilium.io/fqdn created
  • mediabot ํŒŒ๋“œ๊ฐ€ api.github.com ๋„๋ฉ”์ธ๋งŒ ์ ‘๊ทผ ํ—ˆ์šฉ๋˜๋„๋ก CiliumNetworkPolicy ์ž‘์„ฑ ๋ฐ ์ ์šฉ
  • DNS ์งˆ์˜ ํ—ˆ์šฉ์„ ์œ„ํ•ด kube-dns:53 (UDP/TCP) ํฌํŠธ ๊ทœ์น™ ์ถ”๊ฐ€

2. ์ •์ฑ… ์ƒ์„ฑ ์—ฌ๋ถ€ ํ™•์ธ

1
2
3
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl get cnp
NAME   AGE   VALID
fqdn   10s   True

3. Policy Selector ํ™•์ธ

1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl exec -it -n kube-system ds/cilium -- cilium policy selectors 

โœ…ย ์ถœ๋ ฅ

1
2
SELECTOR                                                                                                                                                                      LABELS         USERS   IDENTITIES
&LabelSelector{MatchLabels:map[string]string{any.class: mediabot,any.org: empire,k8s.io.kubernetes.pod.namespace: default,},MatchExpressions:[]LabelSelectorRequirement{},}   default/fqdn   1       53288 
  • org=empire, class=mediabot, app=mediabot ๋ผ๋ฒจ ๊ธฐ๋ฐ˜์œผ๋กœ ์ •์ฑ… ๋งค์นญ๋จ
  • ๊ณต์‹ ์˜ˆ์ œ์—๋Š” app ๋ผ๋ฒจ์ด ์—†์–ด default๋กœ๋งŒ ํ‘œ์‹œ๋˜์–ด ํ˜ผ๋™์ด ๋ฐœ์ƒ โ†’ ์ง์ ‘ ๋ผ๋ฒจ ์ถ”๊ฐ€

4. Cilium DNS ๊ด€๋ จ ์„ค์ • ์กฐํšŒ

1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# cilium config view | grep -i dns

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
dnsproxy-enable-transparent-mode                  true
dnsproxy-socket-linger-timeout                    10
hubble-metrics                                    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
tofqdns-dns-reject-response-code                  refused
tofqdns-enable-dns-compression                    true
tofqdns-endpoint-max-ip-per-hostname              1000
tofqdns-idle-connection-grace-period              0s
tofqdns-max-deferred-connection-deletes           10000
tofqdns-preallocate-identities                    true
tofqdns-proxy-response-max-delay                  100ms
  • CiliumNetworkPolicy ๋กœ DNS ๊ธฐ๋ฐ˜ ์ •์ฑ…์„ ์ ์šฉํ•˜๋ฉด, Cilium์˜ ๋‚ด์žฅ DNS Proxy ๊ฐ€ ํ™œ์„ฑํ™”๋˜์–ด ์š”์ฒญ์„ ๊ฐ€๋กœ์ฑ„๊ณ  ์ •์ฑ…์„ ์ ์šฉ
  • DNS Proxy๋Š” CoreDNS ์•ž๋‹จ์—์„œ ๋™์ž‘ํ•˜๋ฉด์„œ ๋„๋ฉ”์ธ ์งˆ์˜/์‘๋‹ต ํ๋ฆ„์„ ์ œ์–ดํ•จ
  • tofqdns-* ๊ด€๋ จ ์˜ต์…˜๋“ค์€ L3 ๊ณ„์ธต์—์„œ DNS ๊ธฐ๋ฐ˜ ํ†ต์ œ ์ •์ฑ…์„ ๊ด€๋ฆฌํ•˜๋Š” ํ•ญ๋ชฉ

5. api.github.com ํ—ˆ์šฉ ๋„๋ฉ”์ธ ์ ‘๊ทผ ํ…Œ์ŠคํŠธ

1
2
3
4
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl exec mediabot -- curl -I -s https://api.github.com | head -1

# ๊ฒฐ๊ณผ
HTTP/2 200

6. ํ—ˆ์šฉ๋˜์ง€ ์•Š์€ ๋„๋ฉ”์ธ ์ฐจ๋‹จ ํ™•์ธ

1
2
3
4
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl exec mediabot -- curl -I -s --max-time 5 https://support.github.com | head -1

# ๊ฒฐ๊ณผ
command terminated with exit code 28

  • exit code 28 (์—ฐ๊ฒฐ ์‹คํŒจ) โ†’ ์ •์ฑ…์— ์˜ํ•ด ์ฐจ๋‹จ๋จ
  • Cilium ๋„คํŠธ์›Œํฌ ์ •์ฑ…์€ ํ—ˆ์šฉ ์ •์ฑ…์ด ์žˆ์œผ๋ฉด ๋‚˜๋จธ์ง€๋Š” ๋ชจ๋‘ ์ฐจ๋‹จํ•˜๋Š” ๋ฐฉ์‹

7. Hubble Relay ํฌํŠธํฌ์›Œ๋”ฉ

1
2
3
4
5
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# cilium hubble port-forward&

# ๊ฒฐ๊ณผ
[1] 8266
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# โ„น๏ธ  Hubble Relay is available at 127.0.0.1:4245

8. Hubble Observe ํ†ตํ•œ DNS Proxy ๋™์ž‘ ํ™•์ธ

1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# hubble observe --pod mediabot

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
Sep  6 07:52:52.043: default/mediabot:52753 (ID:53288) -> kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) to-endpoint FORWARDED (UDP)
Sep  6 07:52:52.043: default/mediabot:52753 (ID:53288) <> kube-system/coredns-99ff8c6c4-6zg5v (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  6 07:52:52.043: default/mediabot:52753 (ID:53288) <> kube-system/coredns-99ff8c6c4-6zg5v (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  6 07:52:52.043: default/mediabot:52753 (ID:53288) <- kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) to-network FORWARDED (UDP)
Sep  6 07:52:52.046: default/mediabot:50557 (ID:53288) -> kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) to-endpoint FORWARDED (UDP)
Sep  6 07:52:52.046: default/mediabot:50557 (ID:53288) <> kube-system/coredns-99ff8c6c4-6zg5v (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  6 07:52:52.047: default/mediabot:50557 (ID:53288) <> kube-system/coredns-99ff8c6c4-6zg5v (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  6 07:52:52.053: default/mediabot:50557 (ID:53288) <- kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) to-network FORWARDED (UDP)
Sep  6 07:56:00.580: default/mediabot:45901 (ID:53288) -> kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) to-endpoint FORWARDED (UDP)
Sep  6 07:56:00.580: default/mediabot:45901 (ID:53288) <> kube-system/coredns-99ff8c6c4-6zg5v (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  6 07:56:00.580: default/mediabot:45901 (ID:53288) <> kube-system/coredns-99ff8c6c4-6zg5v (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  6 07:56:00.580: default/mediabot:45901 (ID:53288) <- kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) to-network FORWARDED (UDP)
Sep  6 07:56:00.583: default/mediabot:46967 (ID:53288) -> kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) to-endpoint FORWARDED (UDP)
Sep  6 07:56:00.584: default/mediabot:46967 (ID:53288) <> kube-system/coredns-99ff8c6c4-6zg5v (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  6 07:56:00.584: default/mediabot:46967 (ID:53288) <> kube-system/coredns-99ff8c6c4-6zg5v (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  6 07:56:00.584: default/mediabot:46967 (ID:53288) <- kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) to-network FORWARDED (UDP)
Sep  6 07:56:00.599: default/mediabot:53534 (ID:53288) -> kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) to-endpoint FORWARDED (UDP)
Sep  6 07:56:00.599: default/mediabot:53534 (ID:53288) <> kube-system/coredns-99ff8c6c4-fpx2g (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  6 07:56:00.599: default/mediabot:53534 (ID:53288) <> kube-system/coredns-99ff8c6c4-fpx2g (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  6 07:56:00.606: default/mediabot:53534 (ID:53288) <- kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) to-proxy FORWARDED (UDP)
Sep  6 07:56:00.606: default/mediabot:53534 (ID:53288) <- kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) dns-response proxy FORWARDED (DNS Answer  TTL: 4294967295 (Proxy support.github.com. AAAA))
Sep  6 07:56:00.606: kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) <> default/mediabot (ID:53288) pre-xlate-rev TRACED (UDP)
Sep  6 07:56:00.606: kube-system/kube-dns:53 (world) <> default/mediabot (ID:53288) post-xlate-rev TRANSLATED (UDP)
Sep  6 07:56:00.606: default/mediabot:53534 (ID:53288) <- kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) dns-response proxy FORWARDED (DNS Answer "185.199.109.133,185.199.108.133,185.199.110.133,185.199.111.133" TTL: 30 (Proxy support.github.com. A))
Sep  6 07:56:00.607: kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) <> default/mediabot (ID:53288) pre-xlate-rev TRACED (UDP)
Sep  6 07:56:00.607: kube-system/kube-dns:53 (world) <> default/mediabot (ID:53288) post-xlate-rev TRANSLATED (UDP)
Sep  6 07:56:00.607: default/mediabot:51188 (ID:53288) <> support.github.com:443 (world) policy-verdict:none EGRESS DENIED (TCP Flags: SYN)
Sep  6 07:56:00.607: default/mediabot:51188 (ID:53288) <> support.github.com:443 (world) Policy denied DROPPED (TCP Flags: SYN)
Sep  6 07:56:01.625: default/mediabot:51188 (ID:53288) <> support.github.com:443 (world) policy-verdict:none EGRESS DENIED (TCP Flags: SYN)
Sep  6 07:56:01.625: default/mediabot:51188 (ID:53288) <> support.github.com:443 (world) Policy denied DROPPED (TCP Flags: SYN)
Sep  6 07:56:02.649: default/mediabot:51188 (ID:53288) <> support.github.com:443 (world) policy-verdict:none EGRESS DENIED (TCP Flags: SYN)
Sep  6 07:56:02.649: default/mediabot:51188 (ID:53288) <> support.github.com:443 (world) Policy denied DROPPED (TCP Flags: SYN)
Sep  6 07:56:04.095: default/mediabot:37546 (ID:53288) <> support.github.com:443 (world) policy-verdict:none EGRESS DENIED (TCP Flags: SYN)
Sep  6 07:56:04.095: default/mediabot:37546 (ID:53288) <> support.github.com:443 (world) Policy denied DROPPED (TCP Flags: SYN)
Sep  6 07:56:04.957: default/mediabot:59306 (ID:53288) <> support.github.com:443 (world) policy-verdict:none EGRESS DENIED (TCP Flags: SYN)
Sep  6 07:56:04.957: default/mediabot:59306 (ID:53288) <> support.github.com:443 (world) Policy denied DROPPED (TCP Flags: SYN)
EVENTS LOST: HUBBLE_RING_BUFFER CPU(0) 1

9. CoreDNS ๋กœ๊ทธ ํ™œ์„ฑํ™” ๋ฐ ํ™•์ธ

log ์ถ”๊ฐ€

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl logs -n kube-system -l k8s-app=kube-dns -f

# ๊ฒฐ๊ณผ
maxprocs: Leaving GOMAXPROCS=4: CPU quota undefined
.:53
[INFO] plugin/reload: Running configuration SHA512 = 1b226df79860026c6a52e67daa10d7f0d57ec5b023288ec00c5e05f93523c894564e15b91770d3a07ae1cfbe861d15b37d4a0027e69c546ab112970993a3b03b
CoreDNS-1.12.0
linux/amd64, go1.23.3, 51e11f1
maxprocs: Leaving GOMAXPROCS=4: CPU quota undefined
.:53
[INFO] plugin/reload: Running configuration SHA512 = 1b226df79860026c6a52e67daa10d7f0d57ec5b023288ec00c5e05f93523c894564e15b91770d3a07ae1cfbe861d15b37d4a0027e69c546ab112970993a3b03b
CoreDNS-1.12.0
linux/amd64, go1.23.3, 51e11f1
[INFO] Reloading
[INFO] plugin/reload: Running configuration SHA512 = b997d646f2866cdb764039218df1d7492383070c88b4c8bb8a04cb6fcc0183bf42530d185d9bd227f85a77a57fa184d6184af081e37fc852d6819bf5b3d8a5c4
[INFO] Reloading complete
[INFO] 127.0.0.1:55259 - 23681 "HINFO IN 5995726665743064631.5070209189804637255. udp 57 false 512" NXDOMAIN qr,rd,ra 132 0.010613518s
[INFO] Reloading
[INFO] plugin/reload: Running configuration SHA512 = b997d646f2866cdb764039218df1d7492383070c88b4c8bb8a04cb6fcc0183bf42530d185d9bd227f85a77a57fa184d6184af081e37fc852d6819bf5b3d8a5c4
[INFO] Reloading complete
[INFO] 127.0.0.1:60628 - 1978 "HINFO IN 1275766829604113746.7917362220424931272. udp 57 false 512" NXDOMAIN qr,rd,ra 132 0.01771642s

10. ๋ฐ˜๋ณต ์งˆ์˜ ์‹œ๋„ ๋ฐ ๋กœ๊ทธ ๋ถ„์„

1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl exec mediabot -- curl -I -s https://api.github.com | head -1

โœ…ย ์ถœ๋ ฅ

1
HTTP/2 200
1
2
3
4
5
6
7
8
9
10
[INFO] 172.20.2.46:43944 - 34281 "AAAA IN api.github.com.default.svc.cluster.local. udp 58 false 512" NXDOMAIN qr,aa,rd 151 0.000119368s
[INFO] 172.20.2.46:43944 - 38379 "A IN api.github.com.default.svc.cluster.local. udp 58 false 512" NXDOMAIN qr,aa,rd 151 0.000230762s
[INFO] 172.20.2.46:46453 - 58433 "AAAA IN api.github.com.svc.cluster.local. udp 50 false 512" NXDOMAIN qr,aa,rd 143 0.000309497s
[INFO] 172.20.2.46:46453 - 43587 "A IN api.github.com.svc.cluster.local. udp 50 false 512" NXDOMAIN qr,aa,rd 143 0.000172214s
[INFO] 172.20.2.46:40722 - 24412 "A IN api.github.com.cluster.local. udp 46 false 512" NXDOMAIN qr,aa,rd 139 0.000130767s
[INFO] 172.20.2.46:40722 - 20317 "AAAA IN api.github.com.cluster.local. udp 46 false 512" NXDOMAIN qr,aa,rd 139 0.000159982s
[INFO] 172.20.2.46:40697 - 25020 "A IN api.github.com.davolink. udp 41 false 512" NXDOMAIN qr,rd,ra 116 0.006048631s
[INFO] 172.20.2.46:40697 - 25275 "AAAA IN api.github.com.davolink. udp 41 false 512" NXDOMAIN qr,rd,ra 116 0.006064105s
[INFO] 172.20.2.46:58031 - 6124 "A IN api.github.com. udp 32 false 512" NOERROR qr,rd,ra 410 0.005004666s
[INFO] 172.20.2.46:58031 - 41710 "AAAA IN api.github.com. udp 32 false 512" NOERROR qr,rd,ra 129 0.004969755s
1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl exec mediabot -- curl -I -s https://api.github.com | head -1

โœ…ย ์ถœ๋ ฅ

1
HTTP/2 200
1
2
3
4
5
6
7
8
9
10
[INFO] 172.20.2.46:58536 - 65204 "A IN api.github.com.default.svc.cluster.local. udp 58 false 512" NXDOMAIN qr,aa,rd 151 0.00040403s
[INFO] 172.20.2.46:58536 - 31113 "AAAA IN api.github.com.default.svc.cluster.local. udp 58 false 512" NXDOMAIN qr,aa,rd 151 0.000817802s
[INFO] 172.20.2.46:33003 - 18168 "AAAA IN api.github.com.svc.cluster.local. udp 50 false 512" NXDOMAIN qr,aa,rd 143 0.000283518s
[INFO] 172.20.2.46:33003 - 61178 "A IN api.github.com.svc.cluster.local. udp 50 false 512" NXDOMAIN qr,aa,rd 143 0.000897778s
[INFO] 172.20.2.46:42726 - 52191 "A IN api.github.com.cluster.local. udp 46 false 512" NXDOMAIN qr,aa,rd 139 0.000383001s
[INFO] 172.20.2.46:42726 - 53716 "AAAA IN api.github.com.cluster.local. udp 46 false 512" NXDOMAIN qr,aa,rd 139 0.000780851s
[INFO] 172.20.2.46:60419 - 11887 "A IN api.github.com.davolink. udp 41 false 512" NXDOMAIN qr,rd,ra 116 0.006338245s
[INFO] 172.20.2.46:60419 - 9578 "AAAA IN api.github.com.davolink. udp 41 false 512" NXDOMAIN qr,rd,ra 116 0.205647425s
[INFO] 172.20.2.46:56354 - 52407 "AAAA IN api.github.com. udp 32 false 512" NOERROR qr,rd,ra 116 0.004314325s
[INFO] 172.20.2.46:56354 - 13993 "A IN api.github.com. udp 32 false 512" NOERROR qr,rd,ra 62 0.006500433s
  • api.github.com ์งˆ์˜๊ฐ€ ๊ณ„์† CoreDNS์— ๊ธฐ๋ก๋จ
1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# hubble observe --pod mediabot

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
Sep  6 08:08:33.289: default/mediabot:58536 (ID:53288) -> kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) to-endpoint FORWARDED (UDP)
Sep  6 08:08:33.290: default/mediabot:58536 (ID:53288) <> kube-system/coredns-99ff8c6c4-6zg5v (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  6 08:08:33.290: default/mediabot:58536 (ID:53288) <> kube-system/coredns-99ff8c6c4-6zg5v (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  6 08:08:33.290: default/mediabot:58536 (ID:53288) <- kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) to-network FORWARDED (UDP)
Sep  6 08:08:35.374: default/mediabot:38441 (ID:53288) -> kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) to-endpoint FORWARDED (UDP)
Sep  6 08:08:35.374: default/mediabot:38441 (ID:53288) <> kube-system/coredns-99ff8c6c4-6zg5v (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  6 08:08:35.374: default/mediabot:38441 (ID:53288) <> kube-system/coredns-99ff8c6c4-6zg5v (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  6 08:08:35.374: default/mediabot:38441 (ID:53288) <- kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) to-network FORWARDED (UDP)
Sep  6 08:08:35.376: default/mediabot:38802 (ID:53288) -> kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) to-endpoint FORWARDED (UDP)
Sep  6 08:08:35.376: default/mediabot:38802 (ID:53288) <> kube-system/coredns-99ff8c6c4-6zg5v (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  6 08:08:35.376: default/mediabot:38802 (ID:53288) <> kube-system/coredns-99ff8c6c4-6zg5v (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  6 08:08:35.376: default/mediabot:38802 (ID:53288) <- kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) to-network FORWARDED (UDP)
Sep  6 08:08:35.377: default/mediabot:33620 (ID:53288) -> kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) to-endpoint FORWARDED (UDP)
Sep  6 08:08:35.377: default/mediabot:33620 (ID:53288) <> kube-system/coredns-99ff8c6c4-6zg5v (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  6 08:08:35.378: default/mediabot:33620 (ID:53288) <> kube-system/coredns-99ff8c6c4-6zg5v (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  6 08:08:35.378: default/mediabot:33620 (ID:53288) <- kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) to-network FORWARDED (UDP)
Sep  6 08:08:35.380: default/mediabot:59503 (ID:53288) -> kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) to-endpoint FORWARDED (UDP)
Sep  6 08:08:35.380: default/mediabot:59503 (ID:53288) <> kube-system/coredns-99ff8c6c4-6zg5v (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  6 08:08:35.380: default/mediabot:59503 (ID:53288) <> kube-system/coredns-99ff8c6c4-6zg5v (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  6 08:08:35.388: default/mediabot:59503 (ID:53288) <- kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) to-network FORWARDED (UDP)
Sep  6 08:08:35.390: default/mediabot:50527 (ID:53288) <- kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) dns-response proxy FORWARDED (DNS Answer  TTL: 4294967295 (Proxy api.github.com. AAAA))
Sep  6 08:08:35.390: default/mediabot:50527 (ID:53288) <- kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) dns-response proxy FORWARDED (DNS Answer "20.200.245.245" TTL: 15 (Proxy api.github.com. A))
Sep  6 08:08:35.390: kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) <> default/mediabot (ID:53288) pre-xlate-rev TRACED (UDP)
Sep  6 08:08:35.390: kube-system/kube-dns:53 (world) <> default/mediabot (ID:53288) post-xlate-rev TRANSLATED (UDP)
Sep  6 08:08:35.390: kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) <> default/mediabot (ID:53288) pre-xlate-rev TRACED (UDP)
Sep  6 08:08:35.390: kube-system/kube-dns:53 (world) <> default/mediabot (ID:53288) post-xlate-rev TRANSLATED (UDP)
Sep  6 08:08:35.390: default/mediabot:47458 (ID:53288) -> api.github.com:443 (ID:16777217) policy-verdict:L3-Only EGRESS ALLOWED (TCP Flags: SYN)
Sep  6 08:08:35.390: default/mediabot:47458 (ID:53288) -> api.github.com:443 (ID:16777217) to-network FORWARDED (TCP Flags: SYN)
Sep  6 08:08:35.398: default/mediabot:47458 (ID:53288) <- api.github.com:443 (ID:16777217) to-endpoint FORWARDED (TCP Flags: SYN, ACK)
Sep  6 08:08:35.398: default/mediabot:47458 (ID:53288) -> api.github.com:443 (ID:16777217) to-network FORWARDED (TCP Flags: ACK)
Sep  6 08:08:35.399: api.github.com:443 (ID:16777217) <> default/mediabot (ID:53288) pre-xlate-rev TRACED (TCP)
Sep  6 08:08:35.401: default/mediabot:47458 (ID:53288) -> api.github.com:443 (ID:16777217) to-network FORWARDED (TCP Flags: ACK, PSH)
Sep  6 08:08:35.409: default/mediabot:47458 (ID:53288) <- api.github.com:443 (ID:16777217) to-endpoint FORWARDED (TCP Flags: ACK, PSH)
Sep  6 08:08:35.455: api.github.com:443 (ID:16777217) <> default/mediabot (ID:53288) pre-xlate-rev TRACED (TCP)
Sep  6 08:08:35.455: api.github.com:443 (ID:16777217) <> default/mediabot (ID:53288) pre-xlate-rev TRACED (TCP)
Sep  6 08:08:35.464: default/mediabot:47458 (ID:53288) -> api.github.com:443 (ID:16777217) to-network FORWARDED (TCP Flags: ACK, FIN)
Sep  6 08:08:35.474: default/mediabot:47458 (ID:53288) <- api.github.com:443 (ID:16777217) to-endpoint FORWARDED (TCP Flags: ACK, FIN)
Sep  6 08:08:35.474: default/mediabot:47458 (ID:53288) -> api.github.com:443 (ID:16777217) to-network FORWARDED (TCP Flags: RST)
Sep  6 08:08:35.474: default/mediabot:47458 (ID:53288) -> api.github.com:443 (ID:16777217) to-network FORWARDED (TCP Flags: RST)
Sep  6 08:08:35.474: default/mediabot:47458 (ID:53288) <- api.github.com:443 (ID:16777217) to-endpoint FORWARDED (TCP Flags: ACK, RST)
  • ์บ์‹ฑ์ด ์žˆ์Œ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  CoreDNS ๋กœ๊ทธ์— ๊ณ„์† ๋ณด์ด๋Š” ํ˜„์ƒ ๊ด€์ฐฐ๋จ

11. DNS Proxy ์„ค์ •๊ฐ’ ํ™•์ธ

1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# cilium config view | grep -i dns

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
dnsproxy-enable-transparent-mode                  true
dnsproxy-socket-linger-timeout                    10
hubble-metrics                                    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
tofqdns-dns-reject-response-code                  refused
tofqdns-enable-dns-compression                    true
tofqdns-endpoint-max-ip-per-hostname              1000
tofqdns-idle-connection-grace-period              0s
tofqdns-max-deferred-connection-deletes           10000
tofqdns-preallocate-identities                    true
tofqdns-proxy-response-max-delay                  100ms

12. Cilium Agent ์บ์‹œ ์กฐํšŒ

1
2
3
4
5
6
7
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# 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

# ๊ฒฐ๊ณผ
cilium-q2wkn cilium-8wkbz cilium-wcpr2
1
2
3
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# 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"
  • ๋…ธ๋“œ๋ณ„ Cilium Pod๋ฅผ ๋ณ€์ˆ˜(CILIUMPOD0, CILIUMPOD1, CILIUMPOD2)๋กœ ์„ค์ • ํ›„ alias ๋“ฑ๋ก
1
2
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# c1 fqdn cache list
c2 fqdn cache list

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
Endpoint   Source   FQDN   TTL   ExpirationTime   IPs   
Endpoint   Source       FQDN                  TTL   ExpirationTime             IPs               
2394       connection   support.github.com.   0     2025-09-06T08:17:43.159Z   185.199.110.133   
2394       connection   support.github.com.   0     2025-09-06T08:17:43.159Z   185.199.111.133   
2394       connection   support.github.com.   0     2025-09-06T08:17:43.159Z   185.199.109.133   
2394       connection   support.github.com.   0     2025-09-06T08:17:43.159Z   185.199.108.133   
2394       connection   api.github.com.       0     2025-09-06T08:17:43.159Z   20.200.245.245  
  • ์บ์‹œ๋Š” ์กด์žฌํ•˜์ง€๋งŒ, CoreDNS ๋กœ๊ทธ์—๋„ ์งˆ์˜๊ฐ€ ์—ฌ์ „ํžˆ ๊ธฐ๋ก๋˜๋Š” ๋ถˆ์ผ์น˜ ํ˜„์ƒ ๋ฐœ์ƒ

13. FQDNPolicySelector ํ™•์ธ

1
2
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# c1 fqdn names
c2 fqdn names

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
  "DNSPollNames": null,
  "FQDNPolicySelectors": []
}

{
  "DNSPollNames": null,
  "FQDNPolicySelectors": [
    {
      "regexString": "^api[.]github[.]com[.]$",
      "selectorString": "MatchName: api.github.com, MatchPattern: "
    }
  ]
}

๐ŸŒ DNS Egress ์ •์ฑ… ์ ์šฉ 2: ๋ชจ๋“  GitHub ํ•˜์œ„ ๋„๋ฉ”์ธ์— ์•ก์„ธ์Šค

1. FQDN ์บ์‹œ ๋ฐ ์ •์ฑ… ์ดˆ๊ธฐํ™”

1
2
3
4
5
6
7
8
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl delete cnp fqdn
c1 fqdn cache clean -f
c2 fqdn cache clean -f

# ๊ฒฐ๊ณผ
ciliumnetworkpolicy.cilium.io "fqdn" deleted
FQDN proxy cache cleared
FQDN proxy cache cleared
  • ๊ธฐ์กด fqdn ์ •์ฑ…๊ณผ ์บ์‹œ๊ฐ€ ๋‚จ์•„์žˆ์œผ๋ฉด ์ƒˆ ์ •์ฑ… ์ ์šฉ์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ์–ด ์ดˆ๊ธฐํ™” ์ˆ˜ํ–‰
1
2
3
4
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# c2 fqdn cache list

# ๊ฒฐ๊ณผ
Endpoint   Source   FQDN   TTL   ExpirationTime   IPs 

2. GitHub ํ•˜์œ„ ๋„๋ฉ”์ธ ํ—ˆ์šฉ ์ •์ฑ… ์ƒ์„ฑ (*.github.com)

(1) dns-pattern.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
  name: "fqdn"
spec:
  endpointSelector:
    matchLabels:
      org: empire
      class: mediabot
  egress:
  - toFQDNs:
    - matchName: "*.github.com"
  - toEndpoints:
    - matchLabels:
        "k8s:io.kubernetes.pod.namespace": kube-system
        "k8s:k8s-app": kube-dns
    toPorts:
    - ports:
      - port: "53"
        protocol: ANY
      rules:
        dns:
        - matchPattern: "*"

(2) ์ ์šฉ

1
2
3
4
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl apply -f https://raw.githubusercontent.com/cilium/cilium/1.18.1/examples/kubernetes-dns/dns-pattern.yaml

# ๊ฒฐ๊ณผ
ciliumnetworkpolicy.cilium.io/fqdn created

3. ์ •์ฑ… ์ ์šฉ ๊ฒฐ๊ณผ ํ™•์ธ

1
2
3
4
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# c1 fqdn names
c2 fqdn names
c1 fqdn cache list
c2 fqdn cache list

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
  "DNSPollNames": null,
  "FQDNPolicySelectors": []
}

{
  "DNSPollNames": null,
  "FQDNPolicySelectors": [
    {
      "regexString": "^[-a-zA-Z0-9_]*[.]github[.]com[.]$",
      "selectorString": "MatchName: , MatchPattern: *.github.com"
    }
  ]
}

Endpoint   Source   FQDN   TTL   ExpirationTime   IPs   
Endpoint   Source   FQDN   TTL   ExpirationTime   IPs  
  • *.github.com ํŒจํ„ด์ด ์ •๊ทœ์‹ ํ˜•ํƒœ๋กœ ๋ณ€ํ™˜๋˜์–ด ์ ์šฉ๋จ
  • ์บ์‹œ ๋ฆฌ์ŠคํŠธ ์ดˆ๊ธฐ ์ƒํƒœ๋Š” ๋น„์–ด ์žˆ์Œ

4. GitHub ํ•˜์œ„ ๋„๋ฉ”์ธ ์ ‘๊ทผ ํ…Œ์ŠคํŠธ

1
2
3
4
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl exec mediabot -- curl -I -s https://support.github.com | head -1

# ๊ฒฐ๊ณผ
HTTP/2 302 
1
2
3
4
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl exec mediabot -- curl -I -s https://gist.github.com | head -1

# ๊ฒฐ๊ณผ
HTTP/2 302
1
2
3
4
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl exec mediabot -- curl -I -s --max-time 5 https://github.com | head -1

# ๊ฒฐ๊ณผ
HTTP/2 200 
  • support.github.com ์š”์ฒญ โ†’ HTTP/2 302 (ํ—ˆ์šฉ)
  • gist.github.com ์š”์ฒญ โ†’ HTTP/2 302 (ํ—ˆ์šฉ)
  • github.com ์š”์ฒญ โ†’ HTTP/2 200 (์ฐจ๋‹จ ์˜ˆ์ƒ์ด์—ˆ์œผ๋‚˜ ์‹ค์ œ๋กœ๋Š” ํ—ˆ์šฉ๋˜๋Š” ๋™์ž‘)
    • ๊ณต์‹ ๋ฌธ์„œ ์„ค๋ช…์— ๋”ฐ๋ฅด๋ฉด *.github.com ์— github.com ์ž์ฒด๋Š” ํฌํ•จ๋˜์ง€ ์•Š์•„์•ผ ํ•จ โ†’ ์˜ˆ์ƒ๊ณผ ๋‹ค๋ฅธ ๊ฒฐ๊ณผ

5. ๋น„ํ—ˆ์šฉ ๋„๋ฉ”์ธ ์ ‘๊ทผ ํ…Œ์ŠคํŠธ

1
2
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl exec mediabot -- curl -I -s --max-time 5 https://cilium.io| head -1
command terminated with exit code 28


๐Ÿท๏ธ DNS Egress ์ •์ฑ… ์ ์šฉ 3 : DNS, Port ์กฐํ•ฉ ์ ์šฉ

1. ๊ธฐ์กด ์ •์ฑ… ๋ฐ ์บ์‹œ ์ดˆ๊ธฐํ™”

1
2
3
4
5
6
7
8
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl delete cnp fqdn
c1 fqdn cache clean -f
c2 fqdn cache clean -f

# ๊ฒฐ๊ณผ
ciliumnetworkpolicy.cilium.io "fqdn" deleted
FQDN proxy cache cleared
FQDN proxy cache cleared

2. DNS, Port ์กฐํ•ฉ ์ •์ฑ… ์ƒ์„ฑ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
  name: "fqdn"
spec:
  endpointSelector:
    matchLabels:
      org: empire
      class: mediabot
  egress:
  - toFQDNs:
    - matchPattern: "*.github.com"
    toPorts:
    - ports:
      - port: "443"
        protocol: TCP
  - toEndpoints:
    - matchLabels:
        "k8s:io.kubernetes.pod.namespace": kube-system
        "k8s:k8s-app": kube-dns
    toPorts:
    - ports:
      - port: "53"
        protocol: ANY
      rules:
        dns:
        - matchPattern: "*"
1
2
3
4
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl apply -f https://raw.githubusercontent.com/cilium/cilium/1.18.1/examples/kubernetes-dns/dns-port.yaml

# ๊ฒฐ๊ณผ
ciliumnetworkpolicy.cilium.io/fqdn created
  • .github.com ๋Œ€์ƒ์œผ๋กœ TCP 443(HTTPS) ๋งŒ ํ—ˆ์šฉํ•˜๋Š” ์ •์ฑ… ์ƒ์„ฑ
  • DNS ์งˆ์˜๋ฅผ ์œ„ํ•ด CoreDNS(53๋ฒˆ ํฌํŠธ)๋กœ์˜ ์ ‘๊ทผ์€ ๋ณ„๋„๋กœ ํ—ˆ์šฉ

3. ์ •์ฑ… ์ ์šฉ ๊ฒฐ๊ณผ ํ™•์ธ

1
2
3
4
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# c1 fqdn names
c2 fqdn names
c1 fqdn cache list
c2 fqdn cache list

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
  "DNSPollNames": null,
  "FQDNPolicySelectors": []
}

{
  "DNSPollNames": null,
  "FQDNPolicySelectors": [
    {
      "regexString": "^[-a-zA-Z0-9_]*[.]github[.]com[.]$",
      "selectorString": "MatchName: , MatchPattern: *.github.com"
    }
  ]
}

Endpoint   Source   FQDN   TTL   ExpirationTime   IPs   
Endpoint   Source   FQDN   TTL   ExpirationTime   IPs   

4. ๋„๋ฉ”์ธ ์ ‘๊ทผ ํ…Œ์ŠคํŠธ

1
2
3
4
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl exec mediabot -- curl -I -s https://support.github.com | head -1

# ๊ฒฐ๊ณผ
HTTP/2 302 
  • https://support.github.com ์š”์ฒญ โ†’ HTTP/2 302 (์ •์ƒ์ ์œผ๋กœ ํ—ˆ์šฉ๋จ)
1
2
3
4
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl exec mediabot -- curl -I -s --max-time 5 http://support.github.com | head -1

# ๊ฒฐ๊ณผ
command terminated with exit code 28
  • http://support.github.com ์š”์ฒญ โ†’ exit code 28 (์ •์ฑ…์— ๋”ฐ๋ผ ์ฐจ๋‹จ๋จ)

5. ์‹ค์Šต ๋ฆฌ์†Œ์Šค ์ •๋ฆฌ

1
2
3
4
5
6
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# c1 fqdn cache clean -f
c2 fqdn cache clean -f

# ๊ฒฐ๊ณผ
FQDN proxy cache cleared
FQDN proxy cache cleared
1
2
3
4
5
6
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl delete -f https://raw.githubusercontent.com/cilium/cilium/1.18.1/examples/kubernetes-dns/dns-sw-app.yaml
kubectl delete cnp fqdn

# ๊ฒฐ๊ณผ
pod "mediabot" deleted
ciliumnetworkpolicy.cilium.io "fqdn" deleted

๐Ÿ“ฆ ์ƒ˜ํ”Œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐฐํฌ ๋ฐ ํ†ต์‹  ๋ฌธ์ œ ํ™•์ธ

1. ์ƒ˜ํ”Œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐฐํฌ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# 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

# ๊ฒฐ๊ณผ
deployment.apps/webpod created
service/webpod created

2. k8s-ctr ๋…ธ๋“œ์— curl-pod ํŒŒ๋“œ ๋ฐฐํฌ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# 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

# ๊ฒฐ๊ณผ
pod/curl-pod created

๐Ÿ” [Lab2] WireGuard ์„ค์ • ๋ฐ ์‹ค์Šต : ํ„ฐ๋„ ๋ชจ๋“œ๋Š” ๋‘ ๋ฒˆ ์บก์Аํ™”๋จ

1. ์ปค๋„ WireGuard ์ง€์› ํ™•์ธ

1
2
3
4
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# uname -ar

# ๊ฒฐ๊ณผ
Linux k8s-ctr 6.8.0-64-generic #67-Ubuntu SMP PREEMPT_DYNAMIC Sun Jun 15 20:23:31 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
1
2
3
4
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# grep -E 'CONFIG_WIREGUARD=m' /boot/config-$(uname -r)

# ๊ฒฐ๊ณผ
CONFIG_WIREGUARD=m
  • CONFIG_WIREGUARD=m โ†’ Linux 5.6 ์ด์ƒ์—์„œ WireGuard ๋ชจ๋“ˆ ์‚ฌ์šฉ ๊ฐ€๋Šฅ ํ™•์ธ

2. WireGuard ํ™œ์„ฑํ™” ์ „ ๋„คํŠธ์›Œํฌ ์ƒํƒœ ํ™•์ธ

1
2
3
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# ip -c addr
ip -c route
ip rule show

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host noprefixroute 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 08:00:27:6d:e2:c4 brd ff:ff:ff:ff:ff:ff
    altname enp0s3
    inet 10.0.2.15/24 metric 100 brd 10.0.2.255 scope global dynamic eth0
       valid_lft 79621sec preferred_lft 79621sec
    inet6 fd17:625c:f037:2:a00:27ff:fe6d:e2c4/64 scope global dynamic mngtmpaddr noprefixroute 
       valid_lft 86122sec preferred_lft 14122sec
    inet6 fe80::a00:27ff:fe6d:e2c4/64 scope link 
       valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 08:00:27:1b:7e:53 brd ff:ff:ff:ff:ff:ff
    altname enp0s8
    inet 192.168.10.100/24 brd 192.168.10.255 scope global eth1
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:fe1b:7e53/64 scope link 
       valid_lft forever preferred_lft forever
4: cilium_net@cilium_host: <BROADCAST,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether aa:06:64:c5:fe:45 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::a806:64ff:fec5:fe45/64 scope link 
       valid_lft forever preferred_lft forever
5: cilium_host@cilium_net: <BROADCAST,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 12:77:a3:e7:d3:5d brd ff:ff:ff:ff:ff:ff
    inet 172.20.0.188/32 scope global cilium_host
       valid_lft forever preferred_lft forever
    inet6 fe80::1077:a3ff:fee7:d35d/64 scope link 
       valid_lft forever preferred_lft forever
7: lxc6e1bde6d9a82@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 02:a2:a1:c5:16:d2 brd ff:ff:ff:ff:ff:ff link-netns cni-66c371ca-2139-d948-994d-bbc0212eb89c
    inet6 fe80::a2:a1ff:fec5:16d2/64 scope link 
       valid_lft forever preferred_lft forever
9: lxc26e84e529505@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether f6:10:c8:bd:bd:13 brd ff:ff:ff:ff:ff:ff link-netns cni-42947c9d-0424-f65e-dfe9-be44ec108d3a
    inet6 fe80::f410:c8ff:febd:bd13/64 scope link 
       valid_lft forever preferred_lft forever
11: lxcf62e2cdd153a@if10: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether ca:b9:69:22:d2:e7 brd ff:ff:ff:ff:ff:ff link-netns cni-3c60e571-202c-2e3d-6edc-03db2dc9cfb3
    inet6 fe80::c8b9:69ff:fe22:d2e7/64 scope link 
       valid_lft forever preferred_lft forever
13: lxc053b4aa84d05@if12: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether f2:ca:88:ea:7a:9b brd ff:ff:ff:ff:ff:ff link-netns cni-7ce2feec-3b4f-bdbd-c538-9f507b25666a
    inet6 fe80::f0ca:88ff:feea:7a9b/64 scope link 
       valid_lft forever preferred_lft forever
15: lxce8925468e90e@if14: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether e6:5b:f3:b7:a2:10 brd ff:ff:ff:ff:ff:ff link-netns cni-937843ba-934d-8818-e990-b02ef54878d0
    inet6 fe80::e45b:f3ff:feb7:a210/64 scope link 
       valid_lft forever preferred_lft forever
17: lxcf22a71024ba4@if16: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 6e:56:09:c5:86:aa brd ff:ff:ff:ff:ff:ff link-netns cni-d76de399-05bd-1845-85fb-96c7c1a305ad
    inet6 fe80::6c56:9ff:fec5:86aa/64 scope link 
       valid_lft forever preferred_lft forever
23: lxc49a7fe1ea885@if22: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 8a:b5:82:36:0f:c8 brd ff:ff:ff:ff:ff:ff link-netns cni-315ff049-97c6-94ee-022a-e1b3e4e7c385
    inet6 fe80::88b5:82ff:fe36:fc8/64 scope link 
       valid_lft forever preferred_lft forever
       
default via 10.0.2.2 dev eth0 proto dhcp src 10.0.2.15 metric 100 
1.214.68.2 via 10.0.2.2 dev eth0 proto dhcp src 10.0.2.15 metric 100 
10.0.2.0/24 dev eth0 proto kernel scope link src 10.0.2.15 metric 100 
10.0.2.2 dev eth0 proto dhcp scope link src 10.0.2.15 metric 100 
61.41.153.2 via 10.0.2.2 dev eth0 proto dhcp src 10.0.2.15 metric 100 
172.20.0.95 dev lxcf22a71024ba4 proto kernel scope link 
172.20.0.112 dev lxc053b4aa84d05 proto kernel scope link 
172.20.0.119 dev lxc26e84e529505 proto kernel scope link 
172.20.0.181 dev lxc6e1bde6d9a82 proto kernel scope link 
172.20.0.195 dev lxc49a7fe1ea885 proto kernel scope link 
172.20.0.215 dev lxcf62e2cdd153a proto kernel scope link 
172.20.0.218 dev lxce8925468e90e proto kernel scope link 
172.20.1.0/24 via 192.168.10.101 dev eth1 proto kernel 
172.20.2.0/24 via 192.168.10.102 dev eth1 proto kernel 
192.168.10.0/24 dev eth1 proto kernel scope link src 192.168.10.100 

9:	from all fwmark 0x200/0xf00 lookup 2004
10:	from all fwmark 0xa00/0xf00 lookup 2005
100:	from all lookup local
32766:	from all lookup main
32767:	from all lookup default
  • ํ˜„์žฌ cilium_wg0 ์ธํ„ฐํŽ˜์ด์Šค ์—†์Œ โ†’ WireGuard ์•”ํ˜ธํ™” ์ ์šฉ ์ „ ๊ธฐ๋ณธ ๋„คํŠธ์›Œํฌ ์ƒํƒœ ํ™•์ธ

3. Cilium WireGuard ์•”ํ˜ธํ™” ํ™œ์„ฑํ™”

(1) Helm upgrade๋กœ Cilium์— WireGuard ์•”ํ˜ธํ™” ์˜ต์…˜ ์ ์šฉ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# helm upgrade cilium cilium/cilium --version 1.18.1 --namespace kube-system --reuse-values \
  --set encryption.enabled=true --set encryption.type=wireguard
  
# ๊ฒฐ๊ณผ 
I0907 09:15:56.120915   11365 warnings.go:110] "Warning: v1 Endpoints is deprecated in v1.33+; use discovery.k8s.io/v1 EndpointSlice"
I0907 09:15:56.121975   11365 warnings.go:110] "Warning: v1 Endpoints is deprecated in v1.33+; use discovery.k8s.io/v1 EndpointSlice"
I0907 09:15:56.126031   11365 warnings.go:110] "Warning: v1 Endpoints is deprecated in v1.33+; use discovery.k8s.io/v1 EndpointSlice"
Release "cilium" has been upgraded. Happy Helming!
NAME: cilium
LAST DEPLOYED: Sun Sep  7 09:15:54 2025
NAMESPACE: kube-system
STATUS: deployed
REVISION: 2
TEST SUITE: None
NOTES:
You have successfully installed Cilium with Hubble Relay and Hubble UI.

Your release version is 1.18.1.

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

(2) ์ ์šฉ ํ›„ DaemonSet ์žฌ์‹œ์ž‘

1
2
3
4
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl -n kube-system rollout restart ds/cilium

# ๊ฒฐ๊ณผ
daemonset.apps/cilium restarted

(3) ์ ์šฉ ๊ฒฐ๊ณผ

1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# cilium config view | grep -i wireguard

โœ…ย ์ถœ๋ ฅ

1
2
enable-wireguard                                  true
wireguard-persistent-keepalive                    0s

4. ์•”ํ˜ธํ™” ์ƒํƒœ ๋ฐ ํ‚ค ํ™•์ธ

1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl exec -it -n kube-system ds/cilium -- cilium encrypt status

โœ…ย ์ถœ๋ ฅ

1
2
3
4
Encryption: Wireguard                 
Interface: cilium_wg0
	Public key: 2Qoj+Ao91VcauXdQUBjrex80MmYqypiIzIeOJe6UWUM=
	Number of peers: 2
  • WireGuard ์•”ํ˜ธํ™” ํ™œ์„ฑํ™” ๋ฐ Public Key ํ‘œ์‹œ
1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl exec -it -n kube-system ds/cilium -- cilium status | grep Encryption

โœ…ย ์ถœ๋ ฅ

1
Encryption:              Wireguard   [NodeEncryption: Disabled, cilium_wg0 (Pubkey: 2Qoj+Ao91VcauXdQUBjrex80MmYqypiIzIeOJe6UWUM=, Port: 51871, Peers: 2)]
  • cilium_wg0 ์ธํ„ฐํŽ˜์ด์Šค์™€ Port(51871) ํ™•์ธ
  • ๊ฐ ๋…ธ๋“œ ๊ฐ„ Public Key ๊ตํ™˜์œผ๋กœ Peer ์ธ์ฆ ์ˆ˜ํ–‰

5. WireGuard ์ธํ„ฐํŽ˜์ด์Šค ํ™•์ธ

1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# ip -d -c addr show cilium_wg0

โœ…ย ์ถœ๋ ฅ

1
2
3
24: cilium_wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default 
    link/none  promiscuity 0  allmulti 0 minmtu 0 maxmtu 2147483552 
    wireguard numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535 tso_max_size 65536 tso_max_segs 65535 gro_max_size 65536 
1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# wg show

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
interface: cilium_wg0
  public key: Y5uWPr1Tmpyth78YEWFei83nNIN5Sl22IhUUbgdjBBU=
  private key: (hidden)
  listening port: 51871
  fwmark: 0xe00

peer: 2Qoj+Ao91VcauXdQUBjrex80MmYqypiIzIeOJe6UWUM=
  endpoint: 192.168.10.101:51871
  allowed ips: 172.20.1.113/32, 192.168.10.101/32, 172.20.1.249/32, 172.20.1.211/32, 172.20.1.0/24, 172.20.1.204/32
  latest handshake: 4 minutes, 54 seconds ago
  transfer: 524 B received, 468 B sent

peer: zJr4UGy+Ngkw7YirUtPbrrxzGbvwEnZwnCVLrtXXVmA=
  endpoint: 192.168.10.102:51871
  allowed ips: 192.168.10.102/32, 172.20.2.81/32, 172.20.2.0/24, 172.20.2.149/32, 172.20.2.84/32, 172.20.2.79/32
  latest handshake: 4 minutes, 54 seconds ago
  transfer: 316 B received, 324 B sent
  • Public/Private Key, Peer ์ •๋ณด, Handshake ๋ฐ ์ „์†ก๋Ÿ‰ ํ™•์ธ ๊ฐ€๋Šฅ

6. WireGuard ์ƒ์„ธ ์ •๋ณด ํ™•์ธ

1
2
3
4
5
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# wg show all public-key
wg show all private-key
wg show all preshared-keys
wg show all endpoints
wg show all transfer

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
cilium_wg0	Y5uWPr1Tmpyth78YEWFei83nNIN5Sl22IhUUbgdjBBU=
cilium_wg0	MJUHH5QDUjmK30yCaL7hT2ZvxdOewuaDF3Uuue1HS14=
cilium_wg0	2Qoj+Ao91VcauXdQUBjrex80MmYqypiIzIeOJe6UWUM=	(none)
cilium_wg0	zJr4UGy+Ngkw7YirUtPbrrxzGbvwEnZwnCVLrtXXVmA=	(none)
cilium_wg0	2Qoj+Ao91VcauXdQUBjrex80MmYqypiIzIeOJe6UWUM=	192.168.10.101:51871
zJr4UGy+Ngkw7YirUtPbrrxzGbvwEnZwnCVLrtXXVmA=	192.168.10.102:51871
cilium_wg0	2Qoj+Ao91VcauXdQUBjrex80MmYqypiIzIeOJe6UWUM=	524	468
cilium_wg0	zJr4UGy+Ngkw7YirUtPbrrxzGbvwEnZwnCVLrtXXVmA=	316	324
1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl get cn -o yaml | grep annotations -A1

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
    annotations:
      network.cilium.io/wg-pub-key: Y5uWPr1Tmpyth78YEWFei83nNIN5Sl22IhUUbgdjBBU=
--
    annotations:
      network.cilium.io/wg-pub-key: 2Qoj+Ao91VcauXdQUBjrex80MmYqypiIzIeOJe6UWUM=
--
    annotations:
      network.cilium.io/wg-pub-key: zJr4UGy+Ngkw7YirUtPbrrxzGbvwEnZwnCVLrtXXVmA=
  • ๊ฐ Cilium Node์˜ Public Key๋Š” Kubernetes Node ๋ฆฌ์†Œ์Šค ์• ๋…ธํ…Œ์ด์…˜์—๋„ ๊ธฐ๋ก๋จ

7. Pod ๊ฐ„ ํ†ต์‹  ํ™•์ธ (์•”ํ˜ธํ™” ๊ฒฝ๋กœ ํ…Œ์ŠคํŠธ)

1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# tcpdump -i cilium_wg0 -n
1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl exec -it curl-pod -- curl webpod

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
Hostname: webpod-697b545f57-zkb6k
IP: 127.0.0.1
IP: ::1
IP: 172.20.1.249
IP: fe80::102f:89ff:fe3c:e632
RemoteAddr: 172.20.0.195:35450
GET / HTTP/1.1
Host: webpod
User-Agent: curl/8.14.1
Accept: */*
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on cilium_wg0, link-type RAW (Raw IP), snapshot length 262144 bytes
09:29:32.237736 IP 172.20.0.195.53279 > 172.20.2.84.53: 20628+ [1au] A? webpod.default.svc.cluster.local. (73)
09:29:32.237954 IP 172.20.0.195.53279 > 172.20.2.84.53: 50422+ [1au] AAAA? webpod.default.svc.cluster.local. (73)
09:29:32.240059 IP 172.20.2.84.53 > 172.20.0.195.53279: 50422*- 0/1/1 (166)
09:29:32.240095 IP 172.20.2.84.53 > 172.20.0.195.53279: 20628*- 1/0/1 A 10.96.200.211 (121)
09:29:32.240747 IP 172.20.0.195.35450 > 172.20.1.249.80: Flags [S], seq 100649939, win 64860, options [mss 1380,sackOK,TS val 2403113329 ecr 0,nop,wscale 7], length 0
09:29:32.242105 IP 172.20.1.249.80 > 172.20.0.195.35450: Flags [S.], seq 116405546, ack 100649940, win 64296, options [mss 1380,sackOK,TS val 2757771911 ecr 2403113329,nop,wscale 7], length 0
09:29:32.242198 IP 172.20.0.195.35450 > 172.20.1.249.80: Flags [.], ack 1, win 507, options [nop,nop,TS val 2403113331 ecr 2757771911], length 0
09:29:32.242317 IP 172.20.0.195.35450 > 172.20.1.249.80: Flags [P.], seq 1:71, ack 1, win 507, options [nop,nop,TS val 2403113331 ecr 2757771911], length 70: HTTP: GET / HTTP/1.1
09:29:32.243266 IP 172.20.1.249.80 > 172.20.0.195.35450: Flags [.], ack 71, win 502, options [nop,nop,TS val 2757771912 ecr 2403113331], length 0
09:29:32.243853 IP 172.20.1.249.80 > 172.20.0.195.35450: Flags [P.], seq 1:323, ack 71, win 502, options [nop,nop,TS val 2757771913 ecr 2403113331], length 322: HTTP: HTTP/1.1 200 OK
09:29:32.243890 IP 172.20.0.195.35450 > 172.20.1.249.80: Flags [.], ack 323, win 505, options [nop,nop,TS val 2403113332 ecr 2757771913], length 0
09:29:32.244064 IP 172.20.0.195.35450 > 172.20.1.249.80: Flags [F.], seq 71, ack 323, win 505, options [nop,nop,TS val 2403113332 ecr 2757771913], length 0
09:29:32.245104 IP 172.20.1.249.80 > 172.20.0.195.35450: Flags [F.], seq 323, ack 72, win 502, options [nop,nop,TS val 2757771914 ecr 2403113332], length 0
09:29:32.245398 IP 172.20.0.195.35450 > 172.20.1.249.80: Flags [.], ack 324, win 505, options [nop,nop,TS val 2403113334 ecr 2757771914], length 0
  • tcpdump -i cilium_wg0 ๊ฒฐ๊ณผ, Pod ํ†ต์‹ ์ด WireGuard ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด ์บก์Аํ™”๋˜์–ด ํ๋ฆ„ ์ถ”์ ๋จ

8. ๋ฌผ๋ฆฌ ์ธํ„ฐํŽ˜์ด์Šค ํŠธ๋ž˜ํ”ฝ ์บก์ฒ˜

1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# tcpdump -eni any udp port 51871
1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl exec -it curl-pod -- curl webpod

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
11
Hostname: webpod-697b545f57-mmxjm
IP: 127.0.0.1
IP: ::1
IP: 172.20.2.149
IP: fe80::a4c5:4fff:fe8a:9a2e
RemoteAddr: 172.20.0.195:44090
GET / HTTP/1.1
Host: webpod
User-Agent: curl/8.14.1
Accept: */*
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
tcpdump: data link type LINUX_SLL2
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
09:33:22.875937 eth1  Out ifindex 3 08:00:27:1b:7e:53 ethertype IPv4 (0x0800), length 196: 192.168.10.100.51871 > 192.168.10.101.51871: UDP, length 148
09:33:22.876608 eth1  In  ifindex 3 08:00:27:9c:b4:fd ethertype IPv4 (0x0800), length 140: 192.168.10.101.51871 > 192.168.10.100.51871: UDP, length 92
09:33:22.876845 eth1  Out ifindex 3 08:00:27:1b:7e:53 ethertype IPv4 (0x0800), length 192: 192.168.10.100.51871 > 192.168.10.101.51871: UDP, length 144
09:33:22.876863 eth1  Out ifindex 3 08:00:27:1b:7e:53 ethertype IPv4 (0x0800), length 192: 192.168.10.100.51871 > 192.168.10.101.51871: UDP, length 144
09:33:22.877669 eth1  In  ifindex 3 08:00:27:9c:b4:fd ethertype IPv4 (0x0800), length 288: 192.168.10.101.51871 > 192.168.10.100.51871: UDP, length 240
09:33:22.877669 eth1  In  ifindex 3 08:00:27:9c:b4:fd ethertype IPv4 (0x0800), length 240: 192.168.10.101.51871 > 192.168.10.100.51871: UDP, length 192
09:33:22.878559 eth1  Out ifindex 3 08:00:27:1b:7e:53 ethertype IPv4 (0x0800), length 196: 192.168.10.100.51871 > 192.168.10.102.51871: UDP, length 148
09:33:22.879186 eth1  In  ifindex 3 08:00:27:2d:d6:34 ethertype IPv4 (0x0800), length 140: 192.168.10.102.51871 > 192.168.10.100.51871: UDP, length 92
09:33:22.879368 eth1  Out ifindex 3 08:00:27:1b:7e:53 ethertype IPv4 (0x0800), length 144: 192.168.10.100.51871 > 192.168.10.102.51871: UDP, length 96
09:33:22.879864 eth1  In  ifindex 3 08:00:27:2d:d6:34 ethertype IPv4 (0x0800), length 144: 192.168.10.102.51871 > 192.168.10.100.51871: UDP, length 96
09:33:22.880074 eth1  Out ifindex 3 08:00:27:1b:7e:53 ethertype IPv4 (0x0800), length 144: 192.168.10.100.51871 > 192.168.10.102.51871: UDP, length 96
09:33:22.880085 eth1  Out ifindex 3 08:00:27:1b:7e:53 ethertype IPv4 (0x0800), length 208: 192.168.10.100.51871 > 192.168.10.102.51871: UDP, length 160
09:33:22.880988 eth1  In  ifindex 3 08:00:27:2d:d6:34 ethertype IPv4 (0x0800), length 144: 192.168.10.102.51871 > 192.168.10.100.51871: UDP, length 96
09:33:22.880988 eth1  In  ifindex 3 08:00:27:2d:d6:34 ethertype IPv4 (0x0800), length 464: 192.168.10.102.51871 > 192.168.10.100.51871: UDP, length 416
09:33:22.881816 eth1  Out ifindex 3 08:00:27:1b:7e:53 ethertype IPv4 (0x0800), length 144: 192.168.10.100.51871 > 192.168.10.102.51871: UDP, length 96
09:33:22.881827 eth1  Out ifindex 3 08:00:27:1b:7e:53 ethertype IPv4 (0x0800), length 144: 192.168.10.100.51871 > 192.168.10.102.51871: UDP, length 96
09:33:22.882277 eth1  In  ifindex 3 08:00:27:2d:d6:34 ethertype IPv4 (0x0800), length 144: 192.168.10.102.51871 > 192.168.10.100.51871: UDP, length 96
09:33:22.882436 eth1  Out ifindex 3 08:00:27:1b:7e:53 ethertype IPv4 (0x0800), length 144: 192.168.10.100.51871 > 192.168.10.102.51871: UDP, length 96
09:33:32.960639 eth1  In  ifindex 3 08:00:27:2d:d6:34 ethertype IPv4 (0x0800), length 80: 192.168.10.102.51871 > 192.168.10.100.51871: UDP, length 32
09:33:33.018232 eth1  Out ifindex 3 08:00:27:1b:7e:53 ethertype IPv4 (0x0800), length 80: 192.168.10.100.51871 > 192.168.10.101.51871: UDP, length 32
  • ์‹ค์ œ ๋…ธ๋“œ NIC(eth1)์—์„œ UDP 51871 ํฌํŠธ๋กœ ์•”ํ˜ธํ™”๋œ ํŒจํ‚ท ๊ตํ™˜ ํ™•์ธ
  • 192.168.10.100.51871 > 192.168.10.101.51871

9. ํŒจํ‚ท ์ €์žฅ ๋ฐ ๋ณตํ˜ธํ™” ๋ถˆ๊ฐ€ ํ™•์ธ

1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# tcpdump -eni any udp port 51871 -w /tmp/wg.pcap
1
2
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl exec -it curl-pod -- curl webpod
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl exec -it curl-pod -- curl webpod
1
2
3
4
5
vagrant scp k8s-ctr:/tmp/wg.pcap .

# ๊ฒฐ๊ณผ
Warning: Permanently added '[127.0.0.1]:60000' (ED25519) to the list of known hosts.
wg.pcap                                                                                                                                             100% 6312     3.9MB/s   00:00    
1
termshark -r wg.pcap

โœ…ย ์ถœ๋ ฅ

  • ํŒจํ‚ท ๋‚ด์šฉ์€ ์•”ํ˜ธํ™”๋˜์–ด ์ค‘๊ฐ„์—์„œ ํƒˆ์ทจํ•˜๋”๋ผ๋„ ๋ณตํ˜ธํ™” ๋ถˆ๊ฐ€

10. Hubble ๋กœ๊น… ํ™•์ธ

1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# hubble observe --pod curl-pod

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
Sep  7 00:43:46.008: default/curl-pod:48687 (ID:49833) -> kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) to-endpoint FORWARDED (UDP)
Sep  7 00:43:46.008: default/curl-pod:48687 (ID:49833) <> kube-system/coredns-99ff8c6c4-fpx2g (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  7 00:43:46.009: default/curl-pod:48687 (ID:49833) <> kube-system/coredns-99ff8c6c4-fpx2g (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  7 00:43:46.009: default/curl-pod:48687 (ID:49833) <- kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) to-network FORWARDED (UDP)
Sep  7 00:43:46.010: default/curl-pod:42504 (ID:49833) -> default/webpod-697b545f57-mmxjm:80 (ID:48381) to-endpoint FORWARDED (TCP Flags: SYN)
Sep  7 00:43:46.010: default/curl-pod:42504 (ID:49833) <- default/webpod-697b545f57-mmxjm:80 (ID:48381) to-network FORWARDED (TCP Flags: SYN, ACK)
Sep  7 00:43:46.011: default/curl-pod:42504 (ID:49833) -> default/webpod-697b545f57-mmxjm:80 (ID:48381) to-endpoint FORWARDED (TCP Flags: ACK)
Sep  7 00:43:46.011: default/curl-pod:42504 (ID:49833) -> default/webpod-697b545f57-mmxjm:80 (ID:48381) to-endpoint FORWARDED (TCP Flags: ACK, PSH)
Sep  7 00:43:46.011: default/curl-pod:42504 (ID:49833) <> default/webpod-697b545f57-mmxjm (ID:48381) pre-xlate-rev TRACED (TCP)
Sep  7 00:43:46.011: default/curl-pod:42504 (ID:49833) <> default/webpod-697b545f57-mmxjm (ID:48381) pre-xlate-rev TRACED (TCP)
Sep  7 00:43:46.011: default/curl-pod:42504 (ID:49833) <> default/webpod-697b545f57-mmxjm (ID:48381) pre-xlate-rev TRACED (TCP)
Sep  7 00:43:46.012: default/curl-pod:42504 (ID:49833) <> default/webpod-697b545f57-mmxjm (ID:48381) pre-xlate-rev TRACED (TCP)
Sep  7 00:43:46.012: default/curl-pod:42504 (ID:49833) <> default/webpod-697b545f57-mmxjm (ID:48381) pre-xlate-rev TRACED (TCP)
Sep  7 00:43:46.012: default/curl-pod:42504 (ID:49833) <- default/webpod-697b545f57-mmxjm:80 (ID:48381) to-network FORWARDED (TCP Flags: ACK, PSH)
Sep  7 00:43:46.012: default/curl-pod:42504 (ID:49833) -> default/webpod-697b545f57-mmxjm:80 (ID:48381) to-endpoint FORWARDED (TCP Flags: ACK, FIN)
Sep  7 00:43:46.013: default/curl-pod:42504 (ID:49833) <- default/webpod-697b545f57-mmxjm:80 (ID:48381) to-network FORWARDED (TCP Flags: ACK, FIN)
Sep  7 00:43:46.013: default/curl-pod:42504 (ID:49833) <- default/webpod-697b545f57-mmxjm:80 (ID:48381) to-endpoint FORWARDED (TCP Flags: ACK, FIN)
Sep  7 00:43:46.013: default/curl-pod:42504 (ID:49833) -> default/webpod-697b545f57-mmxjm:80 (ID:48381) to-network FORWARDED (TCP Flags: ACK)
Sep  7 00:43:46.013: default/curl-pod:42504 (ID:49833) -> default/webpod-697b545f57-mmxjm:80 (ID:48381) to-endpoint FORWARDED (TCP Flags: ACK)
Sep  7 00:43:47.399: default/curl-pod (ID:49833) <> kube-system/kube-dns:53 (world) pre-xlate-fwd TRACED (UDP)
Sep  7 00:43:47.399: default/curl-pod (ID:49833) <> kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) post-xlate-fwd TRANSLATED (UDP)
Sep  7 00:43:47.399: default/curl-pod:42521 (ID:49833) -> kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) to-network FORWARDED (UDP)
Sep  7 00:43:47.401: default/curl-pod:42521 (ID:49833) -> kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) to-endpoint FORWARDED (UDP)
Sep  7 00:43:47.402: default/curl-pod:42521 (ID:49833) <> kube-system/coredns-99ff8c6c4-6zg5v (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  7 00:43:47.402: default/curl-pod:42521 (ID:49833) <> kube-system/coredns-99ff8c6c4-6zg5v (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  7 00:43:47.402: default/curl-pod:42521 (ID:49833) <- kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) to-network FORWARDED (UDP)
Sep  7 00:43:47.402: default/curl-pod:42521 (ID:49833) <- kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) to-endpoint FORWARDED (UDP)
Sep  7 00:43:47.402: kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) <> default/curl-pod (ID:49833) pre-xlate-rev TRACED (UDP)
Sep  7 00:43:47.402: kube-system/kube-dns:53 (world) <> default/curl-pod (ID:49833) post-xlate-rev TRANSLATED (UDP)
Sep  7 00:43:47.402: kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) <> default/curl-pod (ID:49833) pre-xlate-rev TRACED (UDP)
Sep  7 00:43:47.402: kube-system/kube-dns:53 (world) <> default/curl-pod (ID:49833) post-xlate-rev TRANSLATED (UDP)
Sep  7 00:43:47.402: default/curl-pod (ID:49833) <> default/webpod:80 (world) pre-xlate-fwd TRACED (TCP)
Sep  7 00:43:47.402: default/curl-pod (ID:49833) <> default/webpod-697b545f57-zkb6k:80 (ID:48381) post-xlate-fwd TRANSLATED (TCP)
Sep  7 00:43:47.402: default/curl-pod:38224 (ID:49833) -> default/webpod-697b545f57-zkb6k:80 (ID:48381) to-network FORWARDED (TCP Flags: SYN)
Sep  7 00:43:47.403: default/curl-pod:38224 (ID:49833) -> default/webpod-697b545f57-zkb6k:80 (ID:48381) to-endpoint FORWARDED (TCP Flags: SYN)
Sep  7 00:43:47.403: default/curl-pod:38224 (ID:49833) <- default/webpod-697b545f57-zkb6k:80 (ID:48381) to-network FORWARDED (TCP Flags: SYN, ACK)
Sep  7 00:43:47.403: default/curl-pod:38224 (ID:49833) <- default/webpod-697b545f57-zkb6k:80 (ID:48381) to-endpoint FORWARDED (TCP Flags: SYN, ACK)
Sep  7 00:43:47.403: default/curl-pod:38224 (ID:49833) -> default/webpod-697b545f57-zkb6k:80 (ID:48381) to-network FORWARDED (TCP Flags: ACK)
Sep  7 00:43:47.403: default/curl-pod:38224 (ID:49833) -> default/webpod-697b545f57-zkb6k:80 (ID:48381) to-network FORWARDED (TCP Flags: ACK, PSH)
Sep  7 00:43:47.404: default/curl-pod:38224 (ID:49833) -> default/webpod-697b545f57-zkb6k:80 (ID:48381) to-endpoint FORWARDED (TCP Flags: ACK)
Sep  7 00:43:47.404: default/curl-pod:38224 (ID:49833) -> default/webpod-697b545f57-zkb6k:80 (ID:48381) to-endpoint FORWARDED (TCP Flags: ACK, PSH)
Sep  7 00:43:47.404: default/curl-pod:38224 (ID:49833) <> default/webpod-697b545f57-zkb6k (ID:48381) pre-xlate-rev TRACED (TCP)
Sep  7 00:43:47.404: default/curl-pod:38224 (ID:49833) <> default/webpod-697b545f57-zkb6k (ID:48381) pre-xlate-rev TRACED (TCP)
Sep  7 00:43:47.404: default/curl-pod:38224 (ID:49833) <> default/webpod-697b545f57-zkb6k (ID:48381) pre-xlate-rev TRACED (TCP)
Sep  7 00:43:47.405: default/curl-pod:38224 (ID:49833) <> default/webpod-697b545f57-zkb6k (ID:48381) pre-xlate-rev TRACED (TCP)
Sep  7 00:43:47.405: default/curl-pod:38224 (ID:49833) <> default/webpod-697b545f57-zkb6k (ID:48381) pre-xlate-rev TRACED (TCP)
Sep  7 00:43:47.405: default/curl-pod:38224 (ID:49833) <- default/webpod-697b545f57-zkb6k:80 (ID:48381) to-network FORWARDED (TCP Flags: ACK, PSH)
Sep  7 00:43:47.405: default/curl-pod:38224 (ID:49833) <- default/webpod-697b545f57-zkb6k:80 (ID:48381) to-endpoint FORWARDED (TCP Flags: ACK, PSH)
Sep  7 00:43:47.405: default/curl-pod:38224 (ID:49833) -> default/webpod-697b545f57-zkb6k:80 (ID:48381) to-network FORWARDED (TCP Flags: ACK, FIN)
Sep  7 00:43:47.406: default/curl-pod:38224 (ID:49833) -> default/webpod-697b545f57-zkb6k:80 (ID:48381) to-endpoint FORWARDED (TCP Flags: ACK, FIN)
Sep  7 00:43:47.406: default/curl-pod:38224 (ID:49833) <- default/webpod-697b545f57-zkb6k:80 (ID:48381) to-network FORWARDED (TCP Flags: ACK, FIN)
Sep  7 00:43:47.406: default/curl-pod:38224 (ID:49833) <- default/webpod-697b545f57-zkb6k:80 (ID:48381) to-endpoint FORWARDED (TCP Flags: ACK, FIN)
Sep  7 00:43:47.406: default/curl-pod:38224 (ID:49833) -> default/webpod-697b545f57-zkb6k:80 (ID:48381) to-network FORWARDED (TCP Flags: ACK)
Sep  7 00:43:47.407: default/curl-pod:38224 (ID:49833) -> default/webpod-697b545f57-zkb6k:80 (ID:48381) to-endpoint FORWARDED (TCP Flags: ACK)
  • Pod ๊ฐ„ ์š”์ฒญ/์‘๋‹ต์ด ์•”ํ˜ธํ™”๋œ WireGuard ํ„ฐ๋„์„ ๊ฒฝ์œ ํ•˜์—ฌ ์ „๋‹ฌ๋˜๋Š” ๊ณผ์ • ํ™•์ธ

11. ์„ค์ • ์›๋ณต

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# helm upgrade cilium cilium/cilium --version 1.18.1 --namespace kube-system --reuse-values \
  --set encryption.enabled=false
  
# ๊ฒฐ๊ณผ  
I0907 09:47:15.951908   13591 warnings.go:110] "Warning: v1 Endpoints is deprecated in v1.33+; use discovery.k8s.io/v1 EndpointSlice"
I0907 09:47:15.956586   13591 warnings.go:110] "Warning: v1 Endpoints is deprecated in v1.33+; use discovery.k8s.io/v1 EndpointSlice"
I0907 09:47:15.965752   13591 warnings.go:110] "Warning: v1 Endpoints is deprecated in v1.33+; use discovery.k8s.io/v1 EndpointSlice"
Release "cilium" has been upgraded. Happy Helming!
NAME: cilium
LAST DEPLOYED: Sun Sep  7 09:47:11 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.18.1.

For any further help, visit https://docs.cilium.io/en/v1.18/gettinghelp
1
2
3
4
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl -n kube-system rollout restart ds/cilium

# ๊ฒฐ๊ณผ
daemonset.apps/cilium restarted

โš™๏ธ Inspecting TLS Encrypted Connections with Cilium

  • https://docs.cilium.io/en/stable/security/tls-visibility/
  • ๋Œ€๋ถ€๋ถ„์˜ ๋‚ด๋ถ€ ์‚ฌ์šฉ์ž๋Š” HTTPS(์•”ํ˜ธํ™”๋œ) ํŠธ๋ž˜ํ”ฝ์œผ๋กœ ์™ธ๋ถ€์™€ ํ†ต์‹ 
  • ์ผ๋ฐ˜ ๋ฐฉํ™”๋ฒฝ์€ ์•”ํ˜ธํ™”๋œ HTTPS ๋‚ด์šฉ์„ ์ง์ ‘ ๋ณผ ์ˆ˜ ์—†์–ด ์œ„ํ—˜ ์‚ฌ์ดํŠธ ์ ‘๊ทผ ์ฐจ๋‹จ ๋ถˆ๊ฐ€
  • ๋ณด์•ˆ์ด ๊ฐ•ํ™”๋œ ๊ธฐ์—… ํ™˜๊ฒฝ์—์„œ๋Š”, ์™ธ๋ถ€ ํ†ต์‹  ์‹œ Cilium์ด ์ค‘๊ฐ„์—์„œ TLS ํŠธ๋ž˜ํ”ฝ์„ ๊ฐ€๋กœ์ฑ„ ๋ชจ๋‹ˆํ„ฐ๋ง ๊ฐ€๋Šฅ

1. cilium-secrets ๋„ค์ž„์ŠคํŽ˜์ด์Šค ์กด์žฌ ํ™•์ธ

1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl get all,secret,cm -n cilium-secrets

โœ…ย ์ถœ๋ ฅ

1
2
NAME                         DATA   AGE
configmap/kube-root-ca.crt   1      19h

2. TLS ์„ค์ • ํŒŒ์ผ ์ƒ์„ฑ

1
2
3
4
5
6
7
8
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# cat << EOF > tls-config.yaml
tls:
  readSecretsOnlyFromSecretsNamespace: true
  secretsNamespace:
    name: cilium-secrets # This setting is optional, as it is the default
  secretSync:
    enabled: true
EOF
  • TLS ์ธ์ฆ์„œ/๋น„๋ฐ€์„ Cilium์ด ๊ฐ์‹œยท๋™๊ธฐํ™”ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ—ˆ์šฉ

3. Cilium ์žฌ๋ฐฐํฌ (TLS ์„ค์ • ๋ฐ˜์˜)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# helm upgrade cilium cilium/cilium --version 1.18.1 --namespace kube-system --reuse-values \
-f tls-config.yaml

# ๊ฒฐ๊ณผ
I0907 09:58:41.136472   14540 warnings.go:110] "Warning: v1 Endpoints is deprecated in v1.33+; use discovery.k8s.io/v1 EndpointSlice"
I0907 09:58:41.138440   14540 warnings.go:110] "Warning: v1 Endpoints is deprecated in v1.33+; use discovery.k8s.io/v1 EndpointSlice"
I0907 09:58:41.142939   14540 warnings.go:110] "Warning: v1 Endpoints is deprecated in v1.33+; use discovery.k8s.io/v1 EndpointSlice"
Release "cilium" has been upgraded. Happy Helming!
NAME: cilium
LAST DEPLOYED: Sun Sep  7 09:58:36 2025
NAMESPACE: kube-system
STATUS: deployed
REVISION: 4
TEST SUITE: None
NOTES:
You have successfully installed Cilium with Hubble Relay and Hubble UI.

Your release version is 1.18.1.

For any further help, visit https://docs.cilium.io/en/v1.18/gettinghelp
1
2
3
4
5
6
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl -n kube-system rollout restart deploy/cilium-operator
kubectl -n kube-system rollout restart ds/cilium

# ๊ฒฐ๊ณผ
deployment.apps/cilium-operator restarted
daemonset.apps/cilium restarted

4. TLS Secret ๋™๊ธฐํ™” ์„ค์ • ํ™•์ธ

1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# cilium config view | grep -i secret

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
enable-ingress-secrets-sync                       true
enable-policy-secrets-sync                        true
ingress-secrets-namespace                         cilium-secrets
policy-secrets-namespace                          cilium-secrets
policy-secrets-only-from-secrets-namespace        true

๐Ÿ›ก๏ธ [Lab3] Cilium TLS Interception Demo ์‹ค์Šต

1. Demo ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐฐํฌ (mediabot)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# cat << EOF > dns-sw-app.yaml
apiVersion: v1
kind: Pod
metadata:
  name: mediabot
  labels:
    org: empire
    class: mediabot
    app: mediabot
spec:
  containers:
  - name: mediabot
    image: quay.io/cilium/json-mock:v1.3.8@sha256:5aad04835eda9025fe4561ad31be77fd55309af8158ca8663a72f6abb78c2603
EOF
1
2
3
4
5
6
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl apply -f dns-sw-app.yaml
kubectl wait pod/mediabot --for=condition=Ready

# ๊ฒฐ๊ณผ
pod/mediabot created
pod/mediabot condition met
  • mediabot ํŒŒ๋“œ๋ฅผ ๋ฐฐํฌํ•˜์—ฌ Star Wars API(HTTPS ๊ธฐ๋ฐ˜) ์ ‘๊ทผ ํ…Œ์ŠคํŠธ ์ค€๋น„
  • HTTPS ํŠธ๋ž˜ํ”ฝ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ์•”ํ˜ธํ™”๋˜์–ด ๋„คํŠธ์›Œํฌ ๊ณ„์ธต(Cilium)์—์„œ HTTP ์„ธ๋ถ€ ์ •๋ณด ํ™•์ธ ๋ถˆ๊ฐ€
1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl get pods

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
NAME                      READY   STATUS    RESTARTS   AGE
curl-pod                  1/1     Running   0          16h
mediabot                  1/1     Running   0          40s
webpod-697b545f57-mmxjm   1/1     Running   0          16h
webpod-697b545f57-zkb6k   1/1     Running   0          16h

2. ๋‚ด๋ถ€ CA ํ‚ค ์ƒ์„ฑ

1
2
3
4
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# openssl genrsa -des3 -out myCA.key 2048

Enter PEM pass phrase: qwe123
Verifying - Enter PEM pass phrase: qwe123
  • openssl genrsa ๋ช…๋ น์œผ๋กœ CA ๊ฐœ์ธ ํ‚ค(myCA.key) ์ƒ์„ฑ
1
2
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# ls *.key
myCA.key

3. CA ์ธ์ฆ์„œ ์ƒ์„ฑ

1
2
3
4
5
6
7
8
9
10
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# openssl req -x509 -new -nodes -key myCA.key -sha256 -days 1825 -out myCA.crt

Enter pass phrase for myCA.key: qwe123
Country Name (2 letter code) [AU]:KR
State or Province Name (full name) [Some-State]:Seoul
Locality Name (eg, city) []:Seoul
Organization Name (eg, company) [Internet Widgits Pty Ltd]:cloudneta
Organizational Unit Name (eg, section) []:IT
Common Name (e.g. server FQDN or YOUR name) []:cloudneta.net
Email Address []:
  • ์ƒ์„ฑํ•œ myCA.key๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ž์ฒด ์„œ๋ช… CA ์ธ์ฆ์„œ(myCA.crt) ๋ฐœ๊ธ‰
1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# openssl x509 -in myCA.crt -noout -text

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            70:04:f6:77:46:af:71:1a:96:5a:81:a8:49:fb:76:ff:a7:e8:e6:d1
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = KR, ST = Seoul, L = Seoul, O = cloudneta, OU = IT, CN = cloudneta.net
        Validity
            Not Before: Sep  7 02:01:32 2025 GMT
            Not After : Sep  6 02:01:32 2030 GMT
        Subject: C = KR, ST = Seoul, L = Seoul, O = cloudneta, OU = IT, CN = cloudneta.net
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:a0:41:c3:47:6f:78:16:5a:db:67:f6:f2:49:07:
                    51:18:d9:77:1c:77:cd:6d:84:95:7f:9d:c1:ce:f6:
                    9b:01:52:0d:af:7d:8b:e2:d7:2c:41:e4:18:ea:4f:
                    fd:70:52:cf:1e:a1:f4:b1:6b:35:29:40:73:0d:7b:
                    ba:f9:03:9d:7c:9b:bb:bd:d8:dc:5a:d5:b5:5e:a8:
                    02:40:95:86:28:6f:17:dd:85:90:bc:ee:a5:15:9c:
                    d1:2b:d8:9a:ea:8e:92:93:3a:d9:b1:14:0f:4b:e6:
                    04:87:c3:33:ca:2d:8a:e8:a4:6b:08:34:5e:99:5e:
                    e1:56:90:3f:0d:69:fe:95:25:7c:e3:ac:ee:71:8e:
                    9d:3c:80:75:e4:97:9e:1c:cc:77:66:0a:a8:53:63:
                    da:7d:bd:9f:5c:81:b5:18:54:13:8a:bb:40:25:cc:
                    d0:28:79:09:cb:4f:8c:72:3c:1d:dd:48:8d:8f:10:
                    14:49:e3:c4:d4:fb:9c:a8:3a:07:b0:09:2a:44:18:
                    84:68:f7:b8:7c:23:95:51:82:7a:7e:20:83:15:f2:
                    f9:03:8a:98:6c:14:13:24:ca:33:8e:08:86:4f:9b:
                    62:52:5f:62:ea:b5:42:51:e7:84:3e:c5:48:5e:1f:
                    50:be:35:7b:61:68:57:4c:1c:27:2c:f8:05:a3:a7:
                    12:b3
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                24:41:F1:08:5B:13:03:5E:B3:FB:A9:20:D6:39:F1:2B:C6:46:6D:78
            X509v3 Authority Key Identifier: 
                24:41:F1:08:5B:13:03:5E:B3:FB:A9:20:D6:39:F1:2B:C6:46:6D:78
            X509v3 Basic Constraints: critical
                CA:TRUE
    Signature Algorithm: sha256WithRSAEncryption
    Signature Value:
        82:c8:3b:28:4b:a1:3f:1d:c8:d8:68:81:a2:8c:de:26:f3:bd:
        56:fe:2a:83:a4:b1:c8:59:13:0b:e8:77:02:02:6f:fb:3b:9e:
        00:e3:7b:c7:8a:02:b7:ca:74:9a:dc:ac:10:c6:af:f7:40:b2:
        9a:1f:f6:2d:91:6a:fa:3e:ee:48:8e:32:bb:0e:c0:bb:4a:00:
        aa:7c:87:bf:9a:50:e9:93:fd:37:8c:c4:6d:a1:dc:26:9e:09:
        8e:e8:81:85:13:2c:fa:ac:95:cb:47:c3:7d:4f:19:8c:ec:1d:
        f7:2d:ce:bc:ee:de:ac:9c:66:bb:e4:e6:79:68:1a:9c:48:aa:
        5f:da:8b:8f:27:8e:87:d5:d2:96:9e:97:2a:7c:63:bf:04:19:
        ed:06:a3:26:18:75:f2:cc:63:14:6c:44:af:89:fb:f2:9e:85:
        5f:dc:6a:09:7e:9d:4c:89:01:9f:a7:f0:c5:85:f2:90:f0:67:
        f1:ef:5a:34:98:3a:55:a8:54:41:f6:8d:fb:22:99:74:a1:3f:
        32:79:4f:0e:57:0e:d1:f7:3b:f3:3b:09:cd:39:ab:bf:ac:78:
        8f:98:5d:85:5e:7c:b2:92:11:35:6e:52:48:3d:b0:6c:4b:9c:
        de:35:3e:05:45:97:f5:7e:12:26:fc:ea:03:c9:08:cb:ce:3c:
        3c:14:b4:78
  • CA:TRUE ์†์„ฑ ํ™•์ธ โ†’ ๋ฃจํŠธ CA ๊ถŒํ•œ ๋ณด์œ 

4. ๋Œ€์ƒ ์„œ๋น„์Šค์šฉ ๊ฐœ์ธ ํ‚ค ๋ฐ CSR ์ƒ์„ฑ

1
2
3
4
5
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# openssl genrsa -out internal-httpbin.key 2048
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# ls internal-httpbin.key

# ๊ฒฐ๊ณผ
internal-httpbin.key
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# openssl req -new -key internal-httpbin.key -out internal-httpbin.csr

You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]: KR
State or Province Name (full name) [Some-State]:Seoul
Locality Name (eg, city) []:Seoul
Organization Name (eg, company) [Internet Widgits Pty Ltd]:cloudneta
Organizational Unit Name (eg, section) []:IT
Common Name (e.g. server FQDN or YOUR name) []:httpbin.org
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
1
2
3
4
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# ls internal-httpbin.csr

# ๊ฒฐ๊ณผ
internal-httpbin.csr

5. CA๋กœ ์„œ๋ช…๋œ ์ธ์ฆ์„œ ๋ฐœ๊ธ‰

1
2
3
4
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# openssl x509 -req -days 360 -in internal-httpbin.csr -CA myCA.crt -CAkey myCA.key -CAcreateserial -out internal-httpbin.crt -sha256
Certificate request self-signature ok
subject=C = KR, ST = Seoul, L = Seoul, O = cloudneta, OU = IT, CN = httpbin.org
Enter pass phrase for myCA.key: qwe123
1
2
3
4
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# ls internal-httpbin.crt

# ๊ฒฐ๊ณผ
internal-httpbin.crt
1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# openssl x509 -in internal-httpbin.crt -noout -text

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number:
            18:d7:be:ea:13:75:4b:40:c5:b1:6e:fe:16:16:ea:55:0d:ae:00:75
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = KR, ST = Seoul, L = Seoul, O = cloudneta, OU = IT, CN = cloudneta.net
        Validity
            Not Before: Sep  7 02:09:59 2025 GMT
            Not After : Sep  2 02:09:59 2026 GMT
        Subject: C = KR, ST = Seoul, L = Seoul, O = cloudneta, OU = IT, CN = httpbin.org
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:d1:4c:93:6e:74:c7:0f:70:cd:fd:36:8d:66:b9:
                    19:81:17:d4:b1:8e:60:6a:17:f2:43:eb:74:22:3a:
                    45:43:35:bf:40:84:44:ba:75:72:fb:6b:69:39:84:
                    b4:38:9e:6f:09:57:e4:2f:a0:e6:46:10:6b:74:2e:
                    bf:df:23:ee:0b:b6:51:62:a6:01:26:60:b1:4a:d0:
                    76:fe:a5:80:e6:cd:0b:60:b8:9d:d5:a8:45:63:7a:
                    78:4c:fc:eb:d1:85:76:e7:76:91:2c:1d:46:a4:41:
                    c9:54:5d:10:bf:23:68:f3:02:bc:a3:ff:4b:92:90:
                    e9:07:12:9c:17:0e:3a:cb:ac:20:01:a6:e4:8b:47:
                    6c:7e:fa:0a:30:76:c2:10:c7:3d:fe:ad:78:1f:f8:
                    e2:10:4e:74:f9:b7:90:78:8b:c7:e2:03:41:f2:27:
                    ed:b7:bc:a1:f9:db:0a:a8:71:41:5a:99:4e:51:e6:
                    d2:d5:9c:af:a6:cb:4b:be:e8:eb:89:2d:93:d4:c5:
                    fc:cc:5c:f3:7e:ee:71:56:b2:7d:36:fe:df:7a:2f:
                    39:b4:9d:24:34:c7:f8:cf:2a:a7:c5:2e:15:06:06:
                    f2:2f:17:d8:f3:da:9b:7f:16:96:ed:9c:14:ad:0f:
                    27:00:78:0f:fb:2a:5a:bd:20:2f:75:91:25:ce:95:
                    fa:d7
                Exponent: 65537 (0x10001)
    Signature Algorithm: sha256WithRSAEncryption
    Signature Value:
        03:52:66:d6:68:d6:02:33:23:8a:4b:f4:02:37:3f:fd:19:06:
        7c:1c:fd:50:f0:f1:3e:26:31:ee:00:a7:a9:db:52:ef:37:af:
        27:aa:b6:09:a3:9b:51:63:6d:bd:29:c4:48:74:2b:79:c0:6e:
        2b:75:80:fe:ee:4f:e3:cb:14:86:9d:4d:92:d6:08:a1:14:73:
        a6:90:67:ff:c0:b3:6a:8d:35:e9:14:66:af:a5:1a:00:50:cf:
        6e:e2:ed:e7:65:6a:e7:4d:49:9d:ba:16:eb:3e:86:1c:d8:ac:
        a2:5e:fb:7b:46:4e:f7:20:a4:66:ed:e0:fd:93:de:40:64:59:
        62:4e:be:78:75:d8:27:fd:72:a8:e6:ae:f0:e2:1a:8f:0c:9b:
        f6:2b:b4:d5:9a:59:4a:4e:e3:a9:c0:9f:c4:79:2d:cd:4a:8e:
        de:f2:2b:fc:c6:6f:f9:bc:fe:85:9f:6a:d8:2a:04:04:b3:30:
        ff:4b:54:12:56:cc:df:fc:94:63:c5:b5:37:f9:64:db:24:c9:
        c5:20:2c:9b:5f:70:b9:63:b7:cd:79:ec:64:79:17:71:e9:dd:
        81:54:6e:73:8a:18:d5:43:83:43:5a:66:5a:97:02:03:d2:ae:
        78:26:f2:93:b6:a7:5a:ac:3a:a4:ae:64:83:cf:53:03:46:79:
        19:bd:7e:b2
  • ๋ฐœ๊ธ‰๋œ ์ธ์ฆ์„œ Subject ํ•„๋“œ์—์„œ CN์ด httpbin.org ๋กœ ์„ค์ •๋œ ๊ฒƒ ํ™•์ธ

6. Kubernetes Secret ์ƒ์„ฑ (Terminating TLS)

1
2
3
4
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl create secret tls httpbin-tls-data -n kube-system --cert=internal-httpbin.crt --key=internal-httpbin.key

# ๊ฒฐ๊ณผ
secret/httpbin-tls-data created
1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl get secret -n kube-system  httpbin-tls-data

โœ…ย ์ถœ๋ ฅ

1
2
NAME               TYPE                DATA   AGE
httpbin-tls-data   kubernetes.io/tls   2      27s
  • Secret ์ •์ƒ ์ƒ์„ฑ ํ™•์ธ (kubernetes.io/tls ํƒ€์ž…, ๋ฐ์ดํ„ฐ 2๊ฐœ)

7. ํด๋ผ์ด์–ธํŠธ ํŒŒ๋“œ์— ๋‚ด๋ถ€ CA ์ถ”๊ฐ€

1
2
3
4
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl exec -it mediabot -- ls -l /usr/local/share/ca-certificates/

# ๊ฒฐ๊ณผ
total 0
1
2
3
4
5
6
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl cp myCA.crt default/mediabot:/usr/local/share/ca-certificates/myCA.crt
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl exec -it mediabot -- ls -l /usr/local/share/ca-certificates/

# ๊ฒฐ๊ณผ
total 4
-rw-r--r-- 1 root root 1334 Sep  7 02:14 myCA.crt
  • mediabot ํŒŒ๋“œ ๋‚ด /usr/local/share/ca-certificates/ ๋””๋ ‰ํ„ฐ๋ฆฌ์— myCA.crt ๋ณต์‚ฌ
1
2
3
4
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl exec -it mediabot -- ls -l /etc/ssl/certs/ca-certificates.crt

# ๊ฒฐ๊ณผ
-rw-r--r-- 1 root root 213777 Jan  9  2024 /etc/ssl/certs/ca-certificates.crt
1
2
3
4
5
6
7
8
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl exec mediabot -- update-ca-certificates

# ๊ฒฐ๊ณผ
Updating certificates in /etc/ssl/certs...
rehash: warning: skipping ca-certificates.crt,it does not contain exactly one certificate or CRL
1 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d...
done.
  • ๋‚ด๋ถ€ CA๋ฅผ ์‹œ์Šคํ…œ ์‹ ๋ขฐ CA ๋ชฉ๋ก์— ๋ฐ˜์˜
1
2
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl exec -it mediabot -- ls -l /etc/ssl/certs/ca-certificates.crt
-rw-r--r-- 1 root root 215111 Sep  7 02:16 /etc/ssl/certs/ca-certificates.crt
  • /etc/ssl/certs/ca-certificates.crt ํฌ๊ธฐ ์ฆ๊ฐ€ โ†’ ๋‚ด๋ถ€ CA๊ฐ€ ์ถ”๊ฐ€๋จ ํ™•์ธ

8. Cilium์— ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๋Š” CA ๋ชฉ๋ก ์ œ๊ณต

1
2
3
4
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl cp default/mediabot:/etc/ssl/certs/ca-certificates.crt ca-certificates.crt

# ๊ฒฐ๊ณผ
tar: Removing leading `/' from member names
  • mediabot ํŒŒ๋“œ์—์„œ /etc/ssl/certs/ca-certificates.crt ์ถ”์ถœ
1
2
3
4
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl create secret generic tls-orig-data -n kube-system --from-file=ca.crt=./ca-certificates.crt

# ๊ฒฐ๊ณผ
secret/tls-orig-data created
  • ์ด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ tls-orig-data Secret ์ƒ์„ฑ (kube-system ๋„ค์ž„์ŠคํŽ˜์ด์Šค)
  • Cilium์ด ์™ธ๋ถ€ TLS ์—ฐ๊ฒฐ ์‹œ ์‚ฌ์šฉํ•  ์‹ ๋ขฐ CA ๋ชฉ๋ก ์ œ๊ณต
1
2
3
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl get secret -n kube-system tls-orig-data
NAME            TYPE     DATA   AGE
tls-orig-data   Opaque   1      31s

๐Ÿ“‘ Apply DNS and TLS-aware Egress Policy

1. CiliumNetworkPolicy(l7-visibility-tls) ์ž‘์„ฑ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
  name: "l7-visibility-tls"
spec:
  description: L7 policy with TLS
  endpointSelector:
    matchLabels:
      org: empire
      class: mediabot
  egress:
  - toFQDNs:
    - matchName: "httpbin.org"
    toPorts:
    - ports:
      - port: "443"
        protocol: "TCP"
      terminatingTLS:
        secret:
          namespace: "kube-system"
          name: "httpbin-tls-data"
      originatingTLS:
        secret:
          namespace: "kube-system"
          name: "tls-orig-data"
      rules:
        http:
        - {}
  - toPorts:
    - ports:
      - port: "53"
        protocol: ANY
      rules:
        dns:
          - matchPattern: "*"

2. ์ •์ฑ… ์ ์šฉ ์ „ ํŠธ๋ž˜ํ”ฝ ์ƒํƒœ ํ™•์ธ

1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# hubble observe --pod mediabot -f
1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl exec -it mediabot -- curl -sL 'https://httpbin.org/anything'

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {}, 
  "headers": {
    "Accept": "*/*", 
    "Host": "httpbin.org", 
    "User-Agent": "curl/7.88.1", 
    "X-Amzn-Trace-Id": "Root=1-68bced16-291e405a1fbfd499591dde37"
  }, 
  "json": null, 
  "method": "GET", 
  "origin": "182.230.60.93", 
  "url": "https://httpbin.org/anything"
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
Sep  7 02:25:07.616: default/mediabot (ID:23265) <> kube-system/kube-dns:53 (world) pre-xlate-fwd TRACED (UDP)
Sep  7 02:25:07.616: default/mediabot (ID:23265) <> kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) post-xlate-fwd TRANSLATED (UDP)
Sep  7 02:25:07.616: default/mediabot:47008 (ID:23265) <> kube-system/coredns-99ff8c6c4-6zg5v (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  7 02:25:07.616: default/mediabot:47008 (ID:23265) <> kube-system/coredns-99ff8c6c4-6zg5v (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  7 02:25:07.616: default/mediabot:47008 (ID:23265) -> kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) to-endpoint FORWARDED (UDP)
Sep  7 02:25:07.616: default/mediabot:47008 (ID:23265) <- kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) to-endpoint FORWARDED (UDP)
Sep  7 02:25:07.616: kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) <> default/mediabot (ID:23265) pre-xlate-rev TRACED (UDP)
Sep  7 02:25:07.616: kube-system/kube-dns:53 (world) <> default/mediabot (ID:23265) post-xlate-rev TRANSLATED (UDP)
Sep  7 02:25:07.617: kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) <> default/mediabot (ID:23265) pre-xlate-rev TRACED (UDP)
Sep  7 02:25:07.617: kube-system/kube-dns:53 (world) <> default/mediabot (ID:23265) post-xlate-rev TRANSLATED (UDP)
Sep  7 02:25:07.617: default/mediabot (ID:23265) <> kube-system/kube-dns:53 (world) pre-xlate-fwd TRACED (UDP)
Sep  7 02:25:07.617: default/mediabot (ID:23265) <> kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) post-xlate-fwd TRANSLATED (UDP)
Sep  7 02:25:07.617: default/mediabot:33128 (ID:23265) -> kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) to-network FORWARDED (UDP)
Sep  7 02:25:07.617: default/mediabot:33128 (ID:23265) -> kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) to-endpoint FORWARDED (UDP)
Sep  7 02:25:07.617: default/mediabot:33128 (ID:23265) <> kube-system/coredns-99ff8c6c4-fpx2g (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  7 02:25:07.618: default/mediabot:33128 (ID:23265) <> kube-system/coredns-99ff8c6c4-fpx2g (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  7 02:25:07.618: default/mediabot:33128 (ID:23265) <- kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) to-endpoint FORWARDED (UDP)
Sep  7 02:25:07.618: kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) <> default/mediabot (ID:23265) pre-xlate-rev TRACED (UDP)
Sep  7 02:25:07.618: kube-system/kube-dns:53 (world) <> default/mediabot (ID:23265) post-xlate-rev TRANSLATED (UDP)
Sep  7 02:25:07.618: kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) <> default/mediabot (ID:23265) pre-xlate-rev TRACED (UDP)
Sep  7 02:25:07.618: kube-system/kube-dns:53 (world) <> default/mediabot (ID:23265) post-xlate-rev TRANSLATED (UDP)
Sep  7 02:25:07.618: default/mediabot (ID:23265) <> kube-system/kube-dns:53 (world) pre-xlate-fwd TRACED (UDP)
Sep  7 02:25:07.618: default/mediabot (ID:23265) <> kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) post-xlate-fwd TRANSLATED (UDP)
Sep  7 02:25:07.618: default/mediabot:33128 (ID:23265) <- kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) to-network FORWARDED (UDP)
Sep  7 02:25:07.618: default/mediabot:60232 (ID:23265) <> kube-system/coredns-99ff8c6c4-6zg5v (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  7 02:25:07.618: default/mediabot:60232 (ID:23265) <> kube-system/coredns-99ff8c6c4-6zg5v (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  7 02:25:07.618: default/mediabot:60232 (ID:23265) <- kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) to-endpoint FORWARDED (UDP)
Sep  7 02:25:07.618: default/mediabot:60232 (ID:23265) -> kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) to-endpoint FORWARDED (UDP)
Sep  7 02:25:07.618: kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) <> default/mediabot (ID:23265) pre-xlate-rev TRACED (UDP)
Sep  7 02:25:07.618: kube-system/kube-dns:53 (world) <> default/mediabot (ID:23265) post-xlate-rev TRANSLATED (UDP)
Sep  7 02:25:07.618: kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) <> default/mediabot (ID:23265) pre-xlate-rev TRACED (UDP)
Sep  7 02:25:07.618: kube-system/kube-dns:53 (world) <> default/mediabot (ID:23265) post-xlate-rev TRANSLATED (UDP)
Sep  7 02:25:07.618: default/mediabot (ID:23265) <> kube-system/kube-dns:53 (world) pre-xlate-fwd TRACED (UDP)
Sep  7 02:25:07.618: default/mediabot (ID:23265) <> kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) post-xlate-fwd TRANSLATED (UDP)
Sep  7 02:25:07.618: default/mediabot:44667 (ID:23265) -> kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) to-network FORWARDED (UDP)
Sep  7 02:25:07.619: default/mediabot:44667 (ID:23265) -> kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) to-endpoint FORWARDED (UDP)
Sep  7 02:25:07.619: default/mediabot:44667 (ID:23265) <> kube-system/coredns-99ff8c6c4-fpx2g (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  7 02:25:07.619: default/mediabot:44667 (ID:23265) <> kube-system/coredns-99ff8c6c4-fpx2g (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  7 02:25:07.628: default/mediabot:44667 (ID:23265) <- kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) to-endpoint FORWARDED (UDP)
Sep  7 02:25:07.628: default/mediabot:44667 (ID:23265) <- kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) to-network FORWARDED (UDP)
Sep  7 02:25:07.628: kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) <> default/mediabot (ID:23265) pre-xlate-rev TRACED (UDP)
Sep  7 02:25:07.628: kube-system/kube-dns:53 (world) <> default/mediabot (ID:23265) post-xlate-rev TRANSLATED (UDP)
Sep  7 02:25:07.699: kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) <> default/mediabot (ID:23265) pre-xlate-rev TRACED (UDP)
Sep  7 02:25:07.699: kube-system/kube-dns:53 (world) <> default/mediabot (ID:23265) post-xlate-rev TRANSLATED (UDP)
Sep  7 02:25:07.700: default/mediabot (ID:23265) <> kube-system/kube-dns:53 (world) pre-xlate-fwd TRACED (UDP)
Sep  7 02:25:07.700: default/mediabot (ID:23265) <> kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) post-xlate-fwd TRANSLATED (UDP)
Sep  7 02:25:07.700: default/mediabot:60434 (ID:23265) -> kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) to-network FORWARDED (UDP)
Sep  7 02:25:07.700: default/mediabot:60434 (ID:23265) -> kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) to-endpoint FORWARDED (UDP)
Sep  7 02:25:07.700: default/mediabot:60434 (ID:23265) <> kube-system/coredns-99ff8c6c4-fpx2g (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  7 02:25:07.700: default/mediabot:60434 (ID:23265) <> kube-system/coredns-99ff8c6c4-fpx2g (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  7 02:25:07.705: default/mediabot:60434 (ID:23265) <- kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) to-endpoint FORWARDED (UDP)
Sep  7 02:25:07.705: kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) <> default/mediabot (ID:23265) pre-xlate-rev TRACED (UDP)
Sep  7 02:25:07.705: kube-system/kube-dns:53 (world) <> default/mediabot (ID:23265) post-xlate-rev TRANSLATED (UDP)
Sep  7 02:25:07.705: default/mediabot:60434 (ID:23265) <- kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) to-network FORWARDED (UDP)
Sep  7 02:25:07.740: kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) <> default/mediabot (ID:23265) pre-xlate-rev TRACED (UDP)
Sep  7 02:25:07.740: kube-system/kube-dns:53 (world) <> default/mediabot (ID:23265) post-xlate-rev TRANSLATED (UDP)
Sep  7 02:25:07.740: default/mediabot:34984 (ID:23265) -> 52.71.132.100:443 (world) to-network FORWARDED (TCP Flags: SYN)
Sep  7 02:25:07.947: default/mediabot:34984 (ID:23265) <- 52.71.132.100:443 (world) to-endpoint FORWARDED (TCP Flags: SYN, ACK)
Sep  7 02:25:07.948: default/mediabot:34984 (ID:23265) -> 52.71.132.100:443 (world) to-network FORWARDED (TCP Flags: ACK)
Sep  7 02:25:07.948: 52.71.132.100:443 (world) <> default/mediabot (ID:23265) pre-xlate-rev TRACED (TCP)
Sep  7 02:25:07.949: default/mediabot:34984 (ID:23265) -> 52.71.132.100:443 (world) to-network FORWARDED (TCP Flags: ACK, PSH)
Sep  7 02:25:08.163: default/mediabot:34984 (ID:23265) <- 52.71.132.100:443 (world) to-endpoint FORWARDED (TCP Flags: ACK, PSH)
Sep  7 02:25:08.372: 52.71.132.100:443 (world) <> default/mediabot (ID:23265) pre-xlate-rev TRACED (TCP)
Sep  7 02:25:08.372: 52.71.132.100:443 (world) <> default/mediabot (ID:23265) pre-xlate-rev TRACED (TCP)
Sep  7 02:25:09.096: default/mediabot:34984 (ID:23265) -> 52.71.132.100:443 (world) to-network FORWARDED (TCP Flags: ACK, RST)
  • mediabot โ†’ https://httpbin.org/anything ์š”์ฒญ ์‹œ ์ •์ƒ 200 ์‘๋‹ต
  • Hubble ๋กœ๊ทธ์—๋Š” world IP ์ˆ˜์ค€๊นŒ์ง€๋งŒ ๊ธฐ๋ก๋˜๊ณ , L7 ์„ธ๋ถ€ ์ •๋ณด๋Š” ํ™•์ธ ๋ถˆ๊ฐ€
1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl exec -it mediabot -- curl -sL 'https://httpbin.org/headers' -v

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
*   Trying 44.195.242.49:443...
* Connected to httpbin.org (44.195.242.49) port 443 (#0)
* ALPN: offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: /etc/ssl/certs
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN: server accepted h2
* Server certificate:
*  subject: CN=httpbin.org
*  start date: Jul 20 00:00:00 2025 GMT
*  expire date: Aug 17 23:59:59 2026 GMT
*  subjectAltName: host "httpbin.org" matched cert's "httpbin.org"
*  issuer: C=US; O=Amazon; CN=Amazon RSA 2048 M03
*  SSL certificate verify ok.
* using HTTP/2
* h2h3 [:method: GET]
* h2h3 [:path: /headers]
* h2h3 [:scheme: https]
* h2h3 [:authority: httpbin.org]
* h2h3 [user-agent: curl/7.88.1]
* h2h3 [accept: */*]
* Using Stream ID: 1 (easy handle 0x5cef43e9ac80)
> GET /headers HTTP/2
> Host: httpbin.org
> user-agent: curl/7.88.1
> accept: */*
> 
< HTTP/2 200 
< date: Sun, 07 Sep 2025 02:27:09 GMT
< content-type: application/json
< content-length: 173
< server: gunicorn/19.9.0
< access-control-allow-origin: *
< access-control-allow-credentials: true
< 
{
  "headers": {
    "Accept": "*/*", 
    "Host": "httpbin.org", 
    "User-Agent": "curl/7.88.1", 
    "X-Amzn-Trace-Id": "Root=1-68bced7d-0275a60e6c1206872e96159a"
  }
}
* Connection #0 to host httpbin.org left intact
  • curl -v ์˜ต์…˜์œผ๋กœ ํ™•์ธ ์‹œ Amazon์—์„œ ๋ฐœ๊ธ‰ํ•œ ์ธ์ฆ์„œ๊ฐ€ ํ‘œ์‹œ๋จ

3. ์ •์ฑ… ์ ์šฉ (TLS ์ธ์‹ Egress Policy)

1
2
3
4
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl create -f https://raw.githubusercontent.com/cilium/cilium/1.18.1/examples/kubernetes-tls-inspection/l7-visibility-tls.yaml

# ๊ฒฐ๊ณผ
ciliumnetworkpolicy.cilium.io/l7-visibility-tls created

4. ์ •์ฑ… ์ ์šฉ ํ›„ L7 ๊ฐ€์‹œ์„ฑ ํ™•์ธ

1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# hubble observe --pod mediabot -f
1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl exec -it mediabot -- curl -sL 'https://httpbin.org/anything'

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {}, 
  "headers": {
    "Accept": "*/*", 
    "Host": "httpbin.org", 
    "User-Agent": "curl/7.88.1", 
    "X-Amzn-Trace-Id": "Root=1-68bcee86-162e56176873065d43ba22f7", 
    "X-Envoy-Expected-Rq-Timeout-Ms": "3600000", 
    "X-Envoy-Internal": "true"
  }, 
  "json": null, 
  "method": "GET", 
  "origin": "182.230.60.93", 
  "url": "https://httpbin.org/anything"
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
Sep  7 02:31:15.767: default/mediabot (ID:23265) <> kube-system/kube-dns:53 (world) pre-xlate-fwd TRACED (UDP)
Sep  7 02:31:15.767: default/mediabot (ID:23265) <> kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) post-xlate-fwd TRANSLATED (UDP)
Sep  7 02:31:15.767: default/mediabot:36388 (ID:23265) -> kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) policy-verdict:L4-Only EGRESS ALLOWED (UDP)
Sep  7 02:31:15.767: default/mediabot:36388 (ID:23265) -> kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) to-proxy FORWARDED (UDP)
Sep  7 02:31:15.767: default/mediabot:36388 (ID:23265) <> 192.168.10.101 (host) pre-xlate-rev TRACED (UDP)
Sep  7 02:31:15.767: default/mediabot:36388 (ID:23265) <> 192.168.10.101 (host) pre-xlate-rev TRACED (UDP)
Sep  7 02:31:15.768: default/mediabot:36388 (ID:23265) -> kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) dns-request proxy FORWARDED (DNS Query httpbin.org.default.svc.cluster.local. AAAA)
Sep  7 02:31:15.768: default/mediabot:36388 (ID:23265) -> kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) dns-request proxy FORWARDED (DNS Query httpbin.org.default.svc.cluster.local. A)
Sep  7 02:31:15.768: default/mediabot:36388 (ID:23265) -> kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) to-endpoint FORWARDED (UDP)
Sep  7 02:31:15.769: default/mediabot:36388 (ID:23265) <> kube-system/coredns-99ff8c6c4-fpx2g (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  7 02:31:15.769: default/mediabot:36388 (ID:23265) <> kube-system/coredns-99ff8c6c4-fpx2g (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  7 02:31:15.769: default/mediabot:36388 (ID:23265) <- kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) to-network FORWARDED (UDP)
Sep  7 02:31:15.769: default/mediabot:36388 (ID:23265) <- kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) to-proxy FORWARDED (UDP)
Sep  7 02:31:15.769: default/mediabot:36388 (ID:23265) <- kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) dns-response proxy FORWARDED (DNS Answer RCode: Non-Existent Domain TTL: 4294967295 (Proxy httpbin.org.default.svc.cluster.local. AAAA))
Sep  7 02:31:15.769: kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) <> default/mediabot (ID:23265) pre-xlate-rev TRACED (UDP)
Sep  7 02:31:15.769: kube-system/kube-dns:53 (world) <> default/mediabot (ID:23265) post-xlate-rev TRANSLATED (UDP)
Sep  7 02:31:15.770: default/mediabot:36388 (ID:23265) <- kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) dns-response proxy FORWARDED (DNS Answer RCode: Non-Existent Domain TTL: 4294967295 (Proxy httpbin.org.default.svc.cluster.local. A))
Sep  7 02:31:15.771: kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) <> default/mediabot (ID:23265) pre-xlate-rev TRACED (UDP)
Sep  7 02:31:15.771: kube-system/kube-dns:53 (world) <> default/mediabot (ID:23265) post-xlate-rev TRANSLATED (UDP)
Sep  7 02:31:15.771: default/mediabot (ID:23265) <> kube-system/kube-dns:53 (world) pre-xlate-fwd TRACED (UDP)
Sep  7 02:31:15.771: default/mediabot (ID:23265) <> kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) post-xlate-fwd TRANSLATED (UDP)
Sep  7 02:31:15.771: default/mediabot:60675 (ID:23265) -> kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) policy-verdict:L4-Only EGRESS ALLOWED (UDP)
Sep  7 02:31:15.771: default/mediabot:60675 (ID:23265) -> kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) to-proxy FORWARDED (UDP)
Sep  7 02:31:15.771: default/mediabot:60675 (ID:23265) <> 192.168.10.101 (host) pre-xlate-rev TRACED (UDP)
Sep  7 02:31:15.771: default/mediabot:60675 (ID:23265) <> 192.168.10.101 (host) pre-xlate-rev TRACED (UDP)
Sep  7 02:31:15.771: default/mediabot:60675 (ID:23265) -> kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) dns-request proxy FORWARDED (DNS Query httpbin.org.svc.cluster.local. AAAA)
Sep  7 02:31:15.771: default/mediabot:60675 (ID:23265) -> kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) dns-request proxy FORWARDED (DNS Query httpbin.org.svc.cluster.local. A)
Sep  7 02:31:15.772: default/mediabot:60675 (ID:23265) -> kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) to-endpoint FORWARDED (UDP)
Sep  7 02:31:15.772: default/mediabot:60675 (ID:23265) <> kube-system/coredns-99ff8c6c4-fpx2g (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  7 02:31:15.772: default/mediabot:60675 (ID:23265) <> kube-system/coredns-99ff8c6c4-fpx2g (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  7 02:31:15.772: default/mediabot:60675 (ID:23265) <- kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) to-network FORWARDED (UDP)
Sep  7 02:31:15.773: default/mediabot:60675 (ID:23265) <- kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) to-proxy FORWARDED (UDP)
Sep  7 02:31:15.773: default/mediabot:60675 (ID:23265) <- kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) dns-response proxy FORWARDED (DNS Answer RCode: Non-Existent Domain TTL: 4294967295 (Proxy httpbin.org.svc.cluster.local. A))
Sep  7 02:31:15.773: default/mediabot:60675 (ID:23265) <- kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) dns-response proxy FORWARDED (DNS Answer RCode: Non-Existent Domain TTL: 4294967295 (Proxy httpbin.org.svc.cluster.local. AAAA))
Sep  7 02:31:15.773: kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) <> default/mediabot (ID:23265) pre-xlate-rev TRACED (UDP)
Sep  7 02:31:15.773: kube-system/kube-dns:53 (world) <> default/mediabot (ID:23265) post-xlate-rev TRANSLATED (UDP)
Sep  7 02:31:15.773: kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) <> default/mediabot (ID:23265) pre-xlate-rev TRACED (UDP)
Sep  7 02:31:15.773: kube-system/kube-dns:53 (world) <> default/mediabot (ID:23265) post-xlate-rev TRANSLATED (UDP)
Sep  7 02:31:15.774: default/mediabot:55813 (ID:23265) -> kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) dns-request proxy FORWARDED (DNS Query httpbin.org.cluster.local. AAAA)
Sep  7 02:31:15.774: default/mediabot:55813 (ID:23265) -> kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) dns-request proxy FORWARDED (DNS Query httpbin.org.cluster.local. A)
Sep  7 02:31:15.774: default/mediabot (ID:23265) <> kube-system/kube-dns:53 (world) pre-xlate-fwd TRACED (UDP)
Sep  7 02:31:15.774: default/mediabot (ID:23265) <> kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) post-xlate-fwd TRANSLATED (UDP)
Sep  7 02:31:15.774: default/mediabot:55813 (ID:23265) -> kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) policy-verdict:L4-Only EGRESS ALLOWED (UDP)
Sep  7 02:31:15.774: default/mediabot:55813 (ID:23265) -> kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) to-proxy FORWARDED (UDP)
Sep  7 02:31:15.774: default/mediabot:55813 (ID:23265) <> 192.168.10.101 (host) pre-xlate-rev TRACED (UDP)
Sep  7 02:31:15.774: default/mediabot:55813 (ID:23265) <> 192.168.10.101 (host) pre-xlate-rev TRACED (UDP)
Sep  7 02:31:15.774: default/mediabot:55813 (ID:23265) -> kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) to-endpoint FORWARDED (UDP)
Sep  7 02:31:15.774: default/mediabot:55813 (ID:23265) <> kube-system/coredns-99ff8c6c4-6zg5v (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  7 02:31:15.774: default/mediabot:55813 (ID:23265) <- kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) dns-response proxy FORWARDED (DNS Answer RCode: Non-Existent Domain TTL: 4294967295 (Proxy httpbin.org.cluster.local. AAAA))
Sep  7 02:31:15.774: default/mediabot:55813 (ID:23265) <- kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) dns-response proxy FORWARDED (DNS Answer RCode: Non-Existent Domain TTL: 4294967295 (Proxy httpbin.org.cluster.local. A))
Sep  7 02:31:15.774: kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) <> default/mediabot (ID:23265) pre-xlate-rev TRACED (UDP)
Sep  7 02:31:15.775: kube-system/kube-dns:53 (world) <> default/mediabot (ID:23265) post-xlate-rev TRANSLATED (UDP)
Sep  7 02:31:15.775: default/mediabot:55813 (ID:23265) <> kube-system/coredns-99ff8c6c4-6zg5v (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  7 02:31:15.775: default/mediabot:55813 (ID:23265) <- kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) to-proxy FORWARDED (UDP)
Sep  7 02:31:15.775: kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) <> default/mediabot (ID:23265) pre-xlate-rev TRACED (UDP)
Sep  7 02:31:15.775: kube-system/kube-dns:53 (world) <> default/mediabot (ID:23265) post-xlate-rev TRANSLATED (UDP)
Sep  7 02:31:15.775: default/mediabot (ID:23265) <> kube-system/kube-dns:53 (world) pre-xlate-fwd TRACED (UDP)
Sep  7 02:31:15.775: default/mediabot (ID:23265) <> kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) post-xlate-fwd TRANSLATED (UDP)
Sep  7 02:31:15.775: default/mediabot:36959 (ID:23265) -> kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) policy-verdict:L4-Only EGRESS ALLOWED (UDP)
Sep  7 02:31:15.775: default/mediabot:36959 (ID:23265) -> kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) to-proxy FORWARDED (UDP)
Sep  7 02:31:15.775: default/mediabot:36959 (ID:23265) <> 192.168.10.101 (host) pre-xlate-rev TRACED (UDP)
Sep  7 02:31:15.775: default/mediabot:36959 (ID:23265) <> 192.168.10.101 (host) pre-xlate-rev TRACED (UDP)
Sep  7 02:31:15.775: default/mediabot:36959 (ID:23265) -> kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) dns-request proxy FORWARDED (DNS Query httpbin.org.davolink. A)
Sep  7 02:31:15.775: default/mediabot:36959 (ID:23265) -> kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) dns-request proxy FORWARDED (DNS Query httpbin.org.davolink. AAAA)
Sep  7 02:31:15.775: default/mediabot:36959 (ID:23265) -> kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) to-endpoint FORWARDED (UDP)
Sep  7 02:31:15.775: default/mediabot:36959 (ID:23265) <> kube-system/coredns-99ff8c6c4-fpx2g (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  7 02:31:15.776: default/mediabot:36959 (ID:23265) <> kube-system/coredns-99ff8c6c4-fpx2g (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  7 02:31:15.785: default/mediabot:36959 (ID:23265) <- kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) to-network FORWARDED (UDP)
Sep  7 02:31:15.786: default/mediabot:36959 (ID:23265) <- kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) to-proxy FORWARDED (UDP)
Sep  7 02:31:15.786: default/mediabot:36959 (ID:23265) <- kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) dns-response proxy FORWARDED (DNS Answer RCode: Non-Existent Domain TTL: 4294967295 (Proxy httpbin.org.davolink. A))
Sep  7 02:31:15.787: default/mediabot:36959 (ID:23265) <- kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) dns-response proxy FORWARDED (DNS Answer RCode: Non-Existent Domain TTL: 4294967295 (Proxy httpbin.org.davolink. AAAA))
Sep  7 02:31:15.787: kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) <> default/mediabot (ID:23265) pre-xlate-rev TRACED (UDP)
Sep  7 02:31:15.787: kube-system/kube-dns:53 (world) <> default/mediabot (ID:23265) post-xlate-rev TRANSLATED (UDP)
Sep  7 02:31:15.787: kube-system/coredns-99ff8c6c4-fpx2g:53 (ID:18194) <> default/mediabot (ID:23265) pre-xlate-rev TRACED (UDP)
Sep  7 02:31:15.787: kube-system/kube-dns:53 (world) <> default/mediabot (ID:23265) post-xlate-rev TRANSLATED (UDP)
Sep  7 02:31:15.787: default/mediabot (ID:23265) <> kube-system/kube-dns:53 (world) pre-xlate-fwd TRACED (UDP)
Sep  7 02:31:15.787: default/mediabot (ID:23265) <> kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) post-xlate-fwd TRANSLATED (UDP)
Sep  7 02:31:15.787: default/mediabot:58129 (ID:23265) -> kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) policy-verdict:L4-Only EGRESS ALLOWED (UDP)
Sep  7 02:31:15.787: default/mediabot:58129 (ID:23265) -> kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) to-proxy FORWARDED (UDP)
Sep  7 02:31:15.787: default/mediabot:58129 (ID:23265) <> 192.168.10.101 (host) pre-xlate-rev TRACED (UDP)
Sep  7 02:31:15.787: default/mediabot:58129 (ID:23265) <> 192.168.10.101 (host) pre-xlate-rev TRACED (UDP)
Sep  7 02:31:15.788: default/mediabot:58129 (ID:23265) -> kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) dns-request proxy FORWARDED (DNS Query httpbin.org. AAAA)
Sep  7 02:31:15.788: default/mediabot:58129 (ID:23265) -> kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) to-endpoint FORWARDED (UDP)
Sep  7 02:31:15.788: default/mediabot:58129 (ID:23265) -> kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) dns-request proxy FORWARDED (DNS Query httpbin.org. A)
Sep  7 02:31:15.788: default/mediabot:58129 (ID:23265) <> kube-system/coredns-99ff8c6c4-6zg5v (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  7 02:31:15.789: default/mediabot:58129 (ID:23265) <> kube-system/coredns-99ff8c6c4-6zg5v (ID:18194) pre-xlate-rev TRACED (UDP)
Sep  7 02:31:15.794: default/mediabot:58129 (ID:23265) <- kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) to-proxy FORWARDED (UDP)
Sep  7 02:31:15.795: default/mediabot:58129 (ID:23265) <- kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) dns-response proxy FORWARDED (DNS Answer  TTL: 4294967295 (Proxy httpbin.org. AAAA))
Sep  7 02:31:15.795: kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) <> default/mediabot (ID:23265) pre-xlate-rev TRACED (UDP)
Sep  7 02:31:15.795: kube-system/kube-dns:53 (world) <> default/mediabot (ID:23265) post-xlate-rev TRANSLATED (UDP)
Sep  7 02:31:15.797: default/mediabot:58129 (ID:23265) <- kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) dns-response proxy FORWARDED (DNS Answer "44.195.242.49,54.227.118.219,34.238.12.187,52.71.132.100,54.166.11.78,13.222.46.84" TTL: 30 (Proxy httpbin.org. A))
Sep  7 02:31:15.798: kube-system/coredns-99ff8c6c4-6zg5v:53 (ID:18194) <> default/mediabot (ID:23265) pre-xlate-rev TRACED (UDP)
Sep  7 02:31:15.798: kube-system/kube-dns:53 (world) <> default/mediabot (ID:23265) post-xlate-rev TRANSLATED (UDP)
Sep  7 02:31:15.798: default/mediabot:34464 (ID:23265) -> httpbin.org:443 (ID:16777217) policy-verdict:L3-L4 EGRESS ALLOWED (TCP Flags: SYN)
Sep  7 02:31:15.798: default/mediabot:34464 (ID:23265) -> httpbin.org:443 (ID:16777217) to-proxy FORWARDED (TCP Flags: SYN)
Sep  7 02:31:15.798: default/mediabot:34464 (ID:23265) <- httpbin.org:443 (ID:16777217) to-endpoint FORWARDED (TCP Flags: SYN, ACK)
Sep  7 02:31:15.798: default/mediabot:34464 (ID:23265) -> httpbin.org:443 (ID:16777217) to-proxy FORWARDED (TCP Flags: ACK)
Sep  7 02:31:15.799: httpbin.org:443 (ID:16777217) <> default/mediabot (ID:23265) pre-xlate-rev TRACED (TCP)
Sep  7 02:31:15.799: default/mediabot:34464 (ID:23265) <> 192.168.10.101 (host) pre-xlate-rev TRACED (TCP)
Sep  7 02:31:15.802: default/mediabot:34464 (ID:23265) -> httpbin.org:443 (ID:16777217) to-proxy FORWARDED (TCP Flags: ACK, PSH)
Sep  7 02:31:15.810: default/mediabot:34464 (ID:23265) <- httpbin.org:443 (ID:16777217) to-endpoint FORWARDED (TCP Flags: ACK, PSH)
Sep  7 02:31:15.842: httpbin.org:443 (ID:16777217) <> default/mediabot (ID:23265) pre-xlate-rev TRACED (TCP)
Sep  7 02:31:15.842: httpbin.org:443 (ID:16777217) <> default/mediabot (ID:23265) pre-xlate-rev TRACED (TCP)
Sep  7 02:31:15.843: default/mediabot:34464 (ID:23265) -> httpbin.org:443 (ID:16777217) http-request FORWARDED (HTTP/1.1 GET https://httpbin.org/anything)
Sep  7 02:31:16.651: default/mediabot:34464 (ID:23265) <- httpbin.org:443 (ID:16777217) http-response FORWARDED (HTTP/1.1 200 808ms (GET https://httpbin.org/anything))
Sep  7 02:31:16.652: default/mediabot:34464 (ID:23265) <- httpbin.org:443 (ID:16777217) to-endpoint FORWARDED (TCP Flags: ACK, FIN)
Sep  7 02:31:16.653: default/mediabot:34464 (ID:23265) -> httpbin.org:443 (ID:16777217) to-proxy FORWARDED (TCP Flags: ACK, RST)
  • mediabot โ†’ https://httpbin.org/anything ์š”์ฒญ ์‹œ ์—ฌ์ „ํžˆ ์ •์ƒ ์‘๋‹ต (200 OK)
  • Hubble ๋กœ๊ทธ์—์„œ HTTP L7 ๋ ˆ๋ฒจ ์„ธ๋ถ€์ •๋ณด ํ™•์ธ ๊ฐ€๋Šฅ
    • ex. (HTTP/1.1 GET https://httpbin.org/anything)
  • ์›๋ž˜๋Š” ์™ธ๋ถ€ IP๋งŒ ๊ธฐ๋ก๋์ง€๋งŒ, ์ด์ œ๋Š” L7 ์š”์ฒญ/์‘๋‹ต๊นŒ์ง€ ์ถ”์  ๊ฐ€๋Šฅ

5. ์„œ๋ฒ„ ์ธ์ฆ์„œ ํ™•์ธ (๋ณ€๊ฒฝ ํ™•์ธ)

1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl exec -it mediabot -- curl -sL 'https://httpbin.org/headers' -v

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
*   Trying 52.71.132.100:443...
* Connected to httpbin.org (52.71.132.100) port 443 (#0)
* ALPN: offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: /etc/ssl/certs
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN: server did not agree on a protocol. Uses default.
* Server certificate:
*  subject: C=KR; ST=Seoul; L=Seoul; O=cloudneta; OU=IT; CN=httpbin.org
*  start date: Sep  7 02:09:59 2025 GMT
*  expire date: Sep  2 02:09:59 2026 GMT
*  common name: httpbin.org (matched)
*  issuer: C=KR; ST=Seoul; L=Seoul; O=cloudneta; OU=IT; CN=cloudneta.net
*  SSL certificate verify ok.
* using HTTP/1.x
> GET /headers HTTP/1.1
> Host: httpbin.org
> User-Agent: curl/7.88.1
> Accept: */*
> 
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
< HTTP/1.1 200 OK
< date: Sun, 07 Sep 2025 02:35:31 GMT
< content-type: application/json
< content-length: 256
< server: envoy
< access-control-allow-origin: *
< access-control-allow-credentials: true
< x-envoy-upstream-service-time: 811
< 
{
  "headers": {
    "Accept": "*/*", 
    "Host": "httpbin.org", 
    "User-Agent": "curl/7.88.1", 
    "X-Amzn-Trace-Id": "Root=1-68bcef73-793ab92f5b0e49233cf3b64b", 
    "X-Envoy-Expected-Rq-Timeout-Ms": "3600000", 
    "X-Envoy-Internal": "true"
  }
}
* Connection #0 to host httpbin.org left intact
  • ๊ธฐ์กด: Amazon RSA 2048 M03 ๋ฐœ๊ธ‰ ์ธ์ฆ์„œ ํ‘œ์‹œ
  • ์ •์ฑ… ์ ์šฉ ํ›„: cloudneta.net ๋‚ด๋ถ€ CA๊ฐ€ ๋ฐœ๊ธ‰ํ•œ httpbin.org ์ธ์ฆ์„œ๋กœ ํ‘œ์‹œ

6. ์‹ค์Šต ๋ฆฌ์†Œ์Šค ์‚ญ์ œ

1
2
3
4
5
6
7
8
9
10
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl delete -f https://raw.githubusercontent.com/cilium/cilium/1.18.1/examples/kubernetes-dns/dns-sw-app.yaml
kubectl delete cnp l7-visibility-tls
kubectl delete secret -n kube-system tls-orig-data
kubectl delete secret -n kube-system httpbin-tls-data

# ๊ฒฐ๊ณผ
pod "mediabot" deleted
ciliumnetworkpolicy.cilium.io "l7-visibility-tls" deleted
secret "tls-orig-data" deleted
secret "httpbin-tls-data" deleted

๐Ÿ•ต๏ธ Tetragon

  • Tetragon์€ ๋ฆฌ๋ˆ…์Šค ์ปค๋„ ๋ ˆ๋ฒจ์—์„œ eBPF๋ฅผ ํ™œ์šฉํ•ด ํ”„๋กœ์„ธ์Šค ์‹คํ–‰, ์‹œ์Šคํ…œ ์ฝœ, ๋„คํŠธ์›Œํฌ ๋ฐ ํŒŒ์ผ I/O ์ด๋ฒคํŠธ๋ฅผ ํƒ์ง€ยท๋ชจ๋‹ˆํ„ฐ๋งยทํ†ต์ œ ๊ฐ€๋Šฅ
  • Kubernetes ํ™˜๊ฒฝ์„ ์ธ์‹ํ•˜์—ฌ ๋„ค์ž„์ŠคํŽ˜์ด์Šค, ํŒŒ๋“œ, ์›Œํฌ๋กœ๋“œ ๋‹จ์œ„ ๋ณด์•ˆ ์ด๋ฒคํŠธ ์ถ”์  ๋ฐ ์ •์ฑ… ์ ์šฉ ๊ฐ€๋Šฅ
  • eBPF ๋ ˆ๋ฒจ์—์„œ ์ •์ฑ…๊ณผ ํ•„ํ„ฐ๋ง์„ ์ง์ ‘ ์ ์šฉํ•˜๋Š” ๋Ÿฐํƒ€์ž„ ๋ณด์•ˆ ๋ฐ ๊ด€์ฐฐ ๋„๊ตฌ
  • https://tetragon.io/docs/getting-started/

1. Tetragon ์„ค์น˜

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# helm repo add cilium https://helm.cilium.io
helm repo update
helm install tetragon cilium/tetragon -n kube-system

# ๊ฒฐ๊ณผ
Error: repository name (cilium) already exists, please specify a different name
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "metrics-server" chart repository
...Successfully got an update from the "cilium" chart repository
Update Complete. โŽˆHappy Helming!โŽˆ
NAME: tetragon
LAST DEPLOYED: Sun Sep  7 11:44:41 2025
NAMESPACE: kube-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
1
2
3
4
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl rollout status -n kube-system ds/tetragon -w

# ๊ฒฐ๊ณผ
daemon set "tetragon" successfully rolled out

2. Tetragon Pod ๋ฐ ๊ตฌ์„ฑ ํ™•์ธ

1
2
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# k -n kube-system get deploy tetragon-operator -owide
k -n kube-system get cm tetragon-operator-config tetragon-config

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
NAME                READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS          IMAGES                                    SELECTOR
tetragon-operator   1/1     1            1           59s   tetragon-operator   quay.io/cilium/tetragon-operator:v1.5.0   app.kubernetes.io/instance=tetragon,app.kubernetes.io/name=tetragon-operator

NAME                       DATA   AGE
tetragon-operator-config   9      59s
tetragon-config            33     59s
1
2
3
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# k -n kube-system get ds tetragon -owide
k -n kube-system get svc,ep tetragon
k -n kube-system get svc,ep tetragon-operator-metrics

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
NAME       DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE    CONTAINERS               IMAGES                                                                      SELECTOR
tetragon   3         3         3       3            3           <none>          108s   export-stdout,tetragon   quay.io/cilium/hubble-export-stdout:v1.1.0,quay.io/cilium/tetragon:v1.5.0   app.kubernetes.io/instance=tetragon,app.kubernetes.io/name=tetragon

Warning: v1 Endpoints is deprecated in v1.33+; use discovery.k8s.io/v1 EndpointSlice
NAME               TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
service/tetragon   ClusterIP   10.96.203.139   <none>        2112/TCP   108s

NAME                 ENDPOINTS                                                     AGE
endpoints/tetragon   192.168.10.100:2112,192.168.10.101:2112,192.168.10.102:2112   108s

Warning: v1 Endpoints is deprecated in v1.33+; use discovery.k8s.io/v1 EndpointSlice
NAME                                TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
service/tetragon-operator-metrics   ClusterIP   10.96.239.199   <none>        2113/TCP   108s

NAME                                  ENDPOINTS         AGE
endpoints/tetragon-operator-metrics   172.20.1.5:2113   108s
1
2
3
`(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# k -n kube-system get pod -l app.kubernetes.io/part-of=tetragon -owide
k -n kube-system get pod -l app.kubernetes.io/name=tetragon
kc -n kube-system describe pod -l app.kubernetes.io/name=tetragon

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
NAME                                READY   STATUS    RESTARTS   AGE     IP               NODE      NOMINATED NODE   READINESS GATES
tetragon-8h56q                      2/2     Running   0          2m42s   192.168.10.102   k8s-w2    <none>           <none>
tetragon-fpq52                      2/2     Running   0          2m42s   192.168.10.100   k8s-ctr   <none>           <none>
tetragon-operator-58c6ddf88-5bfv6   1/1     Running   0          2m42s   172.20.1.5       k8s-w1    <none>           <none>
tetragon-xls2q                      2/2     Running   0          2m42s   192.168.10.101   k8s-w1    <none>           <none>

NAME             READY   STATUS    RESTARTS   AGE
tetragon-8h56q   2/2     Running   0          2m42s
tetragon-fpq52   2/2     Running   0          2m42s
tetragon-xls2q   2/2     Running   0          2m42s

Name:             tetragon-8h56q
Namespace:        kube-system
Priority:         0
Service Account:  tetragon
Node:             k8s-w2/192.168.10.102
Start Time:       Sun, 07 Sep 2025 11:44:42 +0900
Labels:           app.kubernetes.io/component=agent
                  app.kubernetes.io/instance=tetragon
                  app.kubernetes.io/managed-by=Helm
                  app.kubernetes.io/name=tetragon
                  app.kubernetes.io/part-of=tetragon
                  app.kubernetes.io/version=1.5.0
                  controller-revision-hash=9d9c7b5dd
                  helm.sh/chart=tetragon-1.5.0
                  pod-template-generation=1
Annotations:      checksum/configmap: 4b7a67f7d1778591e8c448707a378338bbd1353a88d4ea0e707be33d31db59e8
Status:           Running
IP:               192.168.10.102
IPs:
  IP:           192.168.10.102
Controlled By:  DaemonSet/tetragon
Containers:
  export-stdout:
    Container ID:  containerd://13c801156a13e828502827f4f36f01fc1ac0bbb0f35165424b98466a1de6ed81
    Image:         quay.io/cilium/hubble-export-stdout:v1.1.0
    Image ID:      quay.io/cilium/hubble-export-stdout@sha256:e1549e5852e32223e6db4e44ef883ed86c7659c260986b35c9a015e33d874437
    Port:          <none>
    Host Port:     <none>
    Command:
      hubble-export-stdout
    Args:
      /var/run/cilium/tetragon/tetragon.log
    State:          Running
      Started:      Sun, 07 Sep 2025 11:44:48 +0900
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/cilium/tetragon from export-logs (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-r4jvt (ro)
  tetragon:
    Container ID:  containerd://6906b3eb223092e25af31fb3ecd30ad8f11408337d754117d9726d9f6df4dfe5
    Image:         quay.io/cilium/tetragon:v1.5.0
    Image ID:      quay.io/cilium/tetragon@sha256:3f9ab530fa832c9c80244aa6776ba794abbd9c313ce6c3177a96b3991b01469c
    Port:          <none>
    Host Port:     <none>
    Args:
      --config-dir=/etc/tetragon/tetragon.conf.d/
    State:          Running
      Started:      Sun, 07 Sep 2025 11:45:02 +0900
    Ready:          True
    Restart Count:  0
    Liveness:       grpc <pod>:6789 liveness delay=0s timeout=60s period=10s #success=1 #failure=3
    Environment:
      NODE_NAME:   (v1:spec.nodeName)
    Mounts:
      /etc/tetragon/tetragon.conf.d/ from tetragon-config (ro)
      /procRoot from host-proc (rw)
      /sys/fs/bpf from bpf-maps (rw)
      /var/run/cilium from cilium-run (rw)
      /var/run/cilium/tetragon from export-logs (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-r4jvt (ro)
Conditions:
  Type                        Status
  PodReadyToStartContainers   True 
  Initialized                 True 
  Ready                       True 
  ContainersReady             True 
  PodScheduled                True 
Volumes:
  cilium-run:
    Type:          HostPath (bare host directory volume)
    Path:          /var/run/cilium
    HostPathType:  DirectoryOrCreate
  export-logs:
    Type:          HostPath (bare host directory volume)
    Path:          /var/run/cilium/tetragon
    HostPathType:  DirectoryOrCreate
  tetragon-config:
    Type:      ConfigMap (a volume populated by a ConfigMap)
    Name:      tetragon-config
    Optional:  false
  bpf-maps:
    Type:          HostPath (bare host directory volume)
    Path:          /sys/fs/bpf
    HostPathType:  DirectoryOrCreate
  host-proc:
    Type:          HostPath (bare host directory volume)
    Path:          /proc
    HostPathType:  Directory
  kube-api-access-r4jvt:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    Optional:                false
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 op=Exists
                             node.kubernetes.io/disk-pressure:NoSchedule op=Exists
                             node.kubernetes.io/memory-pressure:NoSchedule op=Exists
                             node.kubernetes.io/network-unavailable:NoSchedule op=Exists
                             node.kubernetes.io/not-ready:NoExecute op=Exists
                             node.kubernetes.io/pid-pressure:NoSchedule op=Exists
                             node.kubernetes.io/unreachable:NoExecute op=Exists
                             node.kubernetes.io/unschedulable:NoSchedule op=Exists
Events:
  Type    Reason     Age    From               Message
  ----    ------     ----   ----               -------
  Normal  Scheduled  2m42s  default-scheduler  Successfully assigned kube-system/tetragon-8h56q to k8s-w2
  Normal  Pulling    2m42s  kubelet            Pulling image "quay.io/cilium/hubble-export-stdout:v1.1.0"
  Normal  Pulled     2m36s  kubelet            Successfully pulled image "quay.io/cilium/hubble-export-stdout:v1.1.0" in 5.717s (5.717s including waiting). Image size: 1524888 bytes.
  Normal  Created    2m36s  kubelet            Created container: export-stdout
  Normal  Started    2m36s  kubelet            Started container export-stdout
  Normal  Pulling    2m36s  kubelet            Pulling image "quay.io/cilium/tetragon:v1.5.0"
  Normal  Pulled     2m23s  kubelet            Successfully pulled image "quay.io/cilium/tetragon:v1.5.0" in 13.387s (13.387s including waiting). Image size: 77257092 bytes.
  Normal  Created    2m23s  kubelet            Created container: tetragon
  Normal  Started    2m22s  kubelet            Started container tetragon

Name:             tetragon-fpq52
Namespace:        kube-system
Priority:         0
Service Account:  tetragon
Node:             k8s-ctr/192.168.10.100
Start Time:       Sun, 07 Sep 2025 11:44:42 +0900
Labels:           app.kubernetes.io/component=agent
                  app.kubernetes.io/instance=tetragon
                  app.kubernetes.io/managed-by=Helm
                  app.kubernetes.io/name=tetragon
                  app.kubernetes.io/part-of=tetragon
                  app.kubernetes.io/version=1.5.0
                  controller-revision-hash=9d9c7b5dd
                  helm.sh/chart=tetragon-1.5.0
                  pod-template-generation=1
Annotations:      checksum/configmap: 4b7a67f7d1778591e8c448707a378338bbd1353a88d4ea0e707be33d31db59e8
Status:           Running
IP:               192.168.10.100
IPs:
  IP:           192.168.10.100
Controlled By:  DaemonSet/tetragon
Containers:
  export-stdout:
    Container ID:  containerd://423fb266b39671cd0603498e93205f670c09ad0955731bc084f7dd1e0c9a1bed
    Image:         quay.io/cilium/hubble-export-stdout:v1.1.0
    Image ID:      quay.io/cilium/hubble-export-stdout@sha256:e1549e5852e32223e6db4e44ef883ed86c7659c260986b35c9a015e33d874437
    Port:          <none>
    Host Port:     <none>
    Command:
      hubble-export-stdout
    Args:
      /var/run/cilium/tetragon/tetragon.log
    State:          Running
      Started:      Sun, 07 Sep 2025 11:44:47 +0900
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/cilium/tetragon from export-logs (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-k2tqd (ro)
  tetragon:
    Container ID:  containerd://f61dc4c727a6b39b7cd46841345503f7dbdb98f08b4e1ca79cffa3715b4f945f
    Image:         quay.io/cilium/tetragon:v1.5.0
    Image ID:      quay.io/cilium/tetragon@sha256:3f9ab530fa832c9c80244aa6776ba794abbd9c313ce6c3177a96b3991b01469c
    Port:          <none>
    Host Port:     <none>
    Args:
      --config-dir=/etc/tetragon/tetragon.conf.d/
    State:          Running
      Started:      Sun, 07 Sep 2025 11:45:01 +0900
    Ready:          True
    Restart Count:  0
    Liveness:       grpc <pod>:6789 liveness delay=0s timeout=60s period=10s #success=1 #failure=3
    Environment:
      NODE_NAME:   (v1:spec.nodeName)
    Mounts:
      /etc/tetragon/tetragon.conf.d/ from tetragon-config (ro)
      /procRoot from host-proc (rw)
      /sys/fs/bpf from bpf-maps (rw)
      /var/run/cilium from cilium-run (rw)
      /var/run/cilium/tetragon from export-logs (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-k2tqd (ro)
Conditions:
  Type                        Status
  PodReadyToStartContainers   True 
  Initialized                 True 
  Ready                       True 
  ContainersReady             True 
  PodScheduled                True 
Volumes:
  cilium-run:
    Type:          HostPath (bare host directory volume)
    Path:          /var/run/cilium
    HostPathType:  DirectoryOrCreate
  export-logs:
    Type:          HostPath (bare host directory volume)
    Path:          /var/run/cilium/tetragon
    HostPathType:  DirectoryOrCreate
  tetragon-config:
    Type:      ConfigMap (a volume populated by a ConfigMap)
    Name:      tetragon-config
    Optional:  false
  bpf-maps:
    Type:          HostPath (bare host directory volume)
    Path:          /sys/fs/bpf
    HostPathType:  DirectoryOrCreate
  host-proc:
    Type:          HostPath (bare host directory volume)
    Path:          /proc
    HostPathType:  Directory
  kube-api-access-k2tqd:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    Optional:                false
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 op=Exists
                             node.kubernetes.io/disk-pressure:NoSchedule op=Exists
                             node.kubernetes.io/memory-pressure:NoSchedule op=Exists
                             node.kubernetes.io/network-unavailable:NoSchedule op=Exists
                             node.kubernetes.io/not-ready:NoExecute op=Exists
                             node.kubernetes.io/pid-pressure:NoSchedule op=Exists
                             node.kubernetes.io/unreachable:NoExecute op=Exists
                             node.kubernetes.io/unschedulable:NoSchedule op=Exists
Events:
  Type    Reason     Age    From               Message
  ----    ------     ----   ----               -------
  Normal  Scheduled  2m42s  default-scheduler  Successfully assigned kube-system/tetragon-fpq52 to k8s-ctr
  Normal  Pulling    2m42s  kubelet            Pulling image "quay.io/cilium/hubble-export-stdout:v1.1.0"
  Normal  Pulled     2m37s  kubelet            Successfully pulled image "quay.io/cilium/hubble-export-stdout:v1.1.0" in 5.123s (5.123s including waiting). Image size: 1524888 bytes.
  Normal  Created    2m37s  kubelet            Created container: export-stdout
  Normal  Started    2m37s  kubelet            Started container export-stdout
  Normal  Pulling    2m37s  kubelet            Pulling image "quay.io/cilium/tetragon:v1.5.0"
  Normal  Pulled     2m23s  kubelet            Successfully pulled image "quay.io/cilium/tetragon:v1.5.0" in 13.679s (13.679s including waiting). Image size: 77257092 bytes.
  Normal  Created    2m23s  kubelet            Created container: tetragon
  Normal  Started    2m23s  kubelet            Started container tetragon

Name:             tetragon-xls2q
Namespace:        kube-system
Priority:         0
Service Account:  tetragon
Node:             k8s-w1/192.168.10.101
Start Time:       Sun, 07 Sep 2025 11:44:42 +0900
Labels:           app.kubernetes.io/component=agent
                  app.kubernetes.io/instance=tetragon
                  app.kubernetes.io/managed-by=Helm
                  app.kubernetes.io/name=tetragon
                  app.kubernetes.io/part-of=tetragon
                  app.kubernetes.io/version=1.5.0
                  controller-revision-hash=9d9c7b5dd
                  helm.sh/chart=tetragon-1.5.0
                  pod-template-generation=1
Annotations:      checksum/configmap: 4b7a67f7d1778591e8c448707a378338bbd1353a88d4ea0e707be33d31db59e8
Status:           Running
IP:               192.168.10.101
IPs:
  IP:           192.168.10.101
Controlled By:  DaemonSet/tetragon
Containers:
  export-stdout:
    Container ID:  containerd://cfcc56cdf2a8b3b549322adc6563696a55fe54b9cadda67bdaa27fdfe6203ee1
    Image:         quay.io/cilium/hubble-export-stdout:v1.1.0
    Image ID:      quay.io/cilium/hubble-export-stdout@sha256:e1549e5852e32223e6db4e44ef883ed86c7659c260986b35c9a015e33d874437
    Port:          <none>
    Host Port:     <none>
    Command:
      hubble-export-stdout
    Args:
      /var/run/cilium/tetragon/tetragon.log
    State:          Running
      Started:      Sun, 07 Sep 2025 11:44:47 +0900
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/cilium/tetragon from export-logs (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-ndq5m (ro)
  tetragon:
    Container ID:  containerd://c71f95d322d8d2b5315230b03adef4f3314e7a371d924c721aa90af1bee9d71e
    Image:         quay.io/cilium/tetragon:v1.5.0
    Image ID:      quay.io/cilium/tetragon@sha256:3f9ab530fa832c9c80244aa6776ba794abbd9c313ce6c3177a96b3991b01469c
    Port:          <none>
    Host Port:     <none>
    Args:
      --config-dir=/etc/tetragon/tetragon.conf.d/
    State:          Running
      Started:      Sun, 07 Sep 2025 11:45:10 +0900
    Ready:          True
    Restart Count:  0
    Liveness:       grpc <pod>:6789 liveness delay=0s timeout=60s period=10s #success=1 #failure=3
    Environment:
      NODE_NAME:   (v1:spec.nodeName)
    Mounts:
      /etc/tetragon/tetragon.conf.d/ from tetragon-config (ro)
      /procRoot from host-proc (rw)
      /sys/fs/bpf from bpf-maps (rw)
      /var/run/cilium from cilium-run (rw)
      /var/run/cilium/tetragon from export-logs (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-ndq5m (ro)
Conditions:
  Type                        Status
  PodReadyToStartContainers   True 
  Initialized                 True 
  Ready                       True 
  ContainersReady             True 
  PodScheduled                True 
Volumes:
  cilium-run:
    Type:          HostPath (bare host directory volume)
    Path:          /var/run/cilium
    HostPathType:  DirectoryOrCreate
  export-logs:
    Type:          HostPath (bare host directory volume)
    Path:          /var/run/cilium/tetragon
    HostPathType:  DirectoryOrCreate
  tetragon-config:
    Type:      ConfigMap (a volume populated by a ConfigMap)
    Name:      tetragon-config
    Optional:  false
  bpf-maps:
    Type:          HostPath (bare host directory volume)
    Path:          /sys/fs/bpf
    HostPathType:  DirectoryOrCreate
  host-proc:
    Type:          HostPath (bare host directory volume)
    Path:          /proc
    HostPathType:  Directory
  kube-api-access-ndq5m:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    Optional:                false
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 op=Exists
                             node.kubernetes.io/disk-pressure:NoSchedule op=Exists
                             node.kubernetes.io/memory-pressure:NoSchedule op=Exists
                             node.kubernetes.io/network-unavailable:NoSchedule op=Exists
                             node.kubernetes.io/not-ready:NoExecute op=Exists
                             node.kubernetes.io/pid-pressure:NoSchedule op=Exists
                             node.kubernetes.io/unreachable:NoExecute op=Exists
                             node.kubernetes.io/unschedulable:NoSchedule op=Exists
Events:
  Type    Reason     Age    From               Message
  ----    ------     ----   ----               -------
  Normal  Scheduled  2m42s  default-scheduler  Successfully assigned kube-system/tetragon-xls2q to k8s-w1
  Normal  Pulling    2m42s  kubelet            Pulling image "quay.io/cilium/hubble-export-stdout:v1.1.0"
  Normal  Pulled     2m37s  kubelet            Successfully pulled image "quay.io/cilium/hubble-export-stdout:v1.1.0" in 4.382s (4.382s including waiting). Image size: 1524888 bytes.
  Normal  Created    2m37s  kubelet            Created container: export-stdout
  Normal  Started    2m37s  kubelet            Started container export-stdout
  Normal  Pulling    2m37s  kubelet            Pulling image "quay.io/cilium/tetragon:v1.5.0"
  Normal  Pulled     2m14s  kubelet            Successfully pulled image "quay.io/cilium/tetragon:v1.5.0" in 10.055s (23.493s including waiting). Image size: 77257092 bytes.
  Normal  Created    2m14s  kubelet            Created container: tetragon
  Normal  Started    2m14s  kubelet            Started container tetragon

3. ๋ฐ๋ชจ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐฐํฌ

1
2
3
4
5
6
7
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl create -f https://raw.githubusercontent.com/cilium/cilium/v1.18.1/examples/minikube/http-sw-app.yaml

# ๊ฒฐ๊ณผ
service/deathstar created
deployment.apps/deathstar created
pod/tiefighter created
pod/xwing created

4. ํ”„๋กœ์„ธ์Šค ์‹คํ–‰ ๋ชจ๋‹ˆํ„ฐ๋ง (Execution Events)

1
2
3
4
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# POD=$(kubectl -n kube-system get pods -l 'app.kubernetes.io/name=tetragon' -o name --field-selector spec.nodeName=$(kubectl get pod xwing -o jsonpath='{.spec.nodeName}'))
echo $POD

pod/tetragon-8h56q
1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl exec -ti -n kube-system $POD -c tetragon -- tetra getevents -o compact --pods xwing
1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl exec -ti xwing -- bash -c 'curl https://ebpf.io/applications/#tetragon'

โœ…ย ์ถœ๋ ฅ

1
2
3
<!DOCTYPE html><html lang="en" prefix="og: http://ogp.me/ns#"><head><meta charSet="utf-8"/><meta http-equiv="x-ua-compatible" content="ie=edge"/><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, viewport-fit=cover"/><link rel="preload" href="/fonts/elza/elza-semibold.woff2" as="font" type="font/woff2" crossorigin="anonymous"/><link rel="preload" href="/fonts/elza-text/elza-text-medium.woff2" as="font" type="font/woff2" crossorigin="anonymous"/><meta name="generator" content="Gatsby 5.14.6"/><meta name="description" content="A directory of eBPF-based open source applications" data-gatsby-head="true"/><meta name="keywords" content="ebpf, bpf, landscape, directory, open source" data-gatsby-head="true"/><meta property="og:title" content="eBPF Applications Landscape" data-gatsby-head="true"/><meta property="og:description" content="A directory of eBPF-based open source applications" data-gatsby-head="true"/><meta property="og:url" content="https://ebpf.io/applications/" data-gatsby-head="true"/><meta property="og:image" content="https://ebpf.io/images/social-preview.jpg" data-gatsby-head="true"/><meta property="og:type" content="website" data-gatsby-head="true"/><meta name="twitter:card" content="summary_large_image" data-gatsby-head="true"/><style data-href="/styles.6dc50e72f6ab2660031c.css" data-identity="gatsby-global-css">/*
! tailwindcss v3.4.7 | MIT License | https://tailwindcss.com
....
1
2
3
๐Ÿš€ process default/xwing /usr/bin/bash -c "curl https://ebpf.io/applications/#tetragon" 
๐Ÿš€ process default/xwing /usr/bin/curl https://ebpf.io/applications/#tetragon 
๐Ÿ’ฅ exit    default/xwing /usr/bin/curl https://ebpf.io/applications/#tetragon 0 
  • xwing ํŒŒ๋“œ ๋‚ด์—์„œ curl ์‹คํ–‰ ์‹œ Tetragon ๋กœ๊ทธ์— ๋‹ค์Œ ์ด๋ฒคํŠธ ๊ธฐ๋ก๋จ
    • bash -c "curl https://ebpf.io/applications/#tetragon" ์‹คํ–‰ ์ด๋ฒคํŠธ ๊ฐ์ง€
    • curl ํ”„๋กœ์„ธ์Šค ์‹คํ–‰ ๋ฐ ์ข…๋ฃŒ(exit 0) ์ด๋ฒคํŠธ ๊ฐ์ง€

5. ๋„คํŠธ์›Œํฌ ์•ก์„ธ์Šค ๋ชจ๋‹ˆํ„ฐ๋ง

1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl exec -ti xwing -- bash -c 'curl https://httpbin.org'

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>httpbin.org</title>
    <link href="https://fonts.googleapis.com/css?family=Open+Sans:400,700|Source+Code+Pro:300,600|Titillium+Web:400,600,700"
        rel="stylesheet">
    <link rel="stylesheet" type="text/css" href="/flasgger_static/swagger-ui.css">
    <link rel="icon" type="image/png" href="/static/favicon.ico" sizes="64x64 32x32 16x16" />
    <style>
        html {
            box-sizing: border-box;
            overflow: -moz-scrollbars-vertical;
            overflow-y: scroll;
        }

        *,
        *:before,
        *:after {
            box-sizing: inherit;
        }

        body {
            margin: 0;
            background: #fafafa;
        }
    </style>
</head>
...
1
2
3
๐Ÿš€ process default/xwing /usr/bin/bash -c "curl https://httpbin.org"      
๐Ÿš€ process default/xwing /usr/bin/curl https://httpbin.org                
๐Ÿ’ฅ exit    default/xwing /usr/bin/curl https://httpbin.org 0  
  • xwing ํŒŒ๋“œ์—์„œ curl https://httpbin.org ์‹คํ–‰
  • ์™ธ๋ถ€ ์‚ฌ์ดํŠธ ์ ‘๊ทผ ์ด๋ฒคํŠธ๊ฐ€ ํ”„๋กœ์„ธ์Šค ์‹คํ–‰ ์ด๋ฒคํŠธ๋กœ ๊ธฐ๋ก๋จ
  • curl ํ”„๋กœ์„ธ์Šค ์‹คํ–‰ ๋ฐ ์ข…๋ฃŒ ์ƒํƒœ ์ฝ”๋“œ(0) ํ™•์ธ

6. ํŒŒ์ผ ์ ‘๊ทผ ๋ชจ๋‹ˆํ„ฐ๋ง

1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl exec -ti xwing -- bash -c 'cat /etc/passwd'

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
_apt:x:42:65534::/nonexistent:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
node:x:1000:1000::/home/node:/bin/bash
1
2
3
๐Ÿš€ process default/xwing /usr/bin/bash -c "cat /etc/passwd"               
๐Ÿš€ process default/xwing /usr/bin/cat /etc/passwd                         
๐Ÿ’ฅ exit    default/xwing /usr/bin/cat /etc/passwd 0  
  • xwing ํŒŒ๋“œ์—์„œ cat /etc/passwd ์‹คํ–‰
  • ํ•ด๋‹น ๋ช…๋ น ์‹คํ–‰ ๋ฐ ํ”„๋กœ์„ธ์Šค ์ข…๋ฃŒ ์ด๋ฒคํŠธ๊ฐ€ Tetragon ๋กœ๊ทธ์— ๊ธฐ๋ก
  • ์‹œ์Šคํ…œ ๋‚ด๋ถ€ ํŒŒ์ผ ์ ‘๊ทผ๊นŒ์ง€ eBPF ๋ ˆ๋ฒจ์—์„œ ์ถ”์  ๊ฐ€๋Šฅํ•จ์„ ํ™•์ธ

๐Ÿ‘€ ํŒŒ์ผ ์ ‘์† ๋ชจ๋‹ˆํ„ฐ๋ง : ์ถ”์  ์ •์ฑ…์œผ๋กœ ๋ฏผ๊ฐ ํŒŒ์ผ ๋ชจ๋‹ˆํ„ฐ๋ง

1. ํŒŒ์ผ ๋ชจ๋‹ˆํ„ฐ๋ง TracingPolicy ์ƒ์„ฑ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
apiVersion: cilium.io/v1alpha1
kind: TracingPolicy
metadata:
  name: "file-monitoring-filtered"
spec:
  kprobes:
  - call: "security_file_permission"
    syscall: false
    return: true
    args:
    - index: 0
      type: "file" # (struct file *) used for getting the path
    - index: 1
      type: "int" # 0x04 is MAY_READ, 0x02 is MAY_WRITE
    returnArg:
      index: 0
      type: "int"
    returnArgAction: "Post"
    selectors:
    - matchArgs:      
      - index: 0
        operator: "Prefix"
        values:
        - "/boot"           # Reads to sensitive directories
        - "/root/.ssh"      # Reads to sensitive files we want to know about
        - "/etc/shadow"
        - "/etc/profile"
        - "/etc/sudoers"
        - "/etc/pam.conf"   # Reads global shell configs bash/csh supported
        - "/etc/bashrc"
        - "/etc/csh.cshrc"
        - "/etc/csh.login"  # Add additional sensitive files here
      - index: 1
        operator: "Equal"
        values:
        - "4" # MAY_READ
...
1
2
3
4
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl apply -f https://raw.githubusercontent.com/cilium/tetragon/main/examples/quickstart/file_monitoring.yaml

# ๊ฒฐ๊ณผ
tracingpolicy.cilium.io/file-monitoring-filtered created
1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl get tracingpolicy

โœ…ย ์ถœ๋ ฅ

1
2
NAME                       AGE
file-monitoring-filtered   39s

2. ๋ฏผ๊ฐ ํŒŒ์ผ ์ฝ๊ธฐ ๊ฐ์ง€ (/etc/shadow)

1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl exec -ti -n kube-system $POD -c tetragon -- tetra getevents -o compact --pods xwing
1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl exec -ti xwing -- bash -c 'cat /etc/shadow'

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
root:*:19709:0:99999:7:::
daemon:*:19709:0:99999:7:::
bin:*:19709:0:99999:7:::
sys:*:19709:0:99999:7:::
sync:*:19709:0:99999:7:::
games:*:19709:0:99999:7:::
man:*:19709:0:99999:7:::
lp:*:19709:0:99999:7:::
mail:*:19709:0:99999:7:::
news:*:19709:0:99999:7:::
uucp:*:19709:0:99999:7:::
proxy:*:19709:0:99999:7:::
www-data:*:19709:0:99999:7:::
backup:*:19709:0:99999:7:::
list:*:19709:0:99999:7:::
irc:*:19709:0:99999:7:::
_apt:*:19709:0:99999:7:::
nobody:*:19709:0:99999:7:::
node:!:19710:0:99999:7:::
1
2
3
4
5
6
7
๐Ÿš€ process default/xwing /usr/bin/bash -c "cat /etc/shadow"               
๐Ÿš€ process default/xwing /usr/bin/cat /etc/shadow                         
๐Ÿ“š read    default/xwing /usr/bin/cat /etc/shadow                         
๐Ÿ“š read    default/xwing /usr/bin/cat /etc/shadow                         
๐Ÿ“š read    default/xwing /usr/bin/cat /etc/shadow                         
๐Ÿ“š read    default/xwing /usr/bin/cat /etc/shadow                         
๐Ÿ’ฅ exit    default/xwing /usr/bin/cat /etc/shadow 0    
  • xwing ํŒŒ๋“œ์—์„œ cat /etc/shadow ์‹คํ–‰
  • Tetragon ์ด๋ฒคํŠธ ๋กœ๊ทธ์—์„œ ๋‹ค์Œ ์ด๋ฒคํŠธ ๊ธฐ๋ก ํ™•์ธ
    • bash -c "cat /etc/shadow" ์‹คํ–‰ ๊ฐ์ง€
    • cat /etc/shadow ํ”„๋กœ์„ธ์Šค ์‹คํ–‰ ์ด๋ฒคํŠธ ๊ฐ์ง€
    • /etc/shadow์— ๋Œ€ํ•œ read ์ด๋ฒคํŠธ(๐Ÿ“š) ๋‹ค์ˆ˜ ๊ธฐ๋ก
    • ํ”„๋กœ์„ธ์Šค ์ข…๋ฃŒ(exit 0)๊นŒ์ง€ ์ถ”์ ๋จ

3. ๋ฏผ๊ฐ ๋””๋ ‰ํ† ๋ฆฌ ์“ฐ๊ธฐ ๊ฐ์ง€ (/etc/bar)

1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl exec -ti xwing -- bash -c 'echo foo >> /etc/bar'

โœ…ย ์ถœ๋ ฅ

1
2
3
4
๐Ÿš€ process default/xwing /usr/bin/bash -c "echo foo >> /etc/bar"          
๐Ÿ“ write   default/xwing /usr/bin/bash /etc/bar                           
๐Ÿ“ write   default/xwing /usr/bin/bash /etc/bar                           
๐Ÿ’ฅ exit    default/xwing /usr/bin/bash -c "echo foo >> /etc/bar" 0 
  • xwing ํŒŒ๋“œ์—์„œ echo foo >> /etc/bar ์‹คํ–‰
  • Tetragon ์ด๋ฒคํŠธ ๋กœ๊ทธ์—์„œ ๋‹ค์Œ ์ด๋ฒคํŠธ ๊ธฐ๋ก ํ™•์ธ
    • bash -c "echo foo >> /etc/bar" ์‹คํ–‰ ๊ฐ์ง€
    • /etc/bar ํŒŒ์ผ์— ๋Œ€ํ•œ write ์ด๋ฒคํŠธ(๐Ÿ“) ๋ฐœ์ƒ
    • ํ”„๋กœ์„ธ์Šค ์ข…๋ฃŒ(exit 0)๊นŒ์ง€ ์ถ”์ ๋จ

4. TracingPolicy ์‚ญ์ œ

1
2
3
4
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl delete -f https://raw.githubusercontent.com/cilium/tetragon/main/examples/quickstart/file_monitoring.yaml

# ๊ฒฐ๊ณผ
tracingpolicy.cilium.io "file-monitoring-filtered" deleted

๐Ÿ” Policy Enforcement : ์ปค๋„ ์ˆ˜์ค€์—์„œ ์ •์ฑ… ์ œํ•œ์„ ์ ์šฉ

1. TracingPolicyNamespaced ์ƒ์„ฑ ๋ฐ ๊ฐ•์ œ ์•ก์…˜ ์ถ”๊ฐ€

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
apiVersion: cilium.io/v1alpha1
kind: TracingPolicyNamespaced
metadata:
  name: "file-monitoring-filtered"
spec:
  kprobes:
  - call: "security_file_permission"
    syscall: false
    return: true
    args:
    - index: 0
      type: "file" # (struct file *) used for getting the path
    - index: 1
      type: "int" # 0x04 is MAY_READ, 0x02 is MAY_WRITE
    returnArg:
      index: 0
      type: "int"
    returnArgAction: "Post"
    selectors:
    - matchArgs:
      - index: 0
        operator: "Prefix"
        values:
        - "/boot"           # Reads to sensitive directories
        - "/root/.ssh"      # Reads to sensitive files we want to know about
        - "/etc/shadow"
        - "/etc/profile"
        - "/etc/sudoers"
        - "/etc/pam.conf"   # Reads global shell configs bash/csh supported
        - "/etc/bashrc"
        - "/etc/csh.cshrc"
        - "/etc/csh.login"  # Add additional sensitive files here
      - index: 1
        operator: "Equal"
        values:
        - "4" # MAY_READ
      matchActions:
      - action: Sigkill
  ...      
1
2
3
4
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl apply -f https://raw.githubusercontent.com/cilium/tetragon/main/examples/quickstart/file_monitoring_enforce.yaml

# ๊ฒฐ๊ณผ
tracingpolicynamespaced.cilium.io/file-monitoring-filtered created

2. ๋ฏผ๊ฐ ํŒŒ์ผ(/etc/shadow) ์ฝ๊ธฐ ์‹œ๋„ ์ฐจ๋‹จ ํ™•์ธ

1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl exec -ti -n kube-system $POD -c tetragon -- tetra getevents -o compact --pods xwing
1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl exec -ti xwing -- bash -c 'cat /etc/shadow'

โœ…ย ์ถœ๋ ฅ

1
command terminated with exit code 137
1
2
3
4
5
๐Ÿš€ process default/xwing /usr/bin/bash -c "cat /etc/shadow"               
๐Ÿš€ process default/xwing /usr/bin/cat /etc/shadow                         
๐Ÿ“š read    default/xwing /usr/bin/cat /etc/shadow                         
๐Ÿ“š read    default/xwing /usr/bin/cat /etc/shadow                         
๐Ÿ’ฅ exit    default/xwing /usr/bin/cat /etc/shadow SIGKILL     
  • xwing ํŒŒ๋“œ์—์„œ cat /etc/shadow ์‹คํ–‰
  • Tetragon ์ด๋ฒคํŠธ์—์„œ read ์ด๋ฒคํŠธ(๐Ÿ“š) ๋ฐœ์ƒ ํ›„, SIGKILL๋กœ ํ”„๋กœ์„ธ์Šค ๊ฐ•์ œ ์ข…๋ฃŒ๋จ ํ™•์ธ
  • ์‹ค์ œ ์ถœ๋ ฅ: command terminated with exit code 137 โ†’ ์ •์ฑ…์ด ์‹ค์ œ๋กœ ์ฐจ๋‹จ ๋™์ž‘ํ•œ ๊ฒƒ์„ ์˜๋ฏธํ•จ

3. ๋ฏผ๊ฐํ•˜์ง€ ์•Š์€ ํŒŒ์ผ ์ ‘๊ทผ ํ—ˆ์šฉ ํ™•์ธ

1
(โŽˆ|HomeLab:N/A) root@k8s-ctr:~# kubectl exec -ti xwing -- bash -c 'echo foo > /tmp/test.txt'

โœ…ย ์ถœ๋ ฅ

1
2
๐Ÿš€ process default/xwing /usr/bin/bash -c "echo foo > /tmp/test.txt"      
๐Ÿ’ฅ exit    default/xwing /usr/bin/bash -c "echo foo > /tmp/test.txt" 0 
  • /tmp/test.txt ํŒŒ์ผ์— ์“ฐ๊ธฐ ์‹œ๋„ (echo foo > /tmp/test.txt)
  • Tetragon ์ด๋ฒคํŠธ ๋กœ๊ทธ์—์„œ write ์ด๋ฒคํŠธ(๐Ÿ“) ๊ฐ€ ๊ธฐ๋ก๋˜์—ˆ์œผ๋‚˜ ์ฐจ๋‹จ๋˜์ง€ ์•Š๊ณ  ์ •์ƒ ์ข…๋ฃŒ๋จ
  • ์ •์ฑ…์— ํฌํ•จ๋˜์ง€ ์•Š์€ ํŒŒ์ผ์— ๋Œ€ํ•ด์„œ๋Š” ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๋Š” ๊ฒƒ์„ ํ™•์ธ
This post is licensed under CC BY 4.0 by the author.