يُستخدم تشغيل Kubernetes محليًا ليعني جهازًا افتراضيًا ثقيلًا وانتظارًا طويلًا. kind وk3d غيرت ذلك عن طريق تشغيل المجموعات كحاويات، والتي تبدأ في ثوانٍ ولا تكلف شيئًا تقريبًا عندما تكون في وضع الخمول. يقوم هذا الدليل بإعداد مجموعة محلية عاملة مع الدخول وتحميل الصور المحلية وحلقة تطوير لا تتضمن الدفع إلى السجل عند كل تغيير.
📋 Table of Contents
- النوع أو k3d: أيهما تختار
- المتطلبات
- الخيار أ: النوع
- يعالج k3d تعيين المنافذ والدخول باستخدام العلامات، لذا يكون الإعداد أقصر. يتضمن k3s Traefik كوحدة تحكم في الدخول بشكل افتراضي.
- أمر ضروري للتنمية المحلية. الافتراضي
- تعمل مجموعتك في حاوياتها الخاصة مع مخزن الصور الخاص بها. الصورة المبنية على مضيفك تكون غير مرئية لها حتى تقوم بتحميلها بشكل صريح.
- إن إعادة البناء والتحميل وإعادة النشر يدويًا لكل تغيير أمر بطيء جدًا بحيث لا يمكن استمراره. طريقتان لإصلاحه.
- توفر كلتا الأداتين فئة تخزين افتراضية، لذلك يعمل PersistentVolumeClaim بدون تكوين.
- هو الأمر الأول الذي يتم تشغيله لأي مشكلة تقريبًا. يوضح قسم الأحداث في الأسفل ما إذا كانت الصورة قد فشلت في السحب، أو كانت العقدة تفتقر إلى الموارد، أو فشل المسبار.
- أخطاء شائعة
- نسيان تحميل الصورة.
- يحتاج إعداد Kubernetes المحلي الإنتاجي إلى أربعة أشياء صحيحة:
النوع أو k3d: أيهما تختار
كلاهما يقوم بتشغيل Kubernetes داخل Docker. إنهم يختلفون في ما يقومون بتشغيله وما يقومون بتحسينه.
| نوع | ك 3د | |
|---|---|---|
| كوبرنيتس | المنبع، غير معدل | k3s – خفيف الوزن، مع تبديل بعض المكونات |
| وقت البدء | سريع | أسرع |
| استخدام الذاكرة | العالي | أقل |
| الأفضل لـ | اختبار مقابل السلوك المنبع الحقيقي، CI | تكرار سريع، أجهزة كمبيوتر محمولة مقيدة |
اخترنوع إذا كنت بحاجة إلى سلوك مماثل للإنتاج الأولي لـ Kubernetes، خاصة لمشغلي الاختبار أو وحدات التحكم في القبول. اخترك 3د إذا كنت تريد أسرع وأخف حلقة لتطوير التطبيقات. كلاهما ممتاز. يغطي هذا الدليل كل منها.
المتطلبات
# Docker must be running
docker version
# kubectl
brew install kubectl # macOS
# or: curl -LO "https://dl.k8s.io/release/$(curl -Ls https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
# kind
brew install kind
# k3d
brew install k3d
الخيار أ: النوع
تعتبر المجموعة أحادية العقدة أمرًا واحدًا، ولكن ملف التكوين يستحق الكتابة على الفور لأن الدخول يتطلب تعيينات المنافذ التي لا يمكن إضافتها لاحقًا دون إعادة إنشاء المجموعة.
# kind-config.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
kubeadmConfigPatches:
- |
kind: InitConfiguration
nodeRegistration:
kubeletExtraArgs:
node-labels: "ingress-ready=true"
extraPortMappings:
- containerPort: 80
hostPort: 80
protocol: TCP
- containerPort: 443
hostPort: 443
protocol: TCP
- role: worker
- role: worker
kind create cluster --name dev --config kind-config.yaml
# kubectl context is switched automatically
kubectl cluster-info --context kind-dev
kubectl get nodes
منع إعادة توجيه المنفذين المضيفين 80 و443 إلى عقدة نظام المجموعة، وهو ما يجعلextraPortMappings الوصول إلى وحدة تحكم الدخول الخاصة بك. أضفه مقدمًا — التعديل التحديثي يعني حذف المجموعة وإعادة إنشائها.http://localhostالدخول على النوع
الخيار ب: k3d
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml
kubectl wait --namespace ingress-nginx \
--for=condition=ready pod \
--selector=app.kubernetes.io/component=controller \
--timeout=90s
يعالج k3d تعيين المنافذ والدخول باستخدام العلامات، لذا يكون الإعداد أقصر. يتضمن k3s Traefik كوحدة تحكم في الدخول بشكل افتراضي.
لاستخدام ingress-nginx بدلاً من Traefik، قم بتعطيل الحزمة المجمعة في وقت الإنشاء.
k3d cluster create dev \
--agents 2 \
--port "80:80@loadbalancer" \
--port "443:443@loadbalancer"
kubectl get nodes
نشر التطبيق
k3d cluster create dev \
--agents 2 \
--port "80:80@loadbalancer" \
--k3s-arg "--disable=traefik@server:0"
أمر ضروري للتنمية المحلية. الافتراضي
# app.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 2
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: my-app:dev
imagePullPolicy: IfNotPresent
ports:
- containerPort: 3000
readinessProbe:
httpGet:
path: /healthz
port: 3000
initialDelaySeconds: 2
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
memory: 512Mi
---
apiVersion: v1
kind: Service
metadata:
name: web
spec:
selector:
app: web
ports:
- port: 80
targetPort: 3000
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web
spec:
ingressClassName: nginx
rules:
- host: app.localhost
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web
port:
number: 80
imagePullPolicy: IfNotPresent يجعل Kubernetes يحاول السحبAlways من سجل غير موجود، وفشلت الكبسولة معmy-app:devتحميل الصور المحلية — الخطوة التي يفوتها الجميعErrImagePull.
تعمل مجموعتك في حاوياتها الخاصة مع مخزن الصور الخاص بها. الصورة المبنية على مضيفك تكون غير مرئية لها حتى تقوم بتحميلها بشكل صريح.
ثم قم بالتقديم والتحقق.
# Build normally
docker build -t my-app:dev .
# kind
kind load docker-image my-app:dev --name dev
# k3d
k3d image import my-app:dev -c dev
إذا جلست القرون في
kubectl apply -f app.yaml
kubectl get pods -w
curl -H "Host: app.localhost" http://localhost/
، فمن المؤكد أنك تخطيت خطوة التحميل أو غادرتImagePullBackOff في وضعها الافتراضي.imagePullPolicyحلقة داخلية سريعة
إن إعادة البناء والتحميل وإعادة النشر يدويًا لكل تغيير أمر بطيء جدًا بحيث لا يمكن استمراره. طريقتان لإصلاحه.
إمالة أو سقالة
شاهد المصدر الخاص بك، وأعد البناء، وتحميل الصورة، وقم بتحديث النشر تلقائيًا.إعادة توجيه المنفذ
# Tiltfile
docker_build('my-app', '.')
k8s_yaml('app.yaml')
k8s_resource('web', port_forwards='3000:3000')
tilt up
يكفي عندما تحتاج فقط إلى الوصول إلى الخدمة دون الدخول.وحدات التخزين المستمرة
kubectl port-forward svc/web 3000:80
# now http://localhost:3000
توفر كلتا الأداتين فئة تخزين افتراضية، لذلك يعمل PersistentVolumeClaim بدون تكوين.
للاحتفاظ بالبيانات على مضيفك حتى ينجو من حذف المجموعة، قم بتثبيت دليل مضيف في وقت الإنشاء.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data
spec:
accessModes: [ReadWriteOnce]
resources:
requests:
storage: 1Gi
التصحيح
# kind-config.yaml
nodes:
- role: control-plane
extraMounts:
- hostPath: /Users/me/k8s-data
containerPath: /data
هو الأمر الأول الذي يتم تشغيله لأي مشكلة تقريبًا. يوضح قسم الأحداث في الأسفل ما إذا كانت الصورة قد فشلت في السحب، أو كانت العقدة تفتقر إلى الموارد، أو فشل المسبار.
# Why is a pod not starting? Events are at the bottom.
kubectl describe pod <pod-name>
# Logs, including from a crashed previous container
kubectl logs <pod-name>
kubectl logs <pod-name> --previous
# Shell into a running container
kubectl exec -it <pod-name> -- sh
# Debug a container with no shell using an ephemeral container
kubectl debug -it <pod-name> --image=busybox --target=web
# Cluster-wide recent events, newest last
kubectl get events --sort-by=.metadata.creationTimestamp
kubectl describe podتنظيف
أخطاء شائعة
# kind
kind delete cluster --name dev
# k3d
k3d cluster delete dev
# k3d can also stop and restart without losing state
k3d cluster stop dev
k3d cluster start dev
نسيان تحميل الصورة.
لا يمكن للمجموعة رؤية صور Docker الخاصة بمضيفك. تحميلها بشكل صريح.مغادرة
في الوضع الافتراضي.imagePullPolicy مع العلامة الافتراضية هي:latest، والذي يفشل في الصور المحلية فقط.Alwaysإضافة تعيينات المنفذ بعد الإنشاء.
يتم إصلاحها عند إنشاء المجموعة. خطط لمنافذ الدخول قبل الإنشاء.إغفال طلبات الموارد.
وبدونها، لا يستطيع المجدول التفكير في السعة، وتبالغ المجموعات المحلية في الالتزام حتى يتم إخلاء الكبسولات.بافتراض أن الإنتاج المحلي يساوي الإنتاج.
لا تحتوي المجموعات المحلية على موازن تحميل حقيقي، ولا فئات تخزين سحابية، ولا يوجد تطبيق لسياسة الشبكة بشكل افتراضي. تعامل معهم كأداة تطوير، وليس كمحاكاة للإنتاج.الخلاصة
يحتاج إعداد Kubernetes المحلي الإنتاجي إلى أربعة أشياء صحيحة:
أنشئ المجموعة بتعيينات المنافذ التي ستحتاجها للدخول، وقم بتحميل الصور المحلية بشكل صريح في المجموعة، وقم بتعيين لذلك لا يلاحق Kubernetes السجل، ويقوم بأتمتة حلقة إعادة البناء باستخدام Tilt أو Skaffold.imagePullPolicy: IfNotPresent استخدم النوع عندما تحتاج إلى سلوك متطابق مع المنبع وk3d عندما تريد الحلقة الأخف والأسرع. يتيح لك كلاهما حذف مجموعة وإعادة إنشائها في ثوانٍ، وهي الميزة الحقيقية – لا تعد المجموعة المحلية المعطلة مشكلة تستحق التصحيح. استخدم النوع عندما تحتاج إلى سلوك متطابق مع المنبع وk3d عندما تريد الحلقة الأخف والأسرع. يتيح لك كلاهما حذف مجموعة وإعادة إنشائها في ثوانٍ، وهي الميزة الحقيقية – لا تعد المجموعة المحلية المعطلة مشكلة تستحق التصحيح.
🔗 Share this article
✍️ Leave a Comment