برنامه نویسی

Kubernetes (بخش 3) – انجمن DEV

Summarize this content to 400 words in Persian Lang

امری در مقابل اعلامی: دو رویکرد به مدیریت زیرساخت Kubernetes

امری ضروری: به طور مستقیم به Kubernetes دستور دهید تا اقدامات را مرحله به مرحله انجام دهد

برای ایجاد یک pod به روش ضروری، باید یک دستور واحد را اجرا کنیم kubectl run my-pod —image=nginx

اعلامی: حالت مورد نظر را در یک فایل پیکربندی تعریف کنید و اجازه دهید Kubernetes آن را مدیریت کند

برای ایجاد یک پاد به روش ضروری باید یک فایل تعریف pod بنویسیم( a yaml file ) ابتدا

apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
– name: my-container
image: nginx

سپس دستور را اجرا کنید kubectl apply -f filename.yaml

درک YAML: ستون فقرات پیکربندی Kubernetes

YAML مخفف (YAML Ain't Markup Language)
این آسان است و با قالب قابل خواندن توسط انسان ارائه می شود
تورفتگی اهمیت زیادی دارد
برای پیکربندی منابع Kubernetes استفاده می شود
این به شما امکان می دهد تنظیمات را به روشی ساختاریافته تعریف و سازماندهی کنید
ایجاد و مدیریت پیکربندی های پیچیده را آسان می کند

فایل YAML برای ایجاد یک pod

apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
– name: my-container
image: nginx

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

دستور مورد استفاده برای اعمال یک پیکربندی YAML:

kubectl apply -f filename.yaml

این دستور به Kubernetes می‌گوید که منابع را براساس مشخصات تعریف شده در فایل YAML ایجاد یا به‌روزرسانی کند

مفاهیم کلیدی در YAML: اشیا، فهرست ها، نظرات و رشته های چند خطی

اشیاء: مجموعه‌ای از جفت‌های کلید-مقدار، مشابه فرهنگ‌های لغت در پایتون. آنها با استفاده از تورفتگی تعریف می شوند.

مثال:
person:
name: Alice
age: 30
city: New York

در این مثال، person یک شی با سه جفت کلید-مقدار است: name، age، و city.

لیست ها: دنباله ای از آیتم ها، که در آن هر مورد با یک خط فاصله (-) و فضا.

مثال:
yamlCopy codefruits:
– Apple
– Banana
– Cherry

اینجا، fruits یک لیست شامل سه مورد است: Apple، Banana، و Cherry.

نظرات: YAML اجازه نظرات را می دهد، با یک شروع کنید #. اینها توسط YAML نادیده گرفته می شوند و برای اضافه کردن توضیحات استفاده می شوند.

مثال:
# This is a comment
server:
host: localhost
port: 8080

رشته های چند خطی: YAML راه هایی برای مدیریت رشته های چند خطی با استفاده از آن ارائه می دهد | (بلوک تحت اللفظی) یا > (بلوک تا شده).

بلوک تحت اللفظی (|):
description: |
This is a multi-line
string that preserves newlines.

بلوک تا شده (>):
description: >
This is a multi-line
string that folds into a single line.

Pods در Kubernetes: The Fundamental Unit of Deployment

برنامه به صورت پاد در kubernetes اجرا می شود

Pod کوچکترین واحد در kubernetes است
داخل غلاف ظروف اجرا می شوند
یک یا چند ظرف را نگه می دارد که با هم کار می کنند
هیچ دو نوع کانتینر مشابه نمی تواند در یک غلاف واحد اجرا شود
هر پاد آدرس IP مخصوص به خود را دریافت می کند
کانتینرها در یک Pod می توانند با استفاده از یکدیگر با یکدیگر ارتباط برقرار کنند localhost
پادها می‌توانند فضای ذخیره‌سازی داشته باشند که ظرف‌های موجود در Pod می‌توانند از آن برای اشتراک‌گذاری فایل‌ها استفاده کنند

مثال: فایل YAML برای ایجاد یک Pod

apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
– name: my-container
image: nginx
ports:
– containerPort: 80

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

این فایل یک Pod به نام ایجاد می کند my-pod با یک ظرف واحد که اجرا می شود nginx وب سرور

ایجاد همان غلاف به روش ضروری

kubectl run my-pod –image=nginx –port=80

چرخه حیات Pod: از ایجاد تا پایان

این نشان دهنده مراحل مختلف یک غلاف از ایجاد تا پایان است.

در انتظار

* The pod is created but not yet running. It’s waiting for the scheduler to assign it to a node or for container images to be pulled

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در حال دویدن

* The pod is assigned to a node, and at least one container is running. However, the container might face issues like:

* **CrashLoopBackOff**: The container repeatedly crashes and restarts

* **Error**: The container terminates with an error

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

موفق شد

* All containers in the pod have finished successfully and won’t restart

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

شکست خورد

* One or more containers in the pod have terminated with an error, and the pod is not being restarted.

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

فسخ:

هنگامی که یک pod حذف می شود، وارد حالت پایان می شود، جایی که Kubernetes متوقف می شود و ظروف آن را حذف می کند.

فضاهای نام در Kubernetes: سازماندهی و جداسازی منابع

فضاهای نام برای سازماندهی و جداسازی منابع در یک خوشه استفاده می شود. آن‌ها به تیم‌ها، پروژه‌ها یا محیط‌های مختلف (مانند برنامه‌نویس، تست و پرود) اجازه می‌دهند بدون درگیری اجرا شوند. هر فضای نام منابع خاص خود را دارد و می توانید محدودیت های منابع و کنترل های دسترسی را در هر فضای نام اعمال کنید. مدیریت و جداسازی منابع در یک خوشه بزرگ Kubernetes را آسان‌تر می‌کند

دستورات کلیدی:

یک فضای نام ایجاد کنید
kubectl create namespace my-namespace

فهرست منابع در یک فضای نام خاص
kubectl get pods -n my-namespaceview all namespaces

مشاهده تمام فضاهای نام
kubectl get ns

Init Containers: راه اندازی Pod خود برای موفقیت

ظرف Init مانند یک کمکی است که قبل از شروع بخش اصلی برنامه شما در یک پاد، اجرا می شود. برای انجام وظایف راه‌اندازی یا اطمینان از رعایت شرایط خاص قبل از اجرای کانتینر اصلی استفاده می‌شود

کانتینرهای Init همیشه قبل از هر ظرف دیگری در غلاف اجرا می شوند
یک غلاف می تواند یک یا چند ظرف اولیه داشته باشد
تا زمانی که ظرف Init با موفقیت کامل نشود، کانتینر اصلی شروع نمی شود
اگر ظرف init یک pod خراب شود، kubelet به طور مکرر آن ظرف اولیه را مجددا راه اندازی می کند تا زمانی که موفق شود
اگر غلاف دارای یک restartpolicy هرگز، و یک ظرف اولیه در هنگام راه‌اندازی پاد از کار می‌افتد، kubernetes به طور کلی غلاف را ناموفق می‌داند.
ظروف init معمولی پشتیبانی نمی کنند lifecycle، livenessProbe، readinessProbe یا startupProbe زمینه ها

فایل تعریف کانتینر را راه اندازی کنید

apiVersion: v1
kind: Pod
metadata:
name: bootcamp-pod
spec:
volumes:
– name: shared-data
emptyDir: {}
initContainers:
– name: bootcamp-init
image: busybox
command: [‘sh’, ‘-c’, ‘wget -O /usr/share/data/index.html http://kubesimplify.com’] volumeMounts:
– name: shared-data
mountPath: /usr/share/data
containers:
– name: nginx
image: nginx
volumeMounts:
– name: shared-data
mountPath: /usr/share/nginx/html

فایل تعریف کانتینرهای اولیه چندگانه

apiVersion: v1
kind: Pod
metadata:
name: init-demo-2
spec:
initContainers:
– name: check-db-service
image: busybox
command: [‘sh’, ‘-c’, ‘until nslookup db.default.svc.cluster.local; do echo waiting for db service; sleep 2; done;’] – name: check-myservice
image: busybox
command: [‘sh’, ‘-c’, ‘until nslookup myservice.default.svc.cluster.local; do echo waiting for db service; sleep 2; done;’] containers:
– name: main-container
image: busybox
command: [‘sleep’, ‘3600’]

فایل تعریف خدمات برای کانتینر اینیت چندگانه

apiVersion: v1
kind: Service
metadata:
name: db
spec:
selector:
app: demo1
ports:
– protocol: TCP
port: 3306
targetPort: 3306

apiVersion: v1
kind: Service
metadata:
name: myservice
spec:
selector:
app: demo2
ports:
– protocol: TCP
port: 80
targetPort: 80

ظروف Sidecar: تقویت برنامه اصلی شما

کانتینر سایدکار یک ظرف اضافی است که در کنار ظرف اصلی در یک غلاف اجرا می شود. این به تقویت یا پشتیبانی از عملکرد ظرف اصلی کمک می کند

کانتینر سایدکار در همان کانتینر اصلی کار می‌کند و شبکه و منابع ذخیره‌سازی مشابهی را به اشتراک می‌گذارد
می تواند به عنوان یک سرور پروکسی برای مدیریت ارتباط بین کانتینر اصلی و سرویس های خارجی عمل کند

نمونه ای از کانتینر چندگانه با کانتینر کناری

apiVersion: v1
kind: Pod
metadata:
name: multi-container-pod
spec:
volumes:
– name: shared-data
emptyDir: {}
initContainers:
– name: meminfo-container
image: alpine
restartPolicy: Always
command: [‘sh’, ‘-c’, ‘sleep 5; while true; do cat /proc/meminfo > /usr/share/data/index.html; sleep 10; done;’] volumeMounts:
– name: shared-data
mountPath: /usr/share/
data
containers:
– name: nginx-container
image: nginx
volumeMounts:
– name: shared-data
mountPath: /usr/share/nginx/html

نمونه غلاف با ظرف کناری

apiVersion: v1
kind: Pod
metadata:
name: sidecar-example
spec:
containers:
– name: main-container
image: main-app-image
ports:
– containerPort: 80
– name: sidecar-container
image: logging-agent-image
volumeMounts:
– name: shared-storage
mountPath: /logs
volumes:
– name: shared-storage
emptyDir: {}

نتیجه گیری

در نتیجه، Kubernetes یک پلت فرم قوی و انعطاف پذیر برای مدیریت برنامه های کاربردی کانتینری ارائه می دهد. با درک روش های مختلف برای تعریف و مدیریت زیرساخت، مانند رویکردهای ضروری و اعلامی، کاربران می توانند روشی را انتخاب کنند که به بهترین وجه با نیازهای آنها مطابقت دارد. YAML نقش مهمی در پیکربندی منابع Kubernetes ایفا می کند و قالبی قابل خواندن برای انسان ارائه می دهد که ایجاد و مدیریت پیکربندی های پیچیده را ساده می کند. Pods به‌عنوان کوچک‌ترین واحد در Kubernetes، ظروف و چرخه عمر آن‌ها را محصور می‌کند و استفاده کارآمد از منابع و ارتباطات را تضمین می‌کند. فضاهای نام به سازماندهی و جداسازی منابع کمک می کند و مدیریت خوشه های بزرگ را آسان تر می کند. علاوه بر این، کانتینرهای اولیه و ظروف کناری کارکرد غلاف ها را افزایش می دهند و به تنظیمات برنامه های پیچیده تر اجازه می دهند. با تسلط بر این مفاهیم، ​​کاربران می توانند به طور موثر از Kubernetes برای استقرار، مقیاس و مدیریت برنامه های خود در یک محیط بومی ابری استفاده کنند.

امری در مقابل اعلامی: دو رویکرد به مدیریت زیرساخت Kubernetes

  1. امری ضروری: به طور مستقیم به Kubernetes دستور دهید تا اقدامات را مرحله به مرحله انجام دهد

    برای ایجاد یک pod به روش ضروری، باید یک دستور واحد را اجرا کنیم kubectl run my-pod —image=nginx

  2. اعلامی: حالت مورد نظر را در یک فایل پیکربندی تعریف کنید و اجازه دهید Kubernetes آن را مدیریت کند

    برای ایجاد یک پاد به روش ضروری باید یک فایل تعریف pod بنویسیم( a yaml file ) ابتدا

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx
    spec:
      containers:
      - name: my-container
        image: nginx
    

    سپس دستور را اجرا کنید kubectl apply -f filename.yaml

درک YAML: ستون فقرات پیکربندی Kubernetes

  • YAML مخفف (YAML Ain't Markup Language)

  • این آسان است و با قالب قابل خواندن توسط انسان ارائه می شود

  • تورفتگی اهمیت زیادی دارد

  • برای پیکربندی منابع Kubernetes استفاده می شود

  • این به شما امکان می دهد تنظیمات را به روشی ساختاریافته تعریف و سازماندهی کنید

  • ایجاد و مدیریت پیکربندی های پیچیده را آسان می کند

فایل YAML برای ایجاد یک pod

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-container
    image: nginx
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

دستور مورد استفاده برای اعمال یک پیکربندی YAML:

kubectl apply -f filename.yaml

این دستور به Kubernetes می‌گوید که منابع را براساس مشخصات تعریف شده در فایل YAML ایجاد یا به‌روزرسانی کند

مفاهیم کلیدی در YAML: اشیا، فهرست ها، نظرات و رشته های چند خطی

  1. اشیاء: مجموعه‌ای از جفت‌های کلید-مقدار، مشابه فرهنگ‌های لغت در پایتون. آنها با استفاده از تورفتگی تعریف می شوند.

    مثال:

    person:
      name: Alice
      age: 30
      city: New York
    

    در این مثال، person یک شی با سه جفت کلید-مقدار است: name، age، و city.

  2. لیست ها: دنباله ای از آیتم ها، که در آن هر مورد با یک خط فاصله (-) و فضا.

    مثال:

    yamlCopy codefruits:
      - Apple
      - Banana
      - Cherry
    

    اینجا، fruits یک لیست شامل سه مورد است: Apple، Banana، و Cherry.

  3. نظرات: YAML اجازه نظرات را می دهد، با یک شروع کنید #. اینها توسط YAML نادیده گرفته می شوند و برای اضافه کردن توضیحات استفاده می شوند.

    مثال:

    # This is a comment
    server:
      host: localhost
      port: 8080
    
  4. رشته های چند خطی: YAML راه هایی برای مدیریت رشته های چند خطی با استفاده از آن ارائه می دهد | (بلوک تحت اللفظی) یا > (بلوک تا شده).

    بلوک تحت اللفظی (|):

    description: |
      This is a multi-line
      string that preserves newlines.
    

    بلوک تا شده (>):

    description: >
      This is a multi-line
      string that folds into a single line.
    

Pods در Kubernetes: The Fundamental Unit of Deployment

برنامه به صورت پاد در kubernetes اجرا می شود

  • Pod کوچکترین واحد در kubernetes است

  • داخل غلاف ظروف اجرا می شوند

  • یک یا چند ظرف را نگه می دارد که با هم کار می کنند

  • هیچ دو نوع کانتینر مشابه نمی تواند در یک غلاف واحد اجرا شود

  • هر پاد آدرس IP مخصوص به خود را دریافت می کند

  • کانتینرها در یک Pod می توانند با استفاده از یکدیگر با یکدیگر ارتباط برقرار کنند localhost

  • پادها می‌توانند فضای ذخیره‌سازی داشته باشند که ظرف‌های موجود در Pod می‌توانند از آن برای اشتراک‌گذاری فایل‌ها استفاده کنند

مثال: فایل YAML برای ایجاد یک Pod

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-container
    image: nginx
    ports:
    - containerPort: 80
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

این فایل یک Pod به نام ایجاد می کند my-pod با یک ظرف واحد که اجرا می شود nginx وب سرور

ایجاد همان غلاف به روش ضروری

kubectl run my-pod --image=nginx --port=80

چرخه حیات Pod: از ایجاد تا پایان

این نشان دهنده مراحل مختلف یک غلاف از ایجاد تا پایان است.

  1. در انتظار
* The pod is created but not yet running. It’s waiting for the scheduler to assign it to a node or for container images to be pulled
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

  1. در حال دویدن
* The pod is assigned to a node, and at least one container is running. However, the container might face issues like:

    * **CrashLoopBackOff**: The container repeatedly crashes and restarts

    * **Error**: The container terminates with an error
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

  1. موفق شد
* All containers in the pod have finished successfully and won't restart
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

  1. شکست خورد
* One or more containers in the pod have terminated with an error, and the pod is not being restarted.
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

فسخ:

هنگامی که یک pod حذف می شود، وارد حالت پایان می شود، جایی که Kubernetes متوقف می شود و ظروف آن را حذف می کند.

فضاهای نام در Kubernetes: سازماندهی و جداسازی منابع

فضاهای نام برای سازماندهی و جداسازی منابع در یک خوشه استفاده می شود. آن‌ها به تیم‌ها، پروژه‌ها یا محیط‌های مختلف (مانند برنامه‌نویس، تست و پرود) اجازه می‌دهند بدون درگیری اجرا شوند. هر فضای نام منابع خاص خود را دارد و می توانید محدودیت های منابع و کنترل های دسترسی را در هر فضای نام اعمال کنید. مدیریت و جداسازی منابع در یک خوشه بزرگ Kubernetes را آسان‌تر می‌کند

دستورات کلیدی:

  • یک فضای نام ایجاد کنید

    kubectl create namespace my-namespace
    
  • فهرست منابع در یک فضای نام خاص

    kubectl get pods -n my-namespaceview all namespaces
    
  • مشاهده تمام فضاهای نام

    kubectl get ns
    

Init Containers: راه اندازی Pod خود برای موفقیت

ظرف Init مانند یک کمکی است که قبل از شروع بخش اصلی برنامه شما در یک پاد، اجرا می شود. برای انجام وظایف راه‌اندازی یا اطمینان از رعایت شرایط خاص قبل از اجرای کانتینر اصلی استفاده می‌شود

  • کانتینرهای Init همیشه قبل از هر ظرف دیگری در غلاف اجرا می شوند

  • یک غلاف می تواند یک یا چند ظرف اولیه داشته باشد

  • تا زمانی که ظرف Init با موفقیت کامل نشود، کانتینر اصلی شروع نمی شود

  • اگر ظرف init یک pod خراب شود، kubelet به طور مکرر آن ظرف اولیه را مجددا راه اندازی می کند تا زمانی که موفق شود

  • اگر غلاف دارای یک restartpolicy هرگز، و یک ظرف اولیه در هنگام راه‌اندازی پاد از کار می‌افتد، kubernetes به طور کلی غلاف را ناموفق می‌داند.

  • ظروف init معمولی پشتیبانی نمی کنند lifecycle، livenessProbe، readinessProbe یا startupProbe زمینه ها

فایل تعریف کانتینر را راه اندازی کنید

apiVersion: v1
kind: Pod
metadata:
  name: bootcamp-pod
spec:
  volumes:
  - name: shared-data
    emptyDir: {}
  initContainers:
  - name: bootcamp-init
    image: busybox
    command: ['sh', '-c', 'wget -O /usr/share/data/index.html http://kubesimplify.com']
    volumeMounts:
    - name: shared-data
      mountPath: /usr/share/data
  containers:
  - name: nginx
    image: nginx
    volumeMounts:
    - name: shared-data
      mountPath: /usr/share/nginx/html

فایل تعریف کانتینرهای اولیه چندگانه

apiVersion: v1
kind: Pod
metadata:
  name: init-demo-2
spec:
  initContainers:
  - name: check-db-service
    image: busybox
    command: ['sh', '-c', 'until nslookup db.default.svc.cluster.local; do echo waiting for db service; sleep 2; done;']
  - name: check-myservice
    image: busybox
    command: ['sh', '-c', 'until nslookup myservice.default.svc.cluster.local; do echo waiting for db service; sleep 2; done;']
  containers:
  - name: main-container
    image: busybox
    command: ['sleep', '3600']

فایل تعریف خدمات برای کانتینر اینیت چندگانه

apiVersion: v1
kind: Service
metadata:
  name: db
spec:
  selector:
    app: demo1
  ports:
  - protocol: TCP
    port: 3306
    targetPort: 3306
---
apiVersion: v1
kind: Service
metadata:
  name: myservice
spec:
  selector:
    app: demo2
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

ظروف Sidecar: تقویت برنامه اصلی شما

کانتینر سایدکار یک ظرف اضافی است که در کنار ظرف اصلی در یک غلاف اجرا می شود. این به تقویت یا پشتیبانی از عملکرد ظرف اصلی کمک می کند

  • کانتینر سایدکار در همان کانتینر اصلی کار می‌کند و شبکه و منابع ذخیره‌سازی مشابهی را به اشتراک می‌گذارد

  • می تواند به عنوان یک سرور پروکسی برای مدیریت ارتباط بین کانتینر اصلی و سرویس های خارجی عمل کند

نمونه ای از کانتینر چندگانه با کانتینر کناری

apiVersion: v1
kind: Pod
metadata:
  name: multi-container-pod
spec:
  volumes:
  - name: shared-data
    emptyDir: {}
  initContainers:
  - name: meminfo-container
    image: alpine
    restartPolicy: Always
    command: ['sh', '-c', 'sleep 5; while true; do cat /proc/meminfo > /usr/share/data/index.html; sleep 10; done;']
    volumeMounts:
    - name: shared-data
      mountPath: /usr/share/
data
  containers:
  - name: nginx-container
    image: nginx
    volumeMounts:
    - name: shared-data
      mountPath: /usr/share/nginx/html

نمونه غلاف با ظرف کناری

apiVersion: v1
kind: Pod
metadata:
  name: sidecar-example
spec:
  containers:
    - name: main-container
      image: main-app-image
      ports:
        - containerPort: 80
    - name: sidecar-container
      image: logging-agent-image
      volumeMounts:
        - name: shared-storage
          mountPath: /logs
  volumes:
    - name: shared-storage
      emptyDir: {}

نتیجه گیری

در نتیجه، Kubernetes یک پلت فرم قوی و انعطاف پذیر برای مدیریت برنامه های کاربردی کانتینری ارائه می دهد. با درک روش های مختلف برای تعریف و مدیریت زیرساخت، مانند رویکردهای ضروری و اعلامی، کاربران می توانند روشی را انتخاب کنند که به بهترین وجه با نیازهای آنها مطابقت دارد. YAML نقش مهمی در پیکربندی منابع Kubernetes ایفا می کند و قالبی قابل خواندن برای انسان ارائه می دهد که ایجاد و مدیریت پیکربندی های پیچیده را ساده می کند. Pods به‌عنوان کوچک‌ترین واحد در Kubernetes، ظروف و چرخه عمر آن‌ها را محصور می‌کند و استفاده کارآمد از منابع و ارتباطات را تضمین می‌کند. فضاهای نام به سازماندهی و جداسازی منابع کمک می کند و مدیریت خوشه های بزرگ را آسان تر می کند. علاوه بر این، کانتینرهای اولیه و ظروف کناری کارکرد غلاف ها را افزایش می دهند و به تنظیمات برنامه های پیچیده تر اجازه می دهند. با تسلط بر این مفاهیم، ​​کاربران می توانند به طور موثر از Kubernetes برای استقرار، مقیاس و مدیریت برنامه های خود در یک محیط بومی ابری استفاده کنند.

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا