<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های امیر نعمت زاده</title>
        <link>https://virgool.io/feed/@amirhne</link>
        <description>من امیر هستم و به فناوری علاقمندم؛ بیشتر به شبکه، دنیای متن باز و کمی برنامه نویسی. اهل فیلم، سینما و گیم هستم و فلسفه رو به عنوان تفریح مطالعه میکنم.</description>
        <language>fa</language>
        <pubDate>2026-06-10 12:54:26</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/6545/avatar/0KrUcU.jpeg?height=120&amp;width=120</url>
            <title>امیر نعمت زاده</title>
            <link>https://virgool.io/@amirhne</link>
        </image>

                    <item>
                <title>راه اندازی HAProxy برای لودبالانسینگ ترافیک وب با Ansible</title>
                <link>https://virgool.io/mobit-eng/%D8%B1%D8%A7%D9%87-%D8%A7%D9%86%D8%AF%D8%A7%D8%B2%DB%8C-haproxy-%D8%A8%D8%B1%D8%A7%DB%8C-%D9%84%D9%88%D8%AF%D8%A8%D8%A7%D9%84%D8%A7%D9%86%D8%B3%DB%8C%D9%86%DA%AF-%D8%AA%D8%B1%D8%A7%D9%81%DB%8C%DA%A9-%D9%88%D8%A8-%D8%A8%D8%A7-ansible-fsk7gtkdztcl</link>
                <description>در این مقاله قرار هست که یک سناریو لودبالانسینگ ترافیک وب با HAProxy پیاده شود و وظیفه راه اندازی صفر تا صد آن به صورت اتوماتیک با Ansible خواهد بود. مخاطب این مقاله افرادی هستند که با داکر، دستورات و محیط گنو/لینوکس و مفاهیم شبکه آشنایی دارند. در این سناریو ترافیک وب یک وب اپلیکشن ساده فلسک که مشابه آن را قبلا در اینجا در داکر قرار دادیم، لودبالانس خواهد شد. لودبالانس به معنی توزیع بار ترافیک بین سرورها با الگوریتم دلخواه است که در اینجا Round-Robin خواهد بود. در ابتدا توضیحات دقیق درباره سناریو داده خواهد شد و پس از آن به راه اندازی محیط آزمایشگاهی (Lab) برای سناریو می پردازیم. در ادامه درباره ساختار Playbook ها توضیح داده میشود و نهایتا با استفاده از یک Playbook برای Ansible تمام سناریو پیاده سازی خواهد شد.سناریودر این سناریو سه سرور وجود دارد که یکی از آنها نقش لودبالانسر اصلی را به عهده دارد و دو سرور دیگر به شکلی مشابه هر کدام دو سرویس وب اپلیکیشن فلسک را همراه با یک لودبالانسر داخلی اجرا میکنند. Ansible بر روی یک ماشین لینوکسی که میتواند سیستم شخصی یا ماشین مجازی باشد، راه اندازی میشود و با ارتباط SSH وظیفه مدیریت سرور ها و راه اندازی سناریو را بر عهده دارد. سناریو به شکل زیر میباشد:راه اندازی محیط آزمایشگاهیبرای راه اندازی محیط آزماشیگاهی (Lab) سناریو از داکر کامپوز استفاده میکنیم؛ پس بایستی داکر و داکر کامپوز بر روی ماشین مورد نظر نصب باشد و پس از آن نصب و راه اندازی انسیبل توضیح داده خواهد شد.داکر کامپوز از یک فایل کانفیگ YAML برای راه اندازی کانتینر ها استفاده میکند و فایل کانفیگ مشابه زیر میباشد که در ادامه درباره آن توضیح داده خواهد شد:version: &#039;3.8&#039;

services:
  HA_proxy_Loadbalancer:
    build:
      context: .
      dockerfile: ubuntu_with_sshd.Dockerfile
    image: ubuntu_haproxy:latest
    hostname: HAproxy
    ports:
      - &#039;22:22&#039;
      - &#039;8080:80&#039;

  flask_server_1:
    image: ubuntu_haproxy:latest
    hostname: server_1
    ports:
      - &#039;23:22&#039;

  flask_server_2:
    image: ubuntu_haproxy:latest
    hostname: server_2
    ports:
      - &#039;24:22&#039; در اینجا نسخه فایل داکر کامپوز مشخص شده است.خالیمشخص میشود که چه کانتینر هایی قرار است راه اندازی شوند.نام کانتینر مشخص میشود و گفته میشود که تنظیمات آن در ادامه قرار دارد.گفته میشود ایمیجی که قرار است کانتینر از روی آن ساخته شود بایستی با مشخصات بعدی ساخته شود.مسیر داکر فایل مورد نظر برای ساخت ایمیج داده شده است که همان مسیری است که فایل کامپوز قرار دارد.نام داکر فایل داده شده است.گفته میشود داکر ایمیج ساخته شده در مرحله قبل با چه نامی ذخیره شود.هاست نیم (etc/hostname/) کانتینر پس از راه اندازی مشخص میشود.گفته میشود که قرار است چه پورت هایی از بیرون کانتینر در دسترس قرار داشته باشند.گفته میشود پورت ۲۲ ماشین به پورت ۲۲ کانتینر فوروارد شود.گفته میشود پورت ۸۰۸۰ ماشین به پورت ۸۰ کانتینر فوروارد شود.خالینام کانتینر مشخص میشود و گفته میشود که تنظیمات آن در ادامه قرار دارد.گفته میشود که کانتیتر از روی چه ایمیجی ساخته شود که در اینجا همان ایمجی است که برای کانتینر لودبالانسر ساخته شده است.هاست نیم (etc/hostname/) کانتینر پس از راه اندازی مشخص میشود.گفته میشود که قرار است چه پورت هایی از بیرون کانتینر در دسترس قرار داشته باشند.گفته میشود پورت ۲۳ ماشین به پورت ۲۲ کانتینر فوروارد شود.خالینام کانتینر مشخص میشود و گفته میشود که تنظیمات آن در ادامه قرار دارد.گفته میشود که کانتیتر از روی چه ایمیجی ساخته شود که در اینجا همان ایمجی است که برای کانتینر لودبالانسر ساخته شده است.هاست نیم (etc/hostname/) کانتینر پس از راه اندازی مشخص میشود.گفته میشود که قرار است چه پورت هایی از بیرون کانتینر در دسترس قرار داشته باشند.گفته میشود پورت ۲۴ ماشین به پورت ۲۲ کانتینر فوروارد شود.نکته مهم: فاصله ها در این فایل بسیار مهم میباشد و بایستی حتما سلسله مراتب در نوشتن این فایل رعایت شود.نکته مهم: داکر دارای یک DNS سرور داخلی در هر شبکه خود هست و تمام کانتیر هایی که در یک شبکه قرار دارند تنها با نام میتوانند با یکدیگر ارتباط برقرار کنند. با استفاده از همین قابلیت در HAProxy در سرور لودبالانسر میتواند با سرور های Backend با نام ارتباط برقرار کند.میتوانید برای دریافت فایل کانفیگ داکر کامپوز و راه اندازی سرور ها از دستورات زیر استفاده کنید:git clone https://github.com/amirhne/flask-haproxy-scenario-lab.git
cd flask-haproxy-scenario-lab/
docker-compose upانسیبل در حال حاضر فقط بر روی سیستم عامل گنو/لینوکس قابل نصب میباشد پس فرض بر این است که یا سیستم عامل ماشین شما گنو/لینوکس است یا ماشین مجازی با سیستم عامل گنو/لینوکس دارید که به داکر دسترسی شبکه دارد.برای نصب انسیبل بر روی توزیع های بر پایه Debian از دستورات زیر استفاده کنید:sudo apt update
sudo apt install ansibleبرای نصب انسیبل بر روی توزیع های بر پایه RedHat از دستورات زیر استفاده کنید:sudo yum -y install epel-repo
sudo yum -y update
sudo yum -y install ansibleعملکرد انسیبل برای مدیریت نود های هدف به صورت Agentless میباشد و فقط برای کنترل نود ها نیازمند دسترسی و ارتباط SSH است. برای سهولت و امنیت بیشتر بهتر است که احراز هویت با نود های هدف با کلید عمومی و خصوصی انجام شود که برای هر بار اتصال نیازمند وارد کردن پسورد نباشیم.در ابتدا برای اینکار با دستور زیر در ماشین یا ماشین مجازی که انسیبل بر روی آن نصب شده است یک کلید میسازیم:ssh-keygenدر تمام مراحل ساخت که نیازمند ورودی است فقط اینتر را بزنید.و سپس با زدن دستورات زیر در ماشین یا ماشین مجازی که انسیبل بر روی آن نصب است، کلید عمومی را بر روی سرور ها قرار میدهیم.ssh-copy-id ansible@127.0.0.1 -p 22
ssh-copy-id ansible@127.0.0.1 -p 23
ssh-copy-id ansible@127.0.0.1 -p 24در صورتی که از ماشین مجازی استفاده میکنید به جای ای پی 127.0.0.1، ای پی ماشینی را بزنید که داکر و کانتینر ها در آن قرار دارند.با انجام مراحل بالا که شامل راه اندازی سرور ها در داکر، نصب و تنظیم انسیل بر روی نود کنترل کننده است؛ محیط مورد نظر برای پیاده سازی سناریو آماده شده است.ساختار پلی بوکساختار پلی بوک به شکلی است که در ابتدا هاست هایی که قرار است عملیات روی آنها انجام شود مشخص میشود و پس از آن با مشخص کردن المان هایی مثل متغیر ها و دسترسی اجرای دستورات،‌ لیستی از کار ها که با نام task مشخص میشود، شکل میگیرد. نوعی از task هم به نام handler وجود دارد که فقط در صورت خوانده شدن توسط یک task و اعمال تغییرات توسط آن، اجرا میشود که در ادامه نمونه آن را مشاهده میکنید.در زیر یک نمونه ساده از یک پلی بوک آورده شده است و در ادامه درباره آن توضیح داده میشود:---
- hosts: machines
  become: yes
  vars:
    - test1: 1
    - test2: apache was not installed
  tasks:
    - name: First Test Task
      shell: echo &#039;the test1 var is {{ test1 }}&#039; &gt; /home/test.txt
    - name: Second Task
      apt:
        name: apache2
        update_cache: yes
        state: latest
      notify: A Handler is Called

  handlers:
    - name: A Handler is Called
      shell: cat &#039;{{ test2 }}&#039; &gt; /home/apache_status.txt
 مشخص میشود که این یک فایل کانفیگ YAML میباشد.گفته میشود که قرار است بر روی چه نود یا نود هایی عملیات ها پیش رو انجام شود. این گروه از نود ها یا یک نود توسط یک فایل inventory مشخص میشوند که در ادامه مقاله نمومه آن آورده شده است. همچنین میتوان آنها در فایل etc/ansible/hosts/ مشخص کرد.گفته میشود که تمامی تسک ها با دسترسی روت انجام شوند.گفته میشود که یک سری متغییر در این پلی بوک وجود دارد.یک متغییر تعریف میشود.یک متغییر تعریف میشود.میشخص میشود که قرار است مجموعه ای از کار ها در ادامه انجام شود.یک تسک جدید با نام آن مشخص میشود.با استفاده از ماژول shell در نود هدف دستور داده شده را انجام شود. ماژول شل برای برای اجرای دستور در محیط دستوری گنو/لینوکس استفاده میشود. همانطور که مشاهده میکنید استفاده از متغییر در محیط انسیبل به شکل {{ var_name }} میباشد.یک تسک جدید با نام آن مشخص میشود.گفته میشود که از ماژول apt استفاده شود و کارهای آن در ادامه مشخص میشود. ماژول apt برای مدیریت پکیج ها در سیستم عامل های بر پایه دبین استفاده میشود.نام پیکیج مشخص میشود.گفته میشود که لیست ریپازیتوری های سیستم عامل بروز شود.گفته میشود که پکیج نام برده بایستی آخرین نسخه آن نصب باشد.یک handler با نام مشخص فراخوانی میشود که در صورت اجرا این تسک و ایجاد تغییر در نود هدف این handler اجرا میشود.خالیگفته میشود که لیست هندلرها در ادامه داده شده است.یک هندلر جدید با نام آن مشخص میشود.گفته میشود در صورت اجرای این هندلر با ماژول شل دستور مورد نظر اجرا شود.با توضیحات ارایه شده مشخص شده است که ساختار یک پلی بوک چگونه میباشد ولی رایج است که برای پیاده سازی نقش ها در پلی بوک از یک ساختار پوشه ای به نام roles که در آن تمامی قسمت های مختلف یک پلی بوک در مسیر های جداگانه قرار داده میشوند، استفاده میشود. به این صورت که هر نقش یا role شامل یکسری task,vars, handlers و... مشخص میباشد که در یک ساختار پوشه قرار میگیرند.در ادامه یک پلی بوک با نام site.yml با استفاده از roles اورده شده است که توضیحات درباره آن داده خواهد شد:---
