مهاجرت از Nginx به Envoy Proxy

سلام، هابر! ترجمه ای از این پست را مورد توجه شما قرار می دهم: مهاجرت از Nginx به Envoy Proxy.

Envoy یک سرور پراکسی توزیع شده با کارایی بالا (نوشته شده در ++C) است که برای سرویس ها و برنامه های کاربردی طراحی شده است، همچنین یک گذرگاه ارتباطی و "سطح داده جهانی" است که برای معماری های "خدمات مش" میکروسرویس بزرگ طراحی شده است. هنگام ایجاد آن، راه حل هایی برای مشکلاتی که در طول توسعه سرورهایی مانند NGINX، HAProxy، متعادل کننده بار سخت افزاری و متعادل کننده بار ابری به وجود آمد، در نظر گرفته شد. Envoy در کنار هر برنامه کار می کند و شبکه را خلاصه می کند تا بدون توجه به پلتفرم، عملکردهای مشترک را ارائه دهد. هنگامی که تمام ترافیک سرویس در یک زیرساخت از طریق شبکه Envoy جریان می یابد، تجسم مناطق مشکل با قابلیت مشاهده ثابت، تنظیم عملکرد کلی و افزودن عملکرد اصلی در یک مکان خاص آسان می شود.

توانمندی ها

  • معماری خارج از فرآیند: envoy یک سرور مستقل و با کارایی بالا است که مقدار کمی از RAM را اشغال می کند. این در ارتباط با هر زبان برنامه یا فریم ورک کار می کند.
  • پشتیبانی http/2 و grpc: envoy دارای پشتیبانی درجه یک http/2 و grpc برای اتصالات ورودی و خروجی است. این یک پروکسی شفاف از http/1.1 تا http/2 است.
  • متعادل سازی بار پیشرفته: نماینده از ویژگی های متعادل کننده بار پیشرفته از جمله تلاش مجدد خودکار، شکستن زنجیره، محدود کردن نرخ جهانی، سایه زدن درخواست، متعادل کردن بار منطقه محلی و غیره پشتیبانی می کند.
  • API مدیریت پیکربندی: envoy یک API قوی برای مدیریت پویا پیکربندی شما ارائه می دهد.
  • قابلیت مشاهده: قابلیت مشاهده عمیق ترافیک L7، پشتیبانی بومی برای ردیابی توزیع شده و قابلیت مشاهده mongodb، dynamodb و بسیاری از برنامه های کاربردی دیگر.

مرحله 1 - مثال پیکربندی NGINX

این اسکریپت از یک فایل خاص ساخته شده استفاده می کند nginx.conf، بر اساس مثال کامل از ویکی NGINX. با باز کردن می توانید پیکربندی را در ویرایشگر مشاهده کنید nginx.conf

پیکربندی منبع nginx

user  www www;
pid /var/run/nginx.pid;
worker_processes  2;

events {
  worker_connections   2000;
}

http {
  gzip on;
  gzip_min_length  1100;
  gzip_buffers     4 8k;
  gzip_types       text/plain;

  log_format main      '$remote_addr - $remote_user [$time_local]  '
    '"$request" $status $bytes_sent '
    '"$http_referer" "$http_user_agent" '
    '"$gzip_ratio"';

  log_format download  '$remote_addr - $remote_user [$time_local]  '
    '"$request" $status $bytes_sent '
    '"$http_referer" "$http_user_agent" '
    '"$http_range" "$sent_http_content_range"';

  upstream targetCluster {
    172.18.0.3:80;
    172.18.0.4:80;
  }

  server {
    listen        8080;
    server_name   one.example.com  www.one.example.com;

    access_log   /var/log/nginx.access_log  main;
    error_log  /var/log/nginx.error_log  info;

    location / {
      proxy_pass         http://targetCluster/;
      proxy_redirect     off;

      proxy_set_header   Host             $host;
      proxy_set_header   X-Real-IP        $remote_addr;
    }
  }
}

پیکربندی‌های NGINX معمولاً دارای سه عنصر کلیدی هستند:

  1. پیکربندی سرور NGINX، ساختار گزارش و عملکرد Gzip. این در همه موارد به صورت جهانی تعریف شده است.
  2. پیکربندی NGINX برای پذیرش درخواست ها به میزبان one.example.com در پورت 8080
  3. تنظیم مکان هدف، نحوه مدیریت ترافیک برای بخش‌های مختلف URL.

