با استفاده از Cilium no WSL – DEV Community

ایجاد یک محیط تست Cilium در WSL
eBPF یک پایه کیلیوم
eBPF یکی از فناوریهایی است که اخیراً در جامعه فناوری مورد بحث قرار گرفته است.
این به لطف توانایی آن در گسترش توابع هسته بدون نیاز به تغییر کد هسته یا بارگذاری ماژول ها است. با eBPF برنامه هایی را به زبان C یا Rust می نویسید که در بایت کد کامپایل می شوند.
راهنمای مصور eBPF
بالاخره سیلیوم چیست؟
Cilium یک نرمافزار منبع باز است که از قابلیتهای eBPF برای ارائه راهحلهایی برای Ingress، دروازههای API، سرویس مش، امنیت و قابلیت مشاهده و سایر موارد به Kubernetes بهره میبرد. این می تواند بدون استفاده از کانتینر کناری مانند Envoy به صورت شفاف کار کند.
مستندات سیلیوم
“eBPF یک فناوری هسته انقلابی است که به توسعه دهندگان اجازه می دهد بنویسند
کدی که می تواند به صورت پویا در هسته بارگذاری شود و روش کرنل را تغییر دهد
رفتار می کند.
این امر نسل جدیدی از عملکرد بالا، قابل مشاهده و
ابزارهای امنیتی و همانطور که خواهید دید، اگر می خواهید برنامه ای را با این ابزارهای مبتنی بر eBPF ابزارسازی کنید، به لطف نمای eBPF درون هسته، نیازی به تغییر یا پیکربندی مجدد برنامه به هیچ وجه ندارید.”
لیز رایس، در کتاب رایگان خود آموزش eBPF
Isovalent همچنین شامل چندین آزمایشگاه رایگان برای یادگیری نحوه استفاده از Cilium و سایر ابزارهای Isovalent مانند هابل است و حتی می توانید نشان های Creddly را بدست آورید.
کامپایل یک کرنل جدید برای WSL
برای اینکه بتوانیم ماژولهای لازم را بارگیری کنیم، باید هستهای را کامپایل کنیم که از قبل ویژگیهای لازم را داشته باشد، WSL استاندارد با هسته 5.15 ارائه میشود، اما از آنجایی که باید همه چیز را دوباره کامپایل کنیم، فوراً یک هسته جدیدتر قرار میدهیم. دانلود کرنل 6.8 که نسخه استاندارد اوبونتو 24.04 است، همچنین برخی از ویژگی های Cilium فقط در نسخه های جدیدتر هسته موجود است که در جدول زیر مشاهده می کنید.
محیط من
سیستم عامل: ویندوز 11 23H2
توزیع WSL: اوبونتو 24.04 LTS
نسخه WSL: 2.1.5.0
Docker Desktop: 4.30
مدیر بسته: اسکوپ
ویژگی سیلیوم | حداقل نسخه هسته |
---|---|
مدیر پهنای باند | >= 5.1 |
دروازه خروج | >= 5.2 |
ادغام نقطه پایانی تونل VXLAN (VTEP). | >= 5.2 |
رمزگذاری شفاف WireGuard | >= 5.6 |
پشتیبانی کامل از Session Affinity | >= 5.7 |
تغییر مسیر پروکسی مبتنی بر BPF | >= 5.7 |
بای پس LB سطح سوکت در شبکه های غلاف | >= 5.7 |
دستگاه های L3 | >= 5.8 |
مسیریابی میزبان مبتنی بر BPF | >= 5.10 |
پشتیبانی از IPv6 BIG TCP | >= 5.19 |
پشتیبانی IPv4 BIG TCP | >= 6.3 |
پوسته WSL اوبونتو را باز کنید، در مدیر ترمینال خود، مال من ترمینال ویندوز است،
و مراحل را دنبال کنید
- ابزارهای لازم برای کامپایل را نصب کنید
sudo apt update && sudo apt install build-essential flex bison libssl-dev libelf-dev bc python3 pahole
- هسته را از مخزن لینوکس دانلود کنید و فقط شاخه ای را دانلود کنید که در مورد linux-6.8.y استفاده خواهیم کرد.
## baixando do repositorio
git clone --depth 1 --branch linux-6.8.y https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
### Entre na pasta
cd linux
- پس از ورود به پوشه لینوکس، فایل پیکربندی هسته Wsl پیش فرض را دانلود کرده و آن را به صورت .config ذخیره می کنیم.
wget https://raw.githubusercontent.com/microsoft/WSL2-Linux-Kernel/linux-msft-wsl-6.1.y/arch/x86/configs/config-wsl -O .config
- بیایید ورودی های LOCALVERVSION را با کلی جایگزین کنیم
sed -i 's/microsoft-standard-WSL2/generic/' ./.config
- بیایید فایل .config را طوری تنظیم کنیم که تمام نیازهای Cilium را برآورده کند
- بیایید یک فایل به نام ایجاد کنیم cilium_modules و مطالب زیر را داخل آن قرار دهید.
## linux/cilium_modules
## Base requirements
CONFIG_BPF=y
CONFIG_BPF_SYSCALL=y
CONFIG_NET_CLS_BPF=y
CONFIG_BPF_JIT=y
CONFIG_NET_CLS_ACT=y
CONFIG_NET_SCH_INGRESS=y
CONFIG_CRYPTO_SHA1=y
CONFIG_CRYPTO_USER_API_HASH=y
CONFIG_CGROUPS=y
CONFIG_CGROUP_BPF=y
## Iptables-based Masquerading
CONFIG_NETFILTER_XT_SET=m
CONFIG_IP_SET=m
CONFIG_IP_SET_HASH_IP=m
## L7 and FQDN Policies
CONFIG_NETFILTER_XT_TARGET_TPROXY=m
CONFIG_NETFILTER_XT_TARGET_CT=m
CONFIG_NETFILTER_XT_MATCH_MARK=m
CONFIG_NETFILTER_XT_MATCH_SOCKET=m
## IPsec
CONFIG_XFRM=y
CONFIG_XFRM_OFFLOAD=y
CONFIG_XFRM_STATISTICS=y
CONFIG_XFRM_ALGO=m
CONFIG_XFRM_USER=m
CONFIG_INET_ESP=m
CONFIG_INET_IPCOMP=m
CONFIG_INET_XFRM_TUNNEL=m
CONFIG_INET_TUNNEL=m
CONFIG_INET6_ESP=m
CONFIG_INET6_IPCOMP=m
CONFIG_INET6_XFRM_TUNNEL=m
CONFIG_INET6_TUNNEL=m
CONFIG_INET_XFRM_MODE_TUNNEL=m
CONFIG_CRYPTO_AEAD=m
CONFIG_CRYPTO_AEAD2=m
CONFIG_CRYPTO_GCM=m
CONFIG_CRYPTO_SEQIV=m
CONFIG_CRYPTO_CBC=m
CONFIG_CRYPTO_HMAC=m
CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_AES=m
- حالا بیایید یک اسکریپت پایتون به نام ایجاد کنیم enable_conf.py ، برای دریافت محتویات فایل cilium_modules و تنظیم .config.
import re
# Lê o conteúdo do arquivo 'cilium_modules
config_replacements = {}
with open('cilium_modules', 'r', encoding='utf-8') as file1:
for line in file1:
line = line.strip()
# Ignora linhas vazias e comentários
if not line or line.startswith('##'):
continue
key, value = line.split('=')
config_replacements[key] = value
# Lê o conteúdo do arquivo '.config'
with open('.config', 'r') as file2:
file2_lines = file2.readlines()
# Mantém um conjunto para controle das chaves que foram atualizadas
updated_keys = set()
# Substitui linhas correspondentes em '.config'
with open('.config', 'w', encoding='utf-8') as file2:
for line in file2_lines:
# Verifica se a linha contém alguma chave de 'cilium_modules' usando regex
for key, value in config_replacements.items():
if re.search(r'\b' + re.escape(key) + r'\b', line):
# Se a linha estiver comentada, remove o símbolo de comentário e atualiza
if line.startswith('# ' + key):
line = f"{key}={value}\n"
# Atualiza o valor da linha
elif re.search(r'^\s*' + re.escape(key) + r'\b', line):
line = f"{key}={value}\n"
updated_keys.add(key)
break
file2.write(line)
# Adiciona as chaves que não foram encontradas ao '.config'
for key, value in config_replacements.items():
if key not in updated_keys:
file2.write(f"{key}={value}\n")
اصل مطلب
python3 enable_conf.py
- اکنون فقط Make را اجرا کنید، می توانید تمام سوالات را به صورت پیش فرض رها کنید.
make -j $(nproc)
- پس از اتمام کامپایل، ماژول ها را نصب کنید.
sudo make modules_install
- بیایید یک پوشه در ویندوز ایجاد کنیم تا هسته جدید را قرار دهیم، به یاد داشته باشیم که همه پوشه های WSL یک هسته مشترک دارند، بنابراین اجازه دهید آن را در درایو C: قرار دهیم.
- در اوبونتو دایرکتوری را ایجاد کنید.
mkdir /mnt/c/wslkernel
- هسته جدید را در پوشه ای که نام آن را تغییر می دهیم کپی کنید هسته سیلیوم
cp arch/x86/boot/bzImage /mnt/c/wslkernel/kernelcilium
- حالا بیایید wslconfig را برای توزیعها تغییر دهیم تا با هسته جدید آپلود شوند، میتوانید از ویرایشگر متن دلخواه خود که در ویندوز هستید استفاده کنید، به پوشه، $env:USERPROFILE بروید و wslconfig. را ویرایش کنید و پیکربندی را مانند زیر اضافه کنید.
[wsl2]
kernel = C:\\wslkernel\\kernelnoble
- پنجره های باز را با wsl ببندید و همه توزیع ها را حذف کنید.
wsl --shutdown
- دوباره اوبونتو را باز کنید و تأیید کنید که از هسته جدید استفاده می کنید.
uname -r
- بیایید فایل پیکربندی را برای ماژول های لازم برای بارگیری در هنگام راه اندازی ایجاد کنیم.
awk '(NR>1) { print $2 }' /usr/lib/modules/$(uname -r)/modules.alias | sudo tee /etc/modules-load.d/cilium.conf
- بیایید سرویس daemon و modules را مجددا راه اندازی کنیم
sudo systemctl daemon-reload
sudo systemctl restart systemd-modules-load
- بررسی اینکه آیا همه چیز اوکی است یا خیر
$cris /kind ❱❱ sudo systemctl status systemd-modules-load
● systemd-modules-load.service - Load Kernel Modules
Loaded: loaded (/usr/lib/systemd/system/systemd-modules-load.service; static)
Active: active (exited) since Tue 2024-06-11 11:23:40 -03; 4h 59min ago
Docs: man:systemd-modules-load.service(8)
man:modules-load.d(5)
Process: 56 ExecStart=/usr/lib/systemd/systemd-modules-load (code=exited, status=0/SUCCESS)
Main PID: 56 (code=exited, status=0/SUCCESS)
Notice: journal has been rotated since unit was started, output may be incomplete.
$cris /kind ❱❱ lsmod
Module Size Used by
ipcomp6 12288 0
xfrm6_tunnel 12288 1 ipcomp6
tunnel6 12288 1 xfrm6_tunnel
esp6 24576 0
xfrm_user 53248 4
xfrm4_tunnel 12288 0
ipcomp 12288 0
xfrm_ipcomp 12288 2 ipcomp6,ipcomp
esp4 24576 0
xfrm_algo 16384 4 esp6,esp4,xfrm_ipcomp,xfrm_user
ip_set_hash_netportnet 49152 0
ip_set_hash_netnet 49152 0
ip_set_hash_netiface 45056 0
ip_set_hash_netport 45056 0
ip_set_hash_net 45056 0
ip_set_hash_mac 24576 0
ip_set_hash_ipportnet 45056 0
ip_set_hash_ipportip 40960 0
ip_set_hash_ipport 40960 0
ip_set_hash_ipmark 40960 0
ip_set_hash_ipmac 40960 0
....
ایجاد خوشه Kubernetes با Kind
با نصب کلاینت Cilium می توانید تمام نصب ها را با استفاده از Helm نیز انجام دهید.
از این پس ما فقط از PowerShell برای ایجاد منابع استفاده می کنیم، ابتدا با استفاده از Kind یک کلاستر ایجاد می کنیم.
- فایل پیکربندی kind را ایجاد کنید، بیایید شبکه پیش فرض و kubeproxy را غیرفعال کنیم.
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraPortMappings:
# localhost.run proxy
- containerPort: 32042
hostPort: 32042
# Hubble relay
- containerPort: 31234
hostPort: 31234
# Hubble UI
- containerPort: 31235
hostPort: 31235
- role: worker
- role: worker
networking:
disableDefaultCNI: true
kubeProxyMode: "none"
- حالا بیایید Cilium را روی خوشه نصب کنیم، برای این کار از مشتری cilium استفاده می کنیم، نصب را می توان از طریق helm نیز انجام داد.
- آخرین نسخه Cilium را برای پلتفرم خود دانلود کنید و آن را در پوشه دلخواه خود از حالت فشرده خارج کنید، به یاد داشته باشید که برای اجرای آن در هر اعلان باید مکان فایل اجرایی را در متغیر محیطی PATH قرار دهید.
## Baixando
aria2c https://github.com/cilium/cilium-cli/releases/download/v0.16.10/cilium-windows-amd64.zip
## descompactando
unzip.exe .\cilium-windows-amd64.zip
- گزینه ای که من ترجیح می دهم استفاده از Scoop است، Cilium در هیچ سطل رسمی نیست، بنابراین باید یک نصب سفارشی ایجاد کنیم.
- یک فایل به نام cilium.json ایجاد کنید و محتوای آن را در زیر قرار دهید.
{
"bin": "cilium.exe",
"version": "v0.16.10",
"url": https://github.com/cilium/ciliumcli/releases/download/v0.16.10/cilium-windows-amd64.zip"
}
- اکنون فقط با اسکوپی که به فایل json اشاره دارد نصب کنید.
scoop install cilium.json
- اکنون فقط دستور cilium را اجرا کنید تا آن را در خوشه نصب کنید، خوشه شما را از طریق زمینه فعلی .kube/config پیدا می کند، می توانید با استفاده از دستور تأیید کنید.
kubectl config get-contexts
،
cilium install
$cris /kind ❱❱ cilium install
🔮 Auto-detected Kubernetes kind: kind
✨ Running "kind" validation checks
✅ Detected kind version "0.23.0"
ℹ️ Using Cilium version 1.15.5
🔮 Auto-detected cluster name: kind-kind
ℹ️ Detecting real Kubernetes API server addr and port on Kind
🔮 Auto-detected kube-proxy has not been installed
ℹ️ Cilium will fully replace all functionalities of kube-proxy
بعد از چند دقیقه سیلیوم آماده شد، می توانیم با cli وضعیت مژه را بررسی کنیم.
cris /kind ❱❱ cilium status
/¯¯\
/¯¯\__/¯¯\ Cilium: OK
\__/¯¯\__/ Operator: OK
/¯¯\__/¯¯\ Envoy DaemonSet: disabled (using embedded mode)
\__/¯¯\__/ Hubble Relay: disabled
\__/ ClusterMesh: disabled
Deployment cilium-operator Desired: 1, Ready: 1/1, Available: 1/1
DaemonSet cilium Desired: 3, Ready: 3/3, Available: 3/3
Containers: cilium Running: 3
cilium-operator Running: 1
Cluster Pods: 3/3 managed by Cilium
Helm chart version:
Image versions cilium quay.io/cilium/cilium:v1.15.5@sha256:4ce1666a73815101ec9a4d360af6c5b7f1193ab00d89b7124f8505dee147ca40: 3
cilium-operator quay.io/cilium/operator-generic:v1.15.5@sha256:f5d3d19754074ca052be6aac5d1ffb1de1eb5f2d947222b5f10f6d97ad4383e8: 1
اگر خطایی نشان داد، می توانید به وضعیت مجموعه daemont نگاهی بیندازید و گزارش های pod را بررسی کنید.
$cris /kind ❱❱ k get daemonsets -n kube-system
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 6m47s daemonset-controller Created pod: cilium-c74rc
Normal SuccessfulCreate 6m47s daemonset-controller Created pod: cilium-b7rrn
Normal SuccessfulCreate 6m47s daemonset-controller Created pod: cilium-wmxlx
بررسی وضعیت غلاف ها
k get pods -l k8s-app=cilium -n kube-**system**
k logs -l k8s-app=cilium -n kube-system
اگر خطایی در ماژول وجود دارد، ممکن است مرحله ای در مرحله ساخت هسته وجود نداشته باشد، می توانید دوباره آن را تجزیه و تحلیل کنید. می توانید نام ماژولی که خطا داده است را دریافت کنید و با استفاده از modprobe سعی کنید آن را بارگذاری کنید.
سابق:
sudo modprobe xt_TPROXY
اگر خطایی وجود نداشته باشد و در lsmod ظاهر شود، احتمالاً در بوت لینوکس وجود ندارد، همانطور که در قسمت 12 کامپایل هسته انجام شد.
آزمایش محیط.
برای آزمایش ما از برنامه آزمایشی جنگ ستارگان از آزمایشگاه شروع با کیلیوم Isovalent استفاده خواهیم کرد.
در این آزمایشگاه، ما یک میکروسرویس ساده را مستقر می کنیم، ما یک استقرار به نام DeathStar داریم که درخواست های POST را از pods xwing و tiefigher دریافت می کند، ما از Cilium برای کنترل ارتباط بین پادها، بر اساس برچسب های پیکربندی شده استفاده می کنیم.
برچسب های Os:
- ستاره مرگ:
org=empire, class=deathstar
- جنگنده Empire TIE:
org=empire, class=tiefighter
- Rebel X-Wing:
org=alliance, class=xwing
بیایید از ایجاد برنامه در خوشه با استفاده از yaml استفاده کنیم http-sw-app.yaml
:
k apply -f https://raw.githubusercontent.com/cilium/cilium/HEAD/examples/minikube/http-sw-app.yaml
بررسی ایجاد منابع
$cris /kind ❱❱ k get pod,deploy,svc
NAME READY STATUS RESTARTS AGE
pod/deathstar-689f66b57d-9c92f 1/1 Running 0 29m
pod/deathstar-689f66b57d-b4ps7 1/1 Running 0 29m
pod/tiefighter 1/1 Running 0 29m
pod/xwing 1/1 Running 0 29m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/deathstar 2/2 2 2 29m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/deathstar ClusterIP 10.96.120.87 <none> 80/TCP 29m
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 130m
مانیفست همچنین سرویسی را برای مدیریت ارتباط با DeathStar ایجاد می کند، ما از exec برای شبیه سازی اینکه در حال اجرای دستور از غلاف xwing هستیم استفاده می کنیم.
k exec tiefighter -- curl -s -XPOST deathstar.default.svc.cluster.local/v1/request-landing
k exec xwing -- curl -s -XPOST deathstar.default.svc.cluster.local/v1/request-landing
در حال حاضر بدون سیاست های فعال، هر دو کشتی می توانند فرود بیایند و api پاسخ می دهد “کشتی فرود آمد”
بیایید یک خط مشی با استفاده از cilium ایجاد کنیم، در زیر مانیفست سیاست، اجازه دهید یک مسدود کردن درب ساده انجام دهیم.
این خط مشی زیر روی لایه های شبکه 3 و 4 عمل می کند، به طور خلاصه می توانیم IP و Port را کنترل کنیم.
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
name: "rule1"
spec:
description: "L3-L4 policy to restrict deathstar access to empire ships only"
# definindo o pod que vai receber a requisição (No caso a DeathStar)
endpointSelector:
matchLabels:
org: empire
class: deathstar
ingress:
# definindo a origem da conexão, somente permitindo o pod com o label org = empire de acessar na porta 80.
- fromEndpoints:
- matchLabels:
org: empire
toPorts:
- ports:
- port: "80"
protocol: TCP
اعمال سیاست
k apply -f https://raw.githubusercontent.com/cilium/cilium/HEAD/examples/minikube/sw_l3_l4_policy.yaml
تست سیاست ها
k exec xwing -- curl -s -XPOST deathstar.default.svc.cluster.local/v1/request-landing
k exec tiefighter -- curl -s -XPOST deathstar.default.svc.cluster.local/v1/request-landing
اکنون فقط tiefighter از API بازخورد دریافت می کند، xwing نمی تواند متصل شود، می توانید CTRL+C را برای خروج فشار دهید.
اکنون می خواهیم tiefighter فقط از ناحیه فرود استفاده کند، api ما نقاط پایانی دیگری دارد، اما ما فقط می خواهیم از /request-landing استفاده کند، برای این کار باید یک قانون HTTP ایجاد کنیم، همانطور که در قوانین تخت 3 و 4 فقط کار می کنیم. با آیپی و پورت، برای کنترل ترافیک http باید یک قانون لایه ۷ ایجاد کنیم:
نقاط پایانی:
$cris /kind ❱❱ k exec tiefighter -- curl -s -get deathstar.default.svc.cluster.local/v1
{
"name": "Death Star",
"hostname": "deathstar-689f66b57d-9c92f",
"model": "DS-1 Orbital Battle Station",
"manufacturer": "Imperial Department of Military Research, Sienar Fleet Systems",
"cost_in_credits": "1000000000000",
"length": "120000",
"crew": "342953",
"passengers": "843342",
"cargo_capacity": "1000000000000",
"hyperdrive_rating": "4.0",
"starship_class": "Deep Space Mobile Battlestation",
"api": [
"GET /v1",
"GET /v1/healthz",
"POST /v1/request-landing",
"PUT /v1/cargobay",
"GET /v1/hyper-matter-reactor/status",
"PUT /v1/exhaust-port"
]
}
برای تنظیم Yaml برای کنترل ترافیک http، ما به سادگی فیلد قوانین را به مانیفست اضافه می کنیم و اصلاحات بیشتر سیاست را اضافه می کنیم.
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
name: "rule1"
spec:
description: "L7 policy to restrict access to specific HTTP call"
endpointSelector:
matchLabels:
org: empire
class: deathstar
ingress:
- fromEndpoints:
- matchLabels:
org: empire
toPorts:
- ports:
- port: "80"
protocol: TCP
rules:
http:
- method: "POST"
path: "/v1/request-landing"
قبل از هر سیاستی، ما به راحتی موفق شدیم DeathStar را نابود کنیم.
$cris /kind ❱❱ k exec tiefighter -- curl -s -XPUT deathstar.default.svc.cluster.local/v1/exhaust-port
Panic: deathstar exploded
goroutine 1 [running]:
main.HandleGarbage(0x2080c3f50, 0x2, 0x4, 0x425c0, 0x5, 0xa)
/code/src/github.com/empire/deathstar/
temp/main.go:9 +0x64
main.main()
/code/src/github.com/empire/deathstar/
temp/main.go:5 +0x85
اعمال سیاست
k apply -f https://raw.githubusercontent.com/cilium/cilium/HEAD/examples/minikube/sw_l3_l4_l7_policy.yaml
آزمایش کردن.
k exec tiefighter -- curl -s -XPOST deathstar.default.svc.cluster.local/v1/request-landing
k exec tiefighter -- curl -s -XPUT deathstar.default.svc.cluster.local/v1/exhaust-port
ما هنوز میتوانیم فرود بیاییم، اما درگاه اگزوز در برابر Tiefighters محافظت میشود.
$cris /kind ❱❱ k exec tiefighter -- curl -s -XPOST deathstar.default.svc.cluster.local/v1/request-landing
Ship landed
$cris /kind ❱❱ k exec tiefighter -- curl -s -XPUT deathstar.default.svc.cluster.local/v1/exhaust-port
Access denied
منابع
هسته WSL
Falco WSL
WSL Kernel Cilium