- hosts: machines
  become: yes
  roles:
  - webserverمشخص میشود که این فایل کانفیگ YAML هست. گفته میشود که قرار است بر روی چه نود یا نود هایی عملیات ها پیش رو انجام شود.گفته میشود که تمامی تسک ها با دسترسی روت انجام شوند.گفته میشود که قرار است که چه نقش هایی بر روی نود یا نود های هدف پیاده سازی شود.همانطور که مشاهده میکنید پلی بوک اصلی به شکل فوق العاده ای ساده و خوانا شده است و فقط کافیست در مسیر همین پلی بوک یک پوشه با نام roles با ساختاری که در ادامه توضیح داده شده است پیاده سازی شود.site.yml
roles/
    webserver/
        tasks/
            main.yml
        handlers/
            main.yml
        vars/
            main.ymlدر این ساختار پوشه ای فقط کافی است که کدهای زیر هر قسمت اصلی از پلی بوک مانند tasks یا handlers در فایل main.yml هر پوشه با نام همان قسمت قرار داده شود و در پلی بوک اصلی فقط کافیست نام آن نقش که همان نام پوشه (در بالا درشت نوشته شده است) است، ذکر شود.حال که ساختار پلی بوک و roles توضیح داده شد سراغ پیاده سازی سناریو مورد نظرمان توسط انسیبل میرویم.پیاده سازی سناریوبرای پیاده سازی سناریو مورد نظرمان از یک پلی بوک استفاده خواهد شد که در آن از ساختار roles استفاده شده است. وظیفه این پلی بوک تنظیم یک سرور به عنوان لودبالانسر اصلی و دو سرور دیگر به عنوان سرور فلسک است. پروژه فلسک مورد استفاده قبلا در اینجا در داکر قرار داده شده است و در این سناریو با فرمی دیگر مورد استفاده قرار گرفته است.لودبالانسر HAProxy برای تنظیمات خود از یک فایل کانفیگ در مسیر etc/haproxy/haproxy.cfg/ استفاده میکند.فایل کانفیگی که برای سرور لودبالانسر استفاده میشود مشابه زیر میباشد که در ادامه درباره آن توضیح داده میشود:frontend loadbalancer
	bind	*:80
	option	forwardfor
	default_backend	flask_servers

backend	flask_servers
	balance	roundrobin
	server	server_1	flask_server_1:80	check
	server	server_2	flask_server_2:80	check
	option	httpchk مشخص میشود که سرور فرانت اند که وظیفه اصلی لودبالانسینگ را دارد در ادامه چه مشخصاتی خواهد داشت و نام آن مشخص میشود.گفته میشود که بر روی تمام ای پی های سرور و پورت ۸۰ ترافیک قبول شود.گفته میشود که ترافیک به سرور ها که بعدا در بک اند مشخص میشود، فروارد شود.نام سرور های بک اند مشخص میشود که در ادامه تعریف خواهد شد.خالیمشخص میشود که مشخصات سرور های بک اند چه خواهد بود و نام آن ها برای استفاده مشخص میشود. این دقیقا همان نام ای است که در قسمت فرانت اند در خط ۴ استفاده شده است.الگوریتم لودبالانسینگ round-robin مشخص میشود. یک سرور با نام server_1 با ادرس مشخص و پورت ۸۰ تعریف شده است، این آدرس دقیقا همان نامی است که هنگام ایجاد کانتینر با داکر کامپوز استفاده شده است و در ادامه گفته میشود که سرور را برای در دسترس بودن برای هر مدت کوتاه با برقراری یک کانکشن tcp چک کند.  یک سروربا نام server_2 با ادرس مشخص و پورت ۸۰ تعریف شده است، این آدرس دقیقا همان نامی است که هنگام ایجاد کانتینر با داکر کامپوز استفاده شده است و در ادامه گفته میشود که سرور را برای در دسترس بودن برای هر مدت کوتاه با برقراری یک کانکشن tcp چک کند. گفته میشود که با دادن درخواست http بالا بودن سرور را برای هر مدت کوتاه چک کند که در صورت دادن پیغام خطا مانند ۵۰۰ دیکر از لیست خارج شود.برای HAProxy هر کدام از سرور های فلسک که عمکرد داخلی دارد از یک فایل کانفیگ دقیقا مشابه همان که برای سرور لودبالانسر استفاده شده است، استفاده میکنیم ولی با یک تغییر کوچک که در ادامه درباره آن توضیح داده خواهد شد:frontend loadbalancer
	bind	*:80
	option	forwardfor
	default_backend	flask_services

backend	flask_services
	balance	roundrobin
	server	flask_1	127.0.0.1:{{ flask_1_port }}	check
	server	flask_2	127.0.0.1:{{ flask_2_port }}	check
	option	httpchk۷ و ۸.  در اینجا از ای پی لوکال استفاده شده است و به جای پورت از یک متغییر در پلی بوک استفاده شده است که در هنگام کپی کردن بر روی سرور تبدیل به پورت دلخواه ما میشود که در اینجا ۳۰۰۰ و ۳۰۰۱ میباشد.برای پیاده سازی سرویس فلسک از نمونه فایل زیر استفاده شده است که در ادامه درباره آن توضیح داده شده است:from flask import Flask, render_template
