WIUNIX ACADEMY
آزمایش NetworkPolicy در Kubernetes؛ منع پیشفرض با دسترسی محدود به DNS و API
صفحهٔ 2 از 3؛ مراحل قبلی و پیشنیازها را پیش از ادامه مرور کن.
آموزش متناسب با محیط تو
کجا اجرا میکنی؟
سیستمعامل و نسخه را انتخاب کن تا مراحل، دستورها و راهحلها برای همان محیط نمایش داده شوند.
آموزش متناسب با مقادیر تو
تنظیمات این آموزش
مقادیر نمونه را برای محیط خودت تنظیم کن؛ متن و دستورهای مرتبط با هم تغییر میکنند. رمز، کلید خصوصی و توکن وارد نکن. مقادیر فقط در همین زبانه نگهداری میشوند و به سرور یا لینک اشتراکگذاری فرستاده نمیشوند. پیش از اجرا، DNS، گواهیها و سیاست شبکهٔ واقعی را بررسی کن.
آیپی، دامنه یا پورت مثالها با محیط تو فرق دارد؟ دکمهٔ زیر را باز کن، مقادیر را تغییر بده و «اعمال در آموزش» را بزن؛ سپس دستورهای بهروزشده را کپی کن.
تنظیم مقادیر برای محیط من4 مقدار قابلتغییر
قدم بعدی
منابع را بسازید و پیش از سیاست، سلامت پایه را ثابت کنید
این مرحله منابع آزمایش را ایجاد میکند. ساخت فضای نام باید بهطور انحصاری موفق شود؛ اگر نشد، ادامه ندهید. سپس برچسب اختصاصی آزمایش و منابع را ایجاد کنید. پیش از اعمال سیاست، هر دو کلاینت باید نام سرور را resolve کنند و پاسخ بگیرند. اگر سلامت سرویس پیش از تغییر تأیید نشده است، timeout بعدی چیزی دربارهٔ سیاست تازه ثابت نمیکند. فضای نام تازه نیز ممکن است مشمول سیاست سراسری، سهمیه یا قواعد پذیرش کلاستر باشد.
خط فرمان؛ فقط در محیطی که مجوز بررسی آن را دارید
cd '/tmp/academy-netpol' || exit 1
kubectl --context='lab' create namespace 'academy-lab' || exit 1
kubectl --context='lab' label namespace 'academy-lab' academy.wiunix.com/lab=networkpolicy || exit 1
kubectl --context='lab' apply --dry-run=server -f lab.yaml || exit 1
kubectl --context='lab' create -f lab.yaml || exit 1
kubectl --context='lab' -n 'academy-lab' wait --for=condition=Ready pod --all --timeout=180s
kubectl --context='lab' -n 'academy-lab' exec client -- wget -Y off -T 3 -qO- http://api:8080/hostname
kubectl --context='lab' -n 'academy-lab' exec stranger -- wget -Y off -T 3 -qO- http://api:8080/hostname
kubectl --context='lab' -n 'academy-lab' get service api -o wideفضای نام تازه ساخته شده باشد و هیچ منبع قبلی بازنویسی نشده باشد، سرور آماده شود و هر دو کلاینت پیش از سیاست پاسخ HTTP مورد انتظار بگیرند.
قدم بعدی
فایل مستقلی برای منع پیشفرض بنویسید
سیاست را در فایل تازه و جدا نگه دارید تا بازگشت فقط همان منابع را درگیر کند. منع خروجی، DNS را هم میبندد و این در نخستین آزمون منفی عمدی است. قواعد استاندارد برای ترافیک نودِ خود Pod و پروتکلهای خارج از TCP/UDP/SCTP محدودیت دارند؛ این تمرین جداسازی میزبان یا مجوزدهی لایهٔ کاربرد را ثابت نمیکند.
خط فرمان؛ فقط در محیطی که مجوز بررسی آن را دارید
cd '/tmp/academy-netpol' || exit 1
(set -C; : > deny.yaml) || exit 1
${EDITOR:-vi} deny.yamlفایل جدید آماده باشد و دامنهٔ اثر آن فقط فضای نام آزمایش باشد.
قدم بعدی
ورودی و خروجی Podهای همین فضای نام را محدود کنید
selector خالی همهٔ Podهای همین فضای نام را انتخاب میکند، نه همهٔ کلاستر را. policyTypes هر دو جهت را صریح مشخص میکند. در این فایل هنوز قاعدهای برای مجازکردن ارتباط وجود ندارد.
محتوای فایل؛ در مسیر درجشده ذخیره کنید
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: academy-default-deny
namespace: academy-lab
spec:
podSelector: {}
policyTypes: [Ingress, Egress]
فایل شامل منع پیشفرض هر دو جهت باشد و مجوز ناخواستهای نداشته باشد.
قدم بعدی
شکست اتصال تازه را با نام و IP واقعی بررسی کنید
پس از فرصت انتشار سیاست، DNS و IP واقعی Service را جداگانه آزمایش کنید. ابتدا مقدار service_ip را از ClusterIP مشاهدهشده وارد کنید؛ یک IP نمونهٔ ناموجود چیزی ثابت نمیکند. در این مرحله انتظار میرود دستور با نتیجهٔ ناموفق تمام شود. آمادگی سرور را مستقل بررسی کنید؛ سرور ازکارافتاده آزمون معتبر سیاست نیست. بعضی CNIها اتصالهای برقرارشده را نگه میدارند، بنابراین هر wget باید اتصال تازهای باز کند.
خط فرمان؛ فقط در محیطی که مجوز بررسی آن را دارید
cd '/tmp/academy-netpol' || exit 1
kubectl --context='lab' create -f deny.yaml
kubectl --context='lab' -n 'academy-lab' exec client -- nslookup api
kubectl --context='lab' -n 'academy-lab' exec client -- wget -Y off -T 3 -qO- 'http://10.96.20.30:8080/hostname'
kubectl --context='lab' -n 'academy-lab' get pod api
kubectl --context='lab' -n 'academy-lab' get networkpolicyDNS و اتصال تازه به IP واقعی مطابق انتظار بسته باشند، درحالیکه سرور جداگانه آماده است.
قدم بعدی
DNS و ارتباط کلاینت به API را محدود و صریح مجاز کنید
namespaceSelector و podSelector در یک عضو peer قرار دارند؛ یعنی هر دو شرط باید برقرار باشند. اگر آنها را در دو عضو جدا بگذارید، معنای شرط «یا» میشود. DNS به هر دو UDP و TCP روی پورت ۵۳ نیاز دارد. این انتخاب برای Pod واقعی CoreDNS است، نه DNS محلی نود. ارتباط برنامه فقط از role=client به app=api روی TCP/8080 و با خروجی متناظر کلاینت مجاز میشود.
خط فرمان؛ فقط در محیطی که مجوز بررسی آن را دارید
cd '/tmp/academy-netpol' || exit 1
(set -C; : > allow.yaml) || exit 1
${EDITOR:-vi} allow.yamlفایل مجوزهای محدود آماده باشد؛ تفاوت شرط همزمان و انتخابهای جداگانه در بازبینی روشن باشد.
قدم بعدی
فقط مقصد DNS و مسیر مشخص API را باز کنید
این قواعد دسترسی عمومی اینترنت یا ورودی آزاد به کلاینتها ایجاد نمیکنند. ترتیب ترجمهٔ مقصد Service نسبت به اعمال سیاست در پیادهسازیها متفاوت است؛ نتیجهٔ واقعی را باید با آزمون مثبت و منفی ثابت کنید. برای موفقکردن ظاهری آزمون، محدودههای IP گسترده اضافه نکنید.
محتوای فایل؛ در مسیر درجشده ذخیره کنید
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata: {name: academy-dns, namespace: academy-lab}
spec:
podSelector: {}
policyTypes: [Egress]
egress:
- to:
- namespaceSelector:
matchLabels: {kubernetes.io/metadata.name: kube-system}
podSelector:
matchLabels: {k8s-app: kube-dns}
ports:
- {protocol: UDP, port: 53}
- {protocol: TCP, port: 53}
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata: {name: academy-api-ingress, namespace: academy-lab}
spec:
podSelector:
matchLabels: {app: api}
policyTypes: [Ingress]
ingress:
- from:
- podSelector:
matchLabels: {role: client}
ports: [{protocol: TCP, port: 8080}]
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata: {name: academy-client-egress, namespace: academy-lab}
spec:
podSelector:
matchLabels: {role: client}
policyTypes: [Egress]
egress:
- to:
- podSelector:
matchLabels: {app: api}
ports: [{protocol: TCP, port: 8080}]
مجوز DNS و ارتباط دقیق کلاینت منتخب تعریف شده باشد و قاعدهٔ باز عمومی وجود نداشته باشد.