همه پیکربندی‌ها برای Envoy Proxy اعمال نمی‌شوند و نیازی به پیکربندی برخی تنظیمات ندارید. فرستاده پروکسی دارد چهار نوع کلیدی، که از زیرساخت اصلی ارائه شده توسط NGINX پشتیبانی می کنند. هسته این است:

  • شنوندگان: آنها تعیین می کنند که Envoy Proxy چگونه درخواست های دریافتی را می پذیرد. Envoy Proxy در حال حاضر فقط از شنوندگان مبتنی بر TCP پشتیبانی می کند. هنگامی که یک اتصال برقرار شد، برای پردازش به مجموعه ای از فیلترها منتقل می شود.
  • فیلترها: آنها بخشی از معماری خط لوله هستند که می توانند داده های ورودی و خروجی را پردازش کنند. این قابلیت شامل فیلترهایی مانند Gzip است که داده ها را قبل از ارسال به مشتری فشرده می کند.
  • روترها: آنها ترافیک را به مقصد مورد نیاز، که به عنوان یک خوشه تعریف شده است، هدایت می کنند.
  • خوشه ها: آنها نقطه پایانی را برای پارامترهای ترافیک و پیکربندی تعریف می کنند.

ما از این چهار مؤلفه برای ایجاد یک پیکربندی Envoy Proxy برای مطابقت با پیکربندی خاص NGINX استفاده خواهیم کرد. هدف Envoy کار با API ها و پیکربندی پویا است. در این مورد، پیکربندی پایه از تنظیمات ثابت و رمزگذاری شده از NGINX استفاده خواهد کرد.

مرحله 2 - پیکربندی NGINX

بخش اول nginx.conf برخی از داخلی های NGINX را تعریف می کند که باید پیکربندی شوند.

ارتباطات کارگری

پیکربندی زیر تعداد فرآیندها و اتصالات کارگر را تعیین می کند. این نشان می دهد که چگونه NGINX برای پاسخگویی به تقاضا مقیاس خواهد شد.

worker_processes  2;

events {
  worker_connections   2000;
}

Envoy Proxy گردش کار و اتصالات را به روش های مختلف مدیریت می کند.

Envoy برای هر رشته سخت افزاری در سیستم یک thread کارگر ایجاد می کند. هر نخ کارگر یک حلقه رویداد غیر مسدود کننده را اجرا می کند که مسئول آن است

  1. گوش دادن به هر شنونده
  2. پذیرش ارتباطات جدید
  3. ایجاد مجموعه ای از فیلترها برای اتصال
  4. تمام عملیات I/O را در طول عمر اتصال پردازش کنید.

تمام پردازش های اتصال بیشتر به طور کامل در موضوع کارگر انجام می شود، از جمله هر گونه رفتار ارسال.

برای هر نخ کارگر در Envoy، یک اتصال Pool وجود دارد. بنابراین، استخرهای اتصال HTTP/2 تنها یک اتصال به ازای هر میزبان خارجی در یک زمان برقرار می‌کنند، اگر چهار رشته کاری وجود داشته باشد، چهار اتصال HTTP/2 به ازای هر میزبان خارجی در حالت پایدار وجود خواهد داشت. با نگه داشتن همه چیز در یک رشته کارگر، تقریباً همه کدها را می توان بدون مسدود کردن نوشت، انگار که یک رشته است. اگر تعداد رزوه های کارگر بیشتر از حد لازم تخصیص داده شود، این امر می تواند منجر به هدر رفتن حافظه، ایجاد تعداد زیادی اتصالات بیکار و کاهش تعداد دفعات بازگشت اتصالات به استخر شود.

برای اطلاعات بیشتر مراجعه کنید وبلاگ نماینده پروکسی.

پیکربندی HTTP

بلوک پیکربندی NGINX زیر تنظیمات HTTP مانند:

  • چه نوع مایم پشتیبانی می شود
  • وقفه های پیش فرض
  • پیکربندی Gzip

می‌توانید این جنبه‌ها را با استفاده از فیلترهای موجود در Envoy Proxy سفارشی کنید، که بعداً در مورد آن صحبت خواهیم کرد.

مرحله 3 - پیکربندی سرور