app = Flask(__name__)
@app.route(&#039;/&#039;)
def hello_world():
    return render_template(&#039;index.html&#039;)
if __name__ == &#039;__main__&#039;:
    app.run(debug=True,host=&#039;0.0.0.0&#039;, port={{ flask_1_port }})در خط آخر همانطور که مشاهده میکنید مجددا از متغییر پلی بوک برای پیاده سازی و مشخص کردن پورت وب اپلیکیشن استفاده شده است. همچنین کد صفحه وبی که به کاربر نمایش داده میشود به شکل زیر میباشد: &lt;!DOCTYPE html&gt;
&lt;html lang=&amp;quoten&amp;quot&gt;
&lt;head&gt;
&lt;meta charset=&amp;quotUTF-8&amp;quot&gt;
    &lt;title&gt; Hello World! &lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;center&gt;
&lt;h2&gt;This Message is shown from&lt;/h2&gt; &lt;h1&gt;{{ ansible_hostname }}&lt;/h1&gt; &lt;h2&gt;that is running flask on port&lt;/h2&gt; &lt;h1&gt;{{ flask_1_port }}&lt;/h1&gt;
&lt;/center&gt;
&lt;/body&gt;
&lt;/html&gt;در قسمت تگ h1 میبینید که مجددا از متغییر پلی بوک برای نمایش پورت فلسک و نام هاست به کاربر استفاده شده است.نکته: استفاده از متغییر این امکان را به ما میدهد که به صورت همزمان فقط با یک تغییر هم امکان تغییر در کد برنامه فلسک و هم تغییر در فایل کانفگیگ HAProxy را داشته باشیم. همچنین بتوانیم با استفاده از متغییر هایی که توسط خود انسیل ساخته مانند : ansible_hostname که به ازای هر نود ساخته میشود و متفاوت میباشد، بتوانیم صفحه نمایش داده شده به کاربر را برای هر سرور به صورت اتوماتیک متمایز کنیم.پلی بوک اصلی که برای پیاده سازی سناریو نوشته شده است از ساختار roles پیروی میکند. در سناریو ما دو نقش وجود که شامل نقش لودبالانسر و نقش سرور فلسک میباشد.پلی بوک اصلی با نام site.yml مشابه زیر میباشد:---
- hosts: loadbalancer
  become: yes
  roles:
    - loadbalancer
- hosts: flask_servers
  become: yes
  roles:
    - flask server with two serviceدرباره ساختار پلی بوک در قسمت قبل توضیح داده شد است و این پلی بود دارای دو نقش loadbalancer و flask server with two service میباشد که به ازا هر کدام یک پوشه با نام های مشابه در پوشه roles قرار دارد.ساختار پروژه پلی بوک برای این سناریو به شکل زیر میباشد و درباره آنها توضیح داد خواهد شد:site.yml
inventory
roles/
    flask server with two service/
        tasks/
            main.yml
        handlers/
            main.yml
        templates/
            flask_1/
                hello.py.j2
                index.html.j2
            flask_2/
                hello.py.j2
                index.html.j2
            haproxy.cfg.j2
        vars/
            main.yml
    loadbalancer/
        files/
            haproxy.cfg
        tasks/
            main.yml
        handlers/
            main.yml فایل اصلی پلی بوکیک فایل میباشد که شامل اطلاعات اتصال به نود های هدف و نام گذاری آن میباشد. این نام گذاری همان نام گذاری مورد استفاده در قسمت hosts پلی بوک میباشد.پوشه نقش هاپوشه نقش flask server with two serviceپوشه تسک های نقش سرور فلسکفایل تسک های نقش سرور فلسکپوشه هندلر های نقش سرور فلسکفایل هندلر های نقش سرور فلسکپوشه فایل هایی که در آنها از متغیر های پلی بوک استفاده کردیم و قرار است به روی سرورهایی با نقش سرور فلسک انتقال پیدا کنند.پوشه فایل های سرویس فلسک اول  بر روی سرور هایی که نقش سرور فلسک را دارند.فایل پایتون سرویس فلسک اول بر روی سرور هایی که نقش سرور فلسک را دارند.فایل html سرویس فلسک اول بر روی سرور هایی که نقش سرور فلسک را دارند.پوشه فایل های سرویس فلسک دوم  بر روی سرور هایی که نقش سرور فلسک را دارند.فایل پایتون سرویس فلسک دوم بر روی سرور هایی که نقش سرور فلسک را دارند.فایل html سرویس فلسک دوم بر روی سرور هایی که نقش سرور فلسک را دارند.فایل کانفیگ HAProxy سرورهایی که نقش سرور فلسک را دارند.پوشه متغییر های نقش سرور فلسکفایل متغییر های نقش سرور فلسکپوشه نقش loadbalancerپوشه فایل هایی که قرار است به سرور نقش لودبالانسر انتقال پیدا کند.فایل کانفیگ HAProxy سرور لودبالانسر که در آن از متغییر استفاده نشده است.پوشه تسک های نقش سرور لودبالانسرفایل تسک های نقش سرور لودبالانسرپوشه هندلر های نقش سرور لودبالانسرفایل هندلر های نقش سرور لودبالانسرفایل roles/loadbanalcer/tasks/main.yml که شامل تسک های نقش لودبالانسر میباشد، مشابه زیر است:---
- name: Installing HAproxy on Loadbalance
  apt: 
    name: haproxy
    update_cache: yes
    state: latest

- name: Configure the HAproxy on Loadbalancer
  copy:
    src: haproxy.cfg
    dest: /etc/haproxy/haproxy.cfg
    mode: &#039;755&#039;
  notify: Restart HAproxyتوضیحات: درباره اولین تسک در قسمت ساختار پلی بوک توضیح داده شده است و در دومین تسک با استفاده از ماژول copy فایل کافیگ از مسیر files نقش loadbalancer بر روی مسیر فایل کانفیگ HAProxy سرور کپی میشود  و پس از اعمال تغییرات درخواست اجرای هندلر Restart HAproxy را میدهد.فایل هایroles/loadbanalcer/handlers/main.ymlroles/flask server with two service/handlers/main.ymlکه شامل هندلرهای نفش لودبالانسر و سرور فلسک میباشد،‌ مشابه زیر است:---
- name: Restart HAproxy
  service:
    name: haproxy
    state: restartedتوضیحات: با استفاده از ماژول سرویس درخواست ری استارت سرویس HAProxy داده میشود.فایل roles/flask server with two service/tasks/main.yml که شامل تسک های نقش فلسک سرور میباشد،‌ مشابه زیر است:---
- name: Installing HAproxy and Python3 on Flask Servers
  apt: 
    name:
      - haproxy
      - python3
      - python3-pip
    update_cache: yes
    state: latest

- name: Configure the HAproxy on Flask Servers
  template:
    src: haproxy.cfg.j2
    dest: /etc/haproxy/haproxy.cfg
    mode: &#039;755&#039;
  notify: Restart HAproxy

- name: Installing flask
  shell: pip3 install flask

- name: Create Folders for Flask
  shell: rm -rf /home/flask_1 /home/flask_2 &amp;&amp; mkdir /home/flask_1 /home/flask_2/ /home/flask_1/templates/ /home/flask_2/templates/

- name: Copy Flask 1
  template:
    src: flask_1/hello.py.j2
    dest: /home/flask_1/hello.py
    mode: &#039;755&#039;

- name: Genarate HTML file on Flask 1
  template:
    src: flask_1/index.html.j2
    dest: /home/flask_1/templates/index.html
    mode: &#039;755&#039;

- name: Run the Flask 1
  shell: nohup python3 /home/flask_1/hello.py &amp;

- name: Copy Flask 2
  template:
    src: flask_2/hello.py.j2
    dest: /home/flask_2/hello.py
    mode: &#039;755&#039;

- name: Genarate HTML file on Flask 2
  template:
    src: flask_2/index.html.j2
    dest: /home/flask_2/templates/index.html
    mode: &#039;755&#039;

- name: Run the flask 2
  shell: nohup python3 /home/flask_2/hello.py &amp;توضیحات: نام گذاری تسک به گونه ای انجام شده است که عمکرد هر تسک کاملا مشخص باشد. تمام ماژول های مورد استفاده توضیحات لازم درباره آنها داده شده است به جز ماژول templates که عمکلرد ان مشابه copy است اما به این تفاوت که فایل های با پسوند .j2 (که در آنها از متغییر های پلی بوک استفاده شده است) در هنگام انتقال همان مقدار متغییر را جایگزین میکنند.فایل roles/flask server with two service/vars/main.yml که شامل متغییر های نقش فلسک سرور میباشد، مشابه زیر است:---
flask_1_port: 3000
flask_2_port: 3001فایل inventory که شامل اطلاعات اتصال به نود های هدف و نام گذاری آن میباشد،‌ مشابه زیر است:[loadbalancer]
haproxy     ansible_host=127.0.0.1  ansible_port=22     ansible_user=ansible

[flask_servers]
server_1    ansible_host=127.0.0.1  ansible_port=23     ansible_user=ansible
server_2    ansible_host=127.0.0.1  ansible_port=24     ansible_user=ansible  در اینجا نام گروه ای از نود های مشخص میشود که در ادامه اطلاعات آنها داده خواهد شد.اطلاعات اتصال به یک نود با نام  haproxy همراه با اطلاعات اتصال مانند: ای پی، پورت ssh و نام کاربری برای اتصال داده شده است.خالیدر اینجا نام گروه ای از نود های مشخص میشود که در ادامه اطلاعات آنها داده خواهد شد.اطلاعات اتصال به یک نود با نام server_1 همراه با اطلاعات اتصال مانند: ای پی، پورت ssh و نام کاربری برای اتصال داده شده است.اطلاعات اتصال به یک نود با نام server_2 همراه با اطلاعات اتصال مانند: ای پی، پورت ssh و نام کاربری برای اتصال داده شده است.نکته: در صورتی که انسیل بر روی ماشین مجازی نصب شده است به جای 127.0.0.1 ای پی ماشینی که داکر بر روی آن نصب است را بایستی جایگزین کرد.از اطلاعات این فایل هنگام اجرای پلی بوک استفاده میشود.تمام توضیحات داده شده در این مقاله آموزشی اگرچه زیاد بودند ولی اجرای آن فقط نیازمند چند دستور است که در ادامه اورده شده است. پس از راه اندازی محیط آزمایشگاهی برای دریافت پروژه پلی بوک از گیتهاب و اجرای آن دستورات زیر را بر روی ماشینی که انسیبل را روی آن نصب کردیم، اجرا کنید:git clone https://github.com/amirhne/flask-haproxy-scenario-playbook.git
cd flask-haproxy-scenario-playbook
ansible-playbook -i inventory site.yml --ask-vault-passفایل های پروژه با استفاده از قابلیت ansible-vault رمزنگاری شده اند و پس از اجرای آخرین دستور درخواست پسورد میشود که 1234567 را وارد کنید.فقط همین سه دستور کافی بود که کل سناریو بدون هیچ تنظیم دستی راه اندازی شود و با باز کردن http://127.0.0.1:8080 با هر بار ریفرش یک صفحه متفاوت که شامل اطلاعات سرور و پورت سرویس فلسک میباشد از روی هر کدام از سرویس های فلسک راه اندازی شده به شما نمایش داده میشود.نکته: در صورتی که انسیل بر روی ماشین مجازی نصب شده است به جای 127.0.0.1 ای پی ماشینی که داکر بر روی آن نصب است را بایستی جایگزین کرد.امیدوارم این مطلب برای شما مفید بوده باشد.</description>
                <category>امیر نعمت زاده</category>
                <author>امیر نعمت زاده</author>
                <pubDate>Wed, 02 Sep 2020 22:39:09 +0430</pubDate>
            </item>
                    <item>
                <title>یک سناریو کاربردی با NGINX</title>
                <link>https://virgool.io/mobit-eng/%DB%8C%DA%A9-%D8%B3%D9%86%D8%A7%D8%B1%DB%8C%D9%88-%DA%A9%D8%A7%D8%B1%D8%A8%D8%B1%D8%AF%DB%8C-%D8%A8%D8%A7-nginx-jbma6sjls5db</link>
                <description>در این پست قصد دارم که یک سناریو کاربردی و آموزشی را که با NGINX و در محیط داکر پیاده سازی شده است را توضیح دهم. مخاطب این مطلب کسانی هستند که با عملکرد DNS و ریکورد های DNS Server، وب سرور، داکر و نحوه خواندن کانفیگ فایل های در گنو/لینوکس آشنا هستند. در ابتدا توضیحاتی درباره سناریو داده خواهد شد و در ادامه به تنظیمات NGINX و پیاده سازی سناریو در داخل داکر با استفاده از داکر کامپوز پرداخته میشود.در این پست قرار است که درخواست های یک دامنه و تمامی زیر دامنه های آن در یک وب سرور NGINX به صورت متمرکز کنترل شود. وب سرور NGINX قرار است که در پس زمینه هر درخواست برای دامنه mobit.com را برای سایت mobit.ir و درخواست ها هر زیر دامنه آن را به یک سرور دیگر که فقط خود NGINX به آن دسترسی دارد ارسال کند و پاسخ را به کاربر بدهد. برای پیاده سازی این سناریو از proxy_pass در NGINX استفاده خواهیم کرد.برای کانفیگ NGINX قرار هست که به ازای دامنه mobit.com و هر زیر دامنه آن یک فایل کانفیگ برای NGINX وجود داشته باشد که دستور العمل برخورد با هر کدام از درخواست ها به وب سرور داده شود. کانفیگ فایل برای برخورد با درخواست های mobit.com با نام mobit.com.conf به شکل زیر میباشد که درباره تمام آن در ادامه توضیح داده خواهد شد: server {
             listen 80 default_server;
             listen [::]:80 default_server;
             server_name mobit.com;
             location / {
             proxy_pass         https://mobit.ir; 
             proxy_redirect     off;
             proxy_set_header   Host $host;
             proxy_set_header   X-Real-IP $remote_addr;
             proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
             proxy_set_header   X-Forwarded-Host $server_name;
             }
}در خط اول با server مشخص میکنیم که تنظیمات سرور ما به شکل زیر خواهد بود.در خط دوم و سوم مشخص میکنیم که سرور ما روی چه پورتی سرویس دهد و با default_server میگوییم که اگر هر درخواست دیگری که با تمام شرایط وب سرور تطابق نداشت، به صورت پیشفرض از تنظیمات این سرور برای درخواست به کاربر استفاده شود.در خط چهار گفته میشود که برای پاسخ به دامنه mobit.com از این کانفیگ استفاده شود. با توجه به اینکه در خط قبل از default_server استفاده کردیم برای تمام درخواست های تعریف نشده هم از این کانفیگ استفاده خواهد شد.در خط پنجم گفته میشود که تمام درخواست ها از مسیر اصلی به بعد از کانفیگ های ذکر شده استفاده شود.در خط ششم گفته میشود که تمام درخواست های کاربر به وب سرور در پس زمینه به mobit.ir ارسال شود.در خط هفتم گفته میشود از تغییرات در url توسط سرور پاسخ دهنده جلوگیری شود.از خط هشتم تا یازدهم گفته میشود که در هدر پکت (packet) درخواست تغییراتی داده شود.در خط دوازدهم و سیزدهم گفته شده است که تنظیمات سرور و مسیر تمام شده است.قرار هست برای کنترل درخواست زیر دامنه دیگر به آدرس helloworld.mobit.com و apache.mobit.com ، دو کانفیگ فایل مشابه وجود داشته باشد که تنها تفاوت آنها در نام کانفیگ فایل، عدم وجود default_server در خط دوم و سوم و تغییر مقدار مقابل proxy_pass در خط پنجم میباشد. تا اینجای کار با نحوه کانفیگ وب سرور NGINX آشنا شدیم در ادامه به اجرای NGINX در داخل کانتینر با تنظیمات مورد نظرمان میپردازیم.برای راه اندازی NGINX با کانفیگ دلخواه خودمان از داکر فایل زیر (در صورتی که با داکر فایل آشنا نیستید در اینجا توضیحات کاملی داده شده است) استفاده میکنیم. FROM nginx:latest
MAINTAINER AmirHosein Nematzadeh &lt;me@amirhne.me&gt;
RUN rm -f /etc/nginx/conf.d/default.conf
COPY ./nginx_config /etc/nginx/conf.d/در خط اول گفته میشود که ایمیج مورد نظر ما از چه ایمیجی ساخته شود.در خط دوم نام و اطلاعات فردی که سازنده ایمیج هست ذکر شده است.در خط سوم کانفیگ فایل پیشقرض NGINX حذف میشوددر خط چهارم کلیه کانفیگ فایل های روی سیستم در مسیری کانفیگ فایل های NGINX قرار میگیرد.با استفاده از این داکر فایل میتوانیم NGINX مورد نظرمان را برای پیاده سازی سناریو داشته باشیم. در ادامه برای پیاده سازی سناریو از داکر کامپوز استفاده میکنیم.داکر کامپوز به منظور راه اندازی چند کانتیر وابسته به صورت هزمان در یک پروژه مورد استفاده قرار میگردد که بسیار بهینه تر و سریع تر از دستور docker run برای راه اندازی هر کانتینر به صورت دستی میباشد. داکر کامپوز از یک فایل YAML برای راه اندازی و کانفیگ کانتیتر ها استفاده میکند.نام پیشفرض فایل YAML که برای داکر کامپوز استفاده میشود، docker-compose.yml میباشد که برای سهولت اجرای دستور داکر کامپوز از این نام استفاده میشود.فایل YAML ما به شکل زیر میباشد که درباره تمام آن در ادامه توضیح داده خواهد شد:   version: &#039;3.8&#039;
   services:
    nginx_for_subdomain_scenario:
       build:
         context: .
         dockerfile: nginx.Dockerfile
       ports: 
         - &#039;80:80&#039;
       depends_on:
        - helloworld
        - apache
    helloworld:
       image: amirhne/hello_world_flask_app
    apache:
       image: httpd در خط اول نسخه فایل YAML مشخص میشود که آخرین نسخه انتخاب شده است.در خط دوم گفته شده است که کانینر های راه اندازی شده چه خواهند بود.در خط سوم نام کانتینر NGINX مشخص میشود که مشابه docker run --name هست.در خط چهارم مشخص میشود که کانتینر بایستی از رو یک داکر فایل ساخته شود.در خط پنجم مسیر داکر فایل مشخص میشود که مسیری است که فایل YAML در آن قرار دارد. این همان داکر فایلی هست که نحوه ساخت آن قبل تر توضیح داده شد.در خط ششم نام داکر فایل داده میشود. در خط هفتم گفته میشود که چه پورت هایی از خارج کانتینر در دسترس باشند مشابه دستور: docker run -p در خط هشتم مشخص میشود چه پورتی از کانتینر به چه پورتی از بیرون فوروارد شود.در خط نهم مشخص میشود که این کانتینر وابسته به راه اندازی چه کانتینر هایی میباشد.در خط دهم و یازدم نام کانتینرهایی که NGINX به آن وابسته هست داده شده است.در خط دوازدهم نام کانتیتر جدید برای راه اندازی داده شده است.در خط سیزدهم گفته شده است که این کانتینر از چه ایمیجی از روی داکر هاب ساخته شود. این همان ایمیجی هست که در مطلب قبلی ساخته شده است و یک اپلیکشن ساده تحت وب میباشد.در خط چهاردهم نام کانتیتر جدید برای راه اندازی داده شده است.در خط پانزدهم گفته شده است که این کانتینر از چه ایمیجی از روی داکر هاب ساخته شود. این ایمیج وب  سرویس آپاچی هست که یه صفحه وب ساده به صورت پیشفرض روی آن در دسترس میباشد.نکته مهم: فاصله ها در این فایل بسیار مهم میباشد و بایستی حتما سلسله مراتب در نوشتن این فایل رعایت شود.نکته مهم: داکر دارای یک DNS سرور داخلی در هر شبکه خود هست و تمام کانتیر هایی که در یک شبکه قرار دارند تنها با نام میتوانند با یکدیگر ارتباط برقرار کنند. با استفاده از همین قابلیت در کانفیگ فایل های NGINX که برای دو زیر دامنه ایجاد شده اند در خط ششم و قسمت proxy_pass فقط نام کانتینر قرار داده شده است. یعنی به شکل زیر: proxy_pass          http://helloworld:5000;وproxy_pass           http://apache;با استفاده از این قابلیت درخواست ها به سمت این دو کانتینر هدایت میشوند.این فایل کانفیگ تمامی تنظیمات لازم برای راه اندازی سناریو ما را دارد که تنها بایستی اجرا شود ولی قبل از آن بایستی مشخص کرد که برای دامنه های مورد نظر برای باز شدن به چه آی پی ترجمه (Resolve) شوند. از انجایی که سناریو مورد نظر فقط قرار هست که بر روی ماشین محلی اجرا شود میتوان با ویرایش فایل hosts سیستم عامل ماشینتان بگویید که این وب سایت روی ماشین محلی هستند.برای این کار ریکورد های زیر را به فایل hosts سیستم تان اضافه کنید:127.0.0.1                   mobit.com
127.0.0.1                   www.mobit.com
127.0.0.1                   helloworld.mobit.com
127.0.0.1                   apache.mobit.comفایل hosts در سیستم عامل گنو/لینوکس در مسیر زیر قرار دارد:/etc/hostsو در سیستم عامل ویندوز در مسیر زیر قرار دارد:c:\Windows\System32\Drivers\etc\hostsدر ادامه میتوانید تمام پروژه را که شامل تمامی کانفیگ فایل ها، داکر فایل و فایل داکر کامپوز هست را با دستور زیر از گیتهاب دریافت کنید و به مسیر پروژه بروید:git clone https://github.com/amirhne/nginx-subdomain-scenario.git
cd nginx-subdomain-scenarioبرای اجرای پروژه این سناریو بایستی حتما داکر و داکر-کامپوز را روی ماشینتان نصب داشته باشید و با اتصال به وی پی ان یا استفاده از شکن دستور زیر را در مسیر اصلی پروژه ای که از گیت هاب دریافت کردید، بزنید:docker-compose up -dحالا میتوانید با رفتن به دامنه http://mobit.com سایت mobit.ir و http://helloworld.mobit.com وب اپلیکیشن فلسک و http://apache.mobit.com وب سرور اپاچی را باز کنید.برای بستن پروژه هم باید از دستور زیر استفاده کنید:docker-compose down --rmi localامیدوارم این مطلب برای شما مفید بوده باشد.</description>
                <category>امیر نعمت زاده</category>
                <author>امیر نعمت زاده</author>
                <pubDate>Mon, 17 Aug 2020 14:34:01 +0430</pubDate>
            </item>
                    <item>
                <title>چگونه یک اپلیکشن ساده تحت وب را در داکر قرار دهیم؟</title>
                <link>https://virgool.io/mobit-eng/%DA%86%DA%AF%D9%88%D9%86%D9%87-%DB%8C%DA%A9-%D8%A7%D9%BE%D9%84%DB%8C%DA%A9%D8%B4%D9%86-%D8%B3%D8%A7%D8%AF%D9%87-%D8%AA%D8%AD%D8%AA-%D9%88%D8%A8-%D8%B1%D8%A7-%D8%AF%D8%B1-%D8%AF%D8%A7%DA%A9%D8%B1-%D9%82%D8%B1%D8%A7%D8%B1-%D8%AF%D9%87%DB%8C%D9%85-d8k42myvmfsn</link>
                <description>در این پست قصد دارم که چگونگی قرار دادن یک اپلیکشن تحت وب که با فلسک نوشته است رو در داکر توضیح بدم. این مطلب برای شروع یادگیری داکر نوشته شده است و مخاطب این مطلب کسانی اند که با مفاهیم داکر آشنا هستند و با محیط دستوری گنو/لینوکس آشنایی دارند. در ابتدا توضیحاتی درباره محیط اجرای اپلیکشن وب فلسک داده خواهد شد و بعد از آن به انتقال و اجرای آن در محیط داکر میپردازم.فلسک یک فرمورک تحت وب هست که برای زبان برنامه نویسی پایتون ساخته شده است و قاعدتا برای اجرای یک اپلیکشن تحت وب فلسک نیازمند نصب پایتون هستید، بعد از نصب پایتون روی سیستم عامل با استفاده از پکیج منجر پایتون (pip) بایستی فلسک نصب شود.با توضیحات داده شده مشخص شد که برای اجرای اپلیکشن تحت وب بایستی چه محیط و نیازمندی (dependency) نصب باشد. بسته به توزیع لینوکسی که قرار هست در آن وب اولیکشن اجرا شود دستورات متفاوت خواهد بود. برای مثال برای نصب نیازمندی ها در سیستم عامل های که از پایه دبین (Debian Based) ساخته شده اند مثل اوبونتو باید از دستور زیر استفاده کرد:sudo apt update &amp;&amp; apt install python3
python3 install pipاما برای کوچکتر و بهینه تر شدن در داکر بهتر هست از Alpine استفاده شود. Alpine یک توزیع لینوکس بسیار کوچیک شده هست که استفاده از اون برای ایجاد یک داکر ایمیج بسیار رایج هست. تفاوتی که استفاده از این توزیع وجود دارد در پکیج منیجر آن هست که apk هست. برای مثال برای نصب نیازمندی های قبلی از دستورات زیر استفاده میشود:apk update &amp;&amp; apk add py-pip
pip install flask در نهایت وب اپلیکشنی که قرار هست که اجرا شود با نام hello.py در مسیر اصلی پروژه قرار دارد و به این صورت هست:from flask import Flask, render_template
app = Flask(__name__)

@app.route(&#039;/&#039;)
def hello_world():
              return render_template(&#039;index.html&#039;)

if __name__ == &#039;__main__&#039;:
              app.run(debug=True,host=&#039;0.0.0.0&#039;)در مسیر اصلی پروژه یک پوشه به نام templates قرار دارد که پس از اجرای این کد صفحه ساده ای که در آن قرار دارد به کاربر نمایش داده میشود. برای دسترسی به پروژه از دستورات زیر استفاده کنید:git clone https://github.com/amirhne/dockerized-hello-world-flask-app.git
cd dockerized-hello-world-flask-app/projectبرای اجرای این اپلیکشین در مسیری که فایل hello.py در آن قرار دارد، دستور زیر را بزنید:python3 hello.pyو بعد از آن پروژه بر روی سیستم شما با پورت ۵۰۰۰ در دسترس خواهد بود و با وارد کردن ادرس http://127.0.0.1:5000 پروژه اجرا خواهد شد.تا اینجای کار این پروژه بر روی سیستم شما اجرا شده است و در این قسمت قرار هست که این وب اپلیکشین در محیط داکر اجرا شود. اپلیکشین ما قرار هست در داخل یک کانتینر اجرا شود و عمکرد داکر به گونه است که برای اجرای هر کانتینر به یک ایمیج نیازمندیم. هر ایمیج به صورت لایه ای و از یک ایمیج قبلی ساخته میشود و کانترینر که قرار هست اپلیکشین ما را اجرا کند خودش یک پراسس (process) هست که از رو ایمیج ساخت شده است.برای ساخت یک ایمیج از یک ایمیج قبلی و اضافه کردن نیازمندی هایمان نیازمند که دستور العمل هستیم، دقیقا مانند یه دستور العمل آشپزی که مرحله به مرحله قرار هست یه چیز به مواد خام اضافه شود. به این دستور العمل داکر فایل گفته میشود. داکر فایلی که قرار هست که ما برای ساخت ایمیج از آن استفاده کنیم به شکل زیر هست:FROM alpine:latest
MAINTAINER AmirHosein Nematzadeh &lt;me@amirhne.me&gt;
EXPOSE 5000
RUN mkdir /home/hello_world
WORKDIR /home/hello_world/
COPY project /home/hello_world
RUN apk update &amp;&amp; apk add py-pip &amp;&amp; pip install flask 
CMD python3 /home/hello_world/hello.pyاین داکر فایل دستور العمل ساخت ایمیج مورد نظر ماست که به صورت خط به خط آن رو توضیح میدم ۱. در خط اول گفته میشود که از چه ایمیجی پایه ای، ایمج ما ساخته شود۲.در خط دوم نام و اطلاعات فردی که سازنده ایمیج هست ذکر شده است۳. در خط سوم گفته شده است که پورت ۵۰۰۰ از بیرون کانترینر در دسترس قرار داشته باشد.۴. در خط چهارم دستور ساخت یه مسیر داده شده است۵. در خط پنجم مسیر کار سیستم عامل مشخص شده است۶. در خط ششم گفته شده است که محتویات پوشه project که در کنار داکر فایل قرار دارد در مسیر پوشه ای که در خط چهارم در داخل ایمیج ساخته شده است، ریخته شود.۷. در خط هفتم دستورات نصب نیازمندی های ما برای اجرای اپلیکیشن داده شده است.۸. در آخرین خط گفته میشود که در صورتی که کانترینر از روی ایمیج ساخته شد،‌ در لحظه اجرا این دستورات هم اجرا شود.برای دسترسی این داکرفایل از گیت هاب و ساخت ایمیج از روی آن از دستورات زیر استفاده کنید:git clone https://github.com/amirhne/dockerized-hello-world-flask-app.git
cd dockerized-hello-world-flask-app
docker build -t hello_world_flask_app .همیچنین برای دانلود ایمیج از قبل ساخته شده با داشتن اتصال وی پی ان یا استفاده از شکن از دستور زیر میتونید استفاده کنید:docker pull amirhne/hello_world_flask_appحالا همه چیز آماده هست که کانترینر شما از روی این ایمیج ایجاد بشه و از بیرون به اون دسترسی داشته باشید. برای اجرای کانتینر باید از دستور زیر استفاده کنید:docker run -d -p 80:5000 --name hello_world hello_world_flask_appدر اینجا گفته میشود که کانتیر در پس زمینه (-d) و با نام هلو ورلد (--name) از روی ایمیج hello_world_flask_app ساخته شود و پورت ۵۰۰۰ کانتیرنر ایجاد شده به پورت ۸۰ ماشین (-p)فوروارد شود.برای اینکه از راه اندازی و اجرای کانتینر اطمینان حاصل کنی از دستور زیر استفاده کنید:docker psخروجی باشد شبیه زیر باشد:CONTAINER ID        IMAGE                   COMMAND                  CREATED             STATUS                    PORTS                  NAMES
6cdf53855fcf        hello_world_flask_app   &amp;quot/bin/sh -c &#039;python3…&amp;quot   5 seconds ago       Up 3 seconds              0.0.0.0:80-&gt;5000/tcp   hello_worldالان شما بایستی وب اپلیکشن که در داخل کانتینر اجرا شده را روی سیستم با پورت ۸۰ داشته باشید و با زدن http://127.0.0.1 در مرورگر به آن دسترسی داشته باشید.امیدوارم این مطلب برای شما مفید بوده باشد.</description>
                <category>امیر نعمت زاده</category>
                <author>امیر نعمت زاده</author>
                <pubDate>Thu, 13 Aug 2020 11:29:36 +0430</pubDate>
            </item>
            </channel>
</rss>