در بلوک پیکربندی HTTP، پیکربندی NGINX برای گوش دادن به پورت 8080 و پاسخ به درخواست‌های ورودی برای دامنه‌ها مشخص می‌کند. one.example.com и www.one.example.com.

 server {
    listen        8080;
    server_name   one.example.com  www.one.example.com;

Inside Envoy توسط Listeners کنترل می شود.

شنوندگان را فرستاد

مهمترین جنبه شروع کار با Envoy Proxy تعریف شنوندگان شما است. شما باید یک فایل پیکربندی ایجاد کنید که نحوه اجرای نمونه Envoy را توضیح دهد.

قطعه زیر یک شنونده جدید ایجاد می کند و آن را به پورت 8080 متصل می کند. پیکربندی به Envoy Proxy می گوید که برای درخواست های دریافتی باید به کدام پورت ها متصل شود.

Envoy Proxy از نماد YAML برای پیکربندی خود استفاده می کند. برای آشنایی با این نماد، اینجا را ببینید پیوند.

Copy to Editorstatic_resources:
  listeners:
  - name: listener_0
    address:
      socket_address: { address: 0.0.0.0, port_value: 8080 }

نیازی به تعریف نیست نام ارائهکننده، زیرا فیلترهای Envoy Proxy این کار را انجام می دهند.

مرحله 4 - پیکربندی مکان

هنگامی که یک درخواست وارد NGINX می شود، بلوک مکان نحوه پردازش و مسیریابی ترافیک را تعیین می کند. در قطعه زیر، تمام ترافیک سایت به یک خوشه upstream (یادداشت مترجم: upstream معمولاً یک سرور برنامه است) به نام کلاستر منتقل می شود. targetCluster. خوشه بالادست گره هایی را تعریف می کند که باید درخواست را پردازش کنند. در مرحله بعد در این مورد بحث خواهیم کرد.

location / {
    proxy_pass         http://targetCluster/;
    proxy_redirect     off;

    proxy_set_header   Host             $host;
    proxy_set_header   X-Real-IP        $remote_addr;
}

در Envoy، Filters این کار را انجام می دهد.

فیلترهای فرستاده

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

Copy to Editor    filter_chains:
    - filters:
      - name: envoy.http_connection_manager
        config:
          codec_type: auto
          stat_prefix: ingress_http
          route_config:
            name: local_route
            virtual_hosts:
            - name: backend
              domains:
                - "one.example.com"
                - "www.one.example.com"
              routes:
              - match:
                  prefix: "/"
                route:
                  cluster: targetCluster
          http_filters:
          - name: envoy.router

نام فرستاده.http_connection_manager یک فیلتر داخلی در Envoy Proxy است. فیلترهای دیگر عبارتند از Redis, Mongo ها, TCP. لیست کامل را می توانید در اینجا پیدا کنید مستندات.

برای کسب اطلاعات بیشتر در مورد سایر سیاست های متعادل کننده بار، به سایت مراجعه کنید اسناد فرستاده.

مرحله 5 - پیکربندی پروکسی و Upstream

در NGINX، پیکربندی upstream مجموعه ای از سرورهای هدف را تعریف می کند که ترافیک را پردازش می کنند. در این مورد، دو خوشه اختصاص داده شد.

  upstream targetCluster {
    172.18.0.3:80;
    172.18.0.4:80;
  }

در Envoy، این توسط خوشه ها مدیریت می شود.

خوشه های فرستاده

معادل بالادستی به عنوان خوشه تعریف می شود. در این صورت میزبان هایی که به ترافیک خدمات رسانی می کنند مشخص شده اند. نحوه دسترسی به هاست ها، مانند مهلت زمانی، به عنوان یک پیکربندی خوشه تعریف می شود. این اجازه می دهد تا کنترل دانه ای بیشتری بر جنبه هایی مانند تأخیر و تعادل بار داشته باشید.

Copy to Editor  clusters:
  - name: targetCluster
    connect_timeout: 0.25s
    type: STRICT_DNS
    dns_lookup_family: V4_ONLY
    lb_policy: ROUND_ROBIN
    hosts: [
      { socket_address: { address: 172.18.0.3, port_value: 80 }},
      { socket_address: { address: 172.18.0.4, port_value: 80 }}
    ]

هنگام استفاده از سرویس کشف STRICT_DNS Envoy به طور مداوم و ناهمزمان اهداف DNS مشخص شده را حل می کند. هر آدرس IP برگشتی از نتیجه DNS یک میزبان صریح در خوشه بالادست در نظر گرفته می شود. این بدان معناست که اگر یک درخواست دو آدرس IP را برگرداند، Envoy فرض می‌کند که دو میزبان در کلاستر وجود دارد و هر دو باید در بارگذاری متعادل باشند. اگر میزبانی از نتیجه حذف شود، Envoy فرض می‌کند که دیگر وجود ندارد و ترافیک را از هر استخر اتصال موجود می‌کشد.

برای اطلاعات بیشتر ببین اسناد پروکسی فرستاده.

مرحله 6 - دسترسی به گزارش و خطاها

پیکربندی نهایی ثبت نام است. Envoy Proxy به جای فشار دادن گزارش‌های خطا به دیسک، رویکردی مبتنی بر ابر را در پیش می‌گیرد. همه گزارش های برنامه خروجی به stdout и استدرر.

هنگامی که کاربران درخواستی ارائه می دهند، گزارش های دسترسی اختیاری هستند و به طور پیش فرض غیرفعال می شوند. برای فعال کردن گزارش‌های دسترسی برای درخواست‌های HTTP، پیکربندی را فعال کنید دسترسی_لاگ برای مدیر اتصال HTTP. مسیر می تواند یا دستگاهی مانند stdoutبسته به نیاز شما، یا یک فایل روی دیسک.

پیکربندی زیر همه گزارش‌های دسترسی را به آن هدایت می‌کند stdout (یادداشت مترجم - stdout برای استفاده از envoy در داخل docker لازم است. اگر بدون docker استفاده می شود، سپس /dev/stdout را با مسیر یک فایل log معمولی جایگزین کنید). قطعه را در بخش پیکربندی مدیر اتصال کپی کنید:

Copy to Clipboardaccess_log:
- name: envoy.file_access_log
  config:
    path: "/dev/stdout"

نتایج باید به این صورت باشد:

      - name: envoy.http_connection_manager
        config:
          codec_type: auto
          stat_prefix: ingress_http
          access_log:
          - name: envoy.file_access_log
            config:
              path: "/dev/stdout"
          route_config:

به طور پیش فرض، Envoy دارای یک رشته قالب است که شامل جزئیات درخواست HTTP است:

[%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"n

نتیجه این رشته فرمت:

[2018-11-23T04:51:00.281Z] "GET / HTTP/1.1" 200 - 0 58 4 1 "-" "curl/7.47.0" "f21ebd42-6770-4aa5-88d4-e56118165a7d" "one.example.com" "172.18.0.4:80"

محتوای خروجی را می توان با تنظیم فیلد قالب سفارشی کرد. مثلا:

access_log:
- name: envoy.file_access_log
  config:
    path: "/dev/stdout"
    format: "[%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"n"

با تنظیم فیلد می توان خط ورود به سیستم را با فرمت JSON نیز خروجی داد json_format. به عنوان مثال:

access_log:
- name: envoy.file_access_log
  config:
    path: "/dev/stdout"
    json_format: {"protocol": "%PROTOCOL%", "duration": "%DURATION%", "request_method": "%REQ(:METHOD)%"}

برای اطلاعات بیشتر در مورد روش ثبت نام فرستاده، مراجعه کنید

https://www.envoyproxy.io/docs/envoy/latest/configuration/access_log#config-access-log-format-dictionaries

ورود به سیستم تنها راه برای به دست آوردن بینش در کار با Envoy Proxy نیست. قابلیت‌های ردیابی و متریک پیشرفته در آن تعبیه شده است. می توانید اطلاعات بیشتری کسب کنید در اسناد ردیابی و یا از طریق اسکریپت ردیابی تعاملی.

مرحله 7 - راه اندازی

اکنون پیکربندی خود را از NGINX به Envoy Proxy منتقل کرده اید. آخرین مرحله راه اندازی یک نمونه Envoy Proxy برای آزمایش آن است.

به عنوان کاربر اجرا شود

در بالای خط پیکربندی NGINX کاربر www www; مشخص می کند که NGINX را به عنوان یک کاربر با امتیاز پایین برای بهبود امنیت اجرا کند.

Envoy Proxy یک رویکرد مبتنی بر ابر را برای مدیریت مالک یک فرآیند اتخاذ می کند. وقتی Envoy Proxy را از طریق یک کانتینر اجرا می کنیم، می توانیم یک کاربر با امتیاز پایین را مشخص کنیم.

راه اندازی Envoy Proxy

دستور زیر Envoy Proxy را از طریق یک کانتینر Docker در هاست اجرا می کند. این دستور به Envoy توانایی گوش دادن به درخواست‌های ورودی در پورت 80 را می‌دهد. با این حال، همانطور که در پیکربندی شنونده مشخص شده است، Envoy Proxy به ترافیک ورودی در پورت 8080 گوش می‌دهد. این به فرآیند اجازه می‌دهد تا به عنوان یک کاربر با امتیاز پایین اجرا شود.

docker run --name proxy1 -p 80:8080 --user 1000:1000 -v /root/envoy.yaml:/etc/envoy/envoy.yaml envoyproxy/envoy

آزمایش

با اجرای پروکسی، اکنون می توان آزمایش ها را ساخت و پردازش کرد. دستور cURL زیر یک درخواست با سربرگ میزبان تعریف شده در پیکربندی پروکسی صادر می کند.

curl -H "Host: one.example.com" localhost -i

درخواست HTTP منجر به خطا می شود 503. این به این دلیل است که اتصالات بالادست کار نمی کنند و در دسترس نیستند. بنابراین، Envoy Proxy هیچ مقصدی برای درخواست ندارد. دستور زیر مجموعه ای از سرویس های HTTP را شروع می کند که با پیکربندی تعریف شده برای Envoy مطابقت دارد.

docker run -d katacoda/docker-http-server; docker run -d katacoda/docker-http-server;

با خدمات موجود، Envoy می تواند با موفقیت ترافیک پراکسی را به مقصد خود هدایت کند.

curl -H "Host: one.example.com" localhost -i

باید پاسخی ببینید که نشان می‌دهد کدام کانتینر Docker درخواست را پردازش کرده است. در لاگ های Envoy Proxy باید یک خروجی رشته دسترسی را نیز مشاهده کنید.

هدرهای پاسخ HTTP اضافی

سرصفحه های HTTP اضافی را در سرصفحه های پاسخ درخواست واقعی خواهید دید. هدر زمانی را نشان می دهد که میزبان بالادستی برای پردازش درخواست صرف کرده است. در میلی ثانیه بیان می شود. اگر مشتری بخواهد زمان سرویس را در مقایسه با تاخیر شبکه تعیین کند، مفید است.

x-envoy-upstream-service-time: 0
server: envoy

پیکربندی نهایی

static_resources:
  listeners:
  - name: listener_0
    address:
      socket_address: { address: 0.0.0.0, port_value: 8080 }
    filter_chains:
    - filters:
      - name: envoy.http_connection_manager
        config:
          codec_type: auto
          stat_prefix: ingress_http
          route_config:
            name: local_route
            virtual_hosts:
            - name: backend
              domains:
                - "one.example.com"
                - "www.one.example.com"
              routes:
              - match:
                  prefix: "/"
                route:
                  cluster: targetCluster
          http_filters:
          - name: envoy.router
          clusters:
  - name: targetCluster
    connect_timeout: 0.25s
    type: STRICT_DNS
    dns_lookup_family: V4_ONLY
    lb_policy: ROUND_ROBIN
    hosts: [
      { socket_address: { address: 172.18.0.3, port_value: 80 }},
      { socket_address: { address: 172.18.0.4, port_value: 80 }}
    ]

admin:
  access_log_path: /tmp/admin_access.log
  address:
    socket_address: { address: 0.0.0.0, port_value: 9090 }

اطلاعات تکمیلی از مترجم

دستورالعمل نصب Envoy Proxy را می توان در وب سایت یافت https://www.getenvoy.io/

به طور پیش فرض، rpm پیکربندی سرویس systemd ندارد.

اضافه کردن systemd service config /etc/systemd/system/envoy.service:

[Unit]
Description=Envoy Proxy
Documentation=https://www.envoyproxy.io/
After=network-online.target
Requires=envoy-auth-server.service
Wants=nginx.service

[Service]
User=root
Restart=on-failure
ExecStart=/usr/bin/envoy --config-path /etc/envoy/config.yaml
[Install]
WantedBy=multi-user.target

باید یک دایرکتوری /etc/envoy/ ایجاد کنید و config.yaml را در آنجا قرار دهید.

یک چت تلگرام با استفاده از پروکسی envoy وجود دارد: https://t.me/envoyproxy_ru

Envoy Proxy از ارائه محتوای ثابت پشتیبانی نمی کند. بنابراین، چه کسی می تواند به این ویژگی رای دهد: https://github.com/envoyproxy/envoy/issues/378

فقط کاربران ثبت نام شده می توانند در نظرسنجی شرکت کنند. ورود، لطفا.

آیا این پست شما را تشویق به نصب و آزمایش پروکسی envoy کرد؟

  • بله

  • هیچ

75 کاربر رای دادند. 18 کاربر رای ممتنع دادند.

منبع: www.habr.com

اضافه کردن نظر