<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های عرفان جعفری زمان</title>
        <link>https://virgool.io/feed/@m_10343082</link>
        <description></description>
        <language>fa</language>
        <pubDate>2026-06-16 16:02:52</pubDate>
        <image>
            <url>https://static.virgool.io/images/default-avatar.jpg</url>
            <title>عرفان جعفری زمان</title>
            <link>https://virgool.io/@m_10343082</link>
        </image>

                    <item>
                <title>بک آپ پوستگرس با pq_dumpall</title>
                <link>https://virgool.io/@m_10343082/%D8%A8%DA%A9-%D8%A2%D9%BE-%D9%BE%D9%88%D8%B3%D8%AA%DA%AF%D8%B1%D8%B3-%D8%A8%D8%A7-pqdumpall-wbplzd5jerph</link>
                <description>برای بکاپگیری از تمام اطلاعات پوستگرس از دستور pq_dumpall می توان استفاده کرد یا به ازای هر یک از دیتابیس های موجود در پوستگرس دستور pq_dump را اجرا نمود و فقط از دیتابیس مورد نظر به صورت زیر بکاپ گرفت:$ pg_dump -h host -U username -p port dbname &gt; db.sql$ Pg_dumpall -h host -U username -p port -f db.sqlحال اگر از تمام اطاعات پوستگرس با Pg_dumpall بکاپ گرفته شده با اجرا bash script زیر می توان بکاپ یک دیتابیس خاص را استخراج کرد:$ cat pgdump.sh#!/bin/bash[ $# -lt 2 ] &amp;&amp; { echo &quot;Usage: $0 &lt;postgresql dump&gt; &lt;dbname&gt;&quot;; exit 1; }sed  &quot;/connect.*$2/,\$!d&quot; $1 | sed &quot;/PostgreSQL database dump complete/,\$d&quot;$ ./pgdump.sh db.sql databasename &gt;&gt; backup.sqlبعد از اتمام دستور بالا می توان بکاپ موجود را در همان دیتابس قبلی با دستور زیر بازیابی نمود:$ psql -U username  -d dbname -f backup.sql -h host -p portو اگر نیاز به بازیابی بکاپ در دیتابیس جدید باشد ابتدا خط اول موجود در backup.sql را پاک کرده و دستور زیر را اجرا نمایید ( C- برای ساخت دیتابیس در صورت عدم وجود می باشد):$ cat backup.sql\connect old-dbname...$ psql -U username -C  -d new_db -f backup.sql -h host -p port</description>
                <category>عرفان جعفری زمان</category>
                <author>عرفان جعفری زمان</author>
                <pubDate>Sun, 14 May 2023 12:08:58 +0330</pubDate>
            </item>
                    <item>
                <title>جمع آوری لاگ های Kubernetes Pods با استفاده از Fluentd - بخش دوم</title>
                <link>https://virgool.io/MobinTadbirSharif/%D8%AC%D9%85%D8%B9-%D8%A2%D9%88%D8%B1%DB%8C-%D9%84%D8%A7%DA%AF-%D9%87%D8%A7%DB%8C-kubernetes-pods-%D8%A8%D8%A7-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%A7%D8%B2-fluentd-%D8%A8%D8%AE%D8%B4-%D8%AF%D9%88%D9%85-nsautjco6l3e</link>
                <description>در بخش قبل کانفیگ forwarder بررسی گردید و در این بخش تنظیمات aggregator مورد بررسی قرار می گیرد.یک نمونه از کانفیگ aggregator به صورت زیر می باشد:      # Ignore fluentd own events
      &lt;match fluent.**&gt;
        @type null
      &lt;/match&gt;
      @include fluentd-inputs.conf
      @include fluentd-output.conf
      {{- if .Values.metrics.enabled }}
      @include metrics.conf
      {{- end }}
    fluentd-inputs.conf: |
      # TCP input to receive logs from
      &lt;source&gt;
        @type forward
        bind 0.0.0.0
        port 24224
      &lt;/source&gt;
      # HTTP input for the liveness and readiness probes
      &lt;source&gt;
        @type http
        bind 0.0.0.0
        port 9880
      &lt;/source&gt;
    fluentd-output.conf: |
      # Throw the healthcheck to the standard output
      &lt;match fluentd.healthcheck&gt;
        @type stdout
      &lt;/match&gt;
      # Send the logs to the standard output
      &lt;match **&gt;
      @type elasticsearch
      include_tag_key true
      host eck-es-http.logs.svc
      port 9200
      user elastic
      password password
      logstash_format false
      index_name fluentd-${tag}
      logstash_prefix fluentd
      target_index_affinity true
      include_timestamp true
      deflector_alias fluentd-${tag}
      rollover_index true
      application_name example
      template_name fluentd-${tag}
      template_file /voho/template
      customize_template {&amp;quot&lt;&lt;TAG&gt;&gt;&amp;quot:&amp;quotfluentd-${tag}&amp;quot}
      template_overwrite true
      &lt;/match&gt;
    metrics.conf: |
      # Prometheus Exporter Plugin
      # input plugin that exports metrics
      &lt;source&gt;
        @type prometheus
        port {{ .Values.metrics.service.port }}
      &lt;/source&gt;
      # input plugin that collects metrics from MonitorAgent
      &lt;source&gt;
        @type prometheus_monitor
        &lt;labels&gt;
          host ${hostname}
        &lt;/labels&gt;
      &lt;/source&gt;
      # input plugin that collects metrics for output plugin
      &lt;source&gt;
        @type prometheus_output_monitor
        &lt;labels&gt;
          host ${hostname}
        &lt;/labels&gt;
      &lt;/sourceحال در زیر به جزئیات کانفیگ فوق می پردازیم:      &lt;source&gt;
        @type forward
        bind 0.0.0.0
        port 24224
      &lt;/source&gt;
      # HTTP input for the liveness and readiness probes
      &lt;source&gt;
        @type http
        bind 0.0.0.0
        port 9880
      &lt;/source&gt;این بخش از تنظیمات منابع ورودی لاگ های را مشخص می کند که اولی از لاگ های forwarder ها که به پورت ۲۴۲۲۴ سرویس fluentd aggregator ارسال می کردند و دومی هم لاگ ها readiness و liveness استفاده می کنند.      &lt;match **&gt;
      @type elasticsearch
      include_tag_key true
      host eck-es-http.logs.svc
      port 9200
      user username
      password password
      logstash_format false
      index_name fluentd-${tag}
      logstash_prefix fluentd
      target_index_affinity true
      include_timestamp true
      deflector_alias fluentd-${tag}
      rollover_index true
      application_name example
      template_name fluentd-${tag}
      template_file /voho/template
      customize_template {&amp;quot&lt;&lt;TAG&gt;&gt;&amp;quot:&amp;quotfluentd-${tag}&amp;quot}
      template_overwrite true
      &lt;/match&gt;افزونه elasticsearch برای برای ارتباط برقرار کردن بین fluentd و elasticsearch می باشد که در مشخص می کند لاگ به چه index و با چه زمانی و ... به سمت elastic ارسال گردد.include_tag_keyمعیین می کند که tag به عنوان یک فیلد در لاگ های ارسالی وجود داشته باشد یا خیر.hostآدرس elasticsearch را مشخص می کند. (اگر الستیک داخل کلاستر می باشد می توان آدرس سرویس را داد و گر نه باید ادرس url الستیک داده شود.)نحوه تعیین آدرس سرویس به صورت servicename&gt;-&lt;namespace&gt;.svc&gt; می باشد.port شماره port الستیک را مشخص می کند.user مقدار username الستیک را می گیرد.passwordمقدار password الستسک را می گیرد.logstash_formatمعین می کند که اسم index در الستیک فرمت logstash (indexname-date) را داشته باشند یا خیر.index_nameاسم index ساخته شده در الستیک را معین می کند.logstash_prefix fluentdمقداری که به اول indexname اضافه می شود (در rollover کردن) را مشخص می کند.4معین می کند که در زمانی که index ها با تگ تاریخ ساخته می شوند اگر index روز های قبل به مقدار حجم حداکثر نرسیده باشد داده ها در همان index ذخیره شوندمزیت این کار این می باشد که تعداد index ها کم می شود م سرعت جستوجو افزایش می یابد.include_timestampمعین می کند که فیلد timestamp در لاگ ها وجود داشته باشند یا خیر.rollover_index با فعال کردن این بخش داده ها با فرمت اسم index به صورت &lt;target_index-application_name-{index_date_pattern}-000001&gt; ذخیره می شوند.deflector_aliasاگر یک index نیازمند rollover باشد باید یک alias برای آن تعریف گردد که این گزینه آن را برای index ها مشخص می کند.application_nameاین قسمت در rollover استفاده می شود.template_nameبرای این که برای هر لاگ با tag مشخص template به صورت خودکار ساخته شود می توان یک فایل template مشخص کرد که برای index آن لاگ ها template را اضافه کند.template_fileمحل فایل template را در pod fluentd مشخص می کند.یک نمونه از فایل template در اخر کانفیگ آورده شده است.customize_templateبرای این که در فایل template تعریف شده مقداری به صورت ثابت یا متغیر تعریف شوند از این بخش استفاده می شود.به عنوان مثال در فایل template مقدار tag به صورت متغییر تعریف شده است که در این بخش مقدار tag از لاگ ها گرفته می شود.template_overwriteمعین می کند اگر در فایل template اگر تغییری داشتیم در template های ساخته شده اعمال شود یا خیر.نمونه از یک فایل template:{
  &amp;quotorder&amp;quot: 100,
  &amp;quotindex_patterns&amp;quot: [
    &amp;quot&lt;&lt;TAG&gt;&gt;-*&amp;quot
  ],
  &amp;quotsettings&amp;quot: {
    &amp;quotindex&amp;quot: {
      &amp;quotlifecycle&amp;quot: {
        &amp;quotname&amp;quot: &amp;quotILM&amp;quot,
        &amp;quotrollover_alias&amp;quot: &amp;quot&lt;&lt;TAG&gt;&gt;&amp;quot
      },
      &amp;quotrefresh_interval&amp;quot: &amp;quot15s&amp;quot,
      &amp;quotnumber_of_shards&amp;quot: &amp;quot1&amp;quot,
      &amp;quotnumber_of_replicas&amp;quot: &amp;quot1&amp;quot
    }
  },
  &amp;quotaliases&amp;quot: {
    &amp;quotall-&lt;&lt;TAG&gt;&gt;&amp;quot: {}
  }
}این فایل باید در image aggregator قرار گیرد که می توان یک dockerfile ایجاد کرده و آن را build کرد:FROM docker.io/bitnami/fluentd:1.14.4-debian-10-r11 

USER root

RUN mkdir /example
 
COPY template /example/template</description>
                <category>عرفان جعفری زمان</category>
                <author>عرفان جعفری زمان</author>
                <pubDate>Sat, 16 Jul 2022 16:52:04 +0430</pubDate>
            </item>
                    <item>
                <title>جمع آوری لاگ های Kubernetes Pods با استفاده از Fluentd - بخش اول</title>
                <link>https://virgool.io/MobinTadbirSharif/%D8%AC%D9%85%D8%B9-%D8%A2%D9%88%D8%B1%DB%8C-%D9%84%D8%A7%DA%AF-%D9%87%D8%A7%DB%8C-kubernetes-pods-%D8%A8%D8%A7-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%A7%D8%B2-fluentd-%D8%A8%D8%AE%D8%B4-%D8%A7%D9%88%D9%84-oj0xtwmiliom</link>
                <description>نرم افزار Fluentd یک ابزار مبتنی بر فضای ابری open-source و کاملا رایگان برای جمع آوری لاگ است که کاربر را قادر می ‌سازد معماری سازگار Log All Everything را با سیستم های خیلی زیادی را داشته باشد. این ابزار به زبان C نوشته شده است و روی تمام سیستم عامل ها از جمله ویندوز و لینوکس اجرا می شود و تحت لیسانس Apache 2.0 است. همچنین می توان از قالب JSON برای ساختار دادن به داده استفاده می کند. از جمله مزایای آن می توان به کم حجم بودن آن و انعطاف پذیر بودن آن در تعداد کاربران استفاده کننده از آن اشاره کرد.در کلاستر کوبرنتیز لاگ های stdout و stderr پادها در نودهای کلاستر در مسیر .../var/log/containers/ جمع آوری می شوند و می توان با کانفیگ کردن fluentd برای جمع آوری و ارسال آن ها, لاگ های پادها را در الستیک داشت. معماری fluentd به گونه می باشد که در هر node یک fluentd به صورت daemon set با اسم forwarder لاگ ها را از پوشه لاگ جمع آوری می کند و به سمت یک fluentd به اسم aggregator می فرستد که این aggregator لاگ ها را به سمت elasticsearch می فرستد.برای نصب و کانفیگ fluentd از helm chart آن استفاده می کنیم که می توان از آدرس github.com/bitnami/charts/tree/master/bitnami/fluentd دانلود کرد.برای ارسال لاگ باید قسمت configMapFiles در forwarder و aggregator کانفیگ شوند که در زیر اورده شده است:  configMapFiles:
    fluentd.conf: |
      # Ignore fluentd own events
      &lt;match fluent.**&gt;
        @type null
      &lt;/match&gt;
      @include fluentd-inputs.conf
      @include fluentd-output.conf
      {{- if .Values.metrics.enabled }}
      @include metrics.conf
      {{- end }}
    fluentd-inputs.conf: |
      # HTTP input for the liveness and readiness probes
      &lt;source&gt;
        @type http
        port 9880
      &lt;/source&gt;
      # Get the logs from the containers running in the node
      &lt;source&gt;
        @type tail
        path /var/log/containers/*.log
        pos_file /opt/bitnami/fluentd/logs/buffers/fluentd-docker.pos
        exclude_path /var/log/containers/*fluentd*.log
        tag kubernetes.*
        time_key @timestamp
        time_format %Y-%m-%dT%T.%L%Z
        read_from_head true
        &lt;parse&gt;
          @type json
        &lt;/parse&gt;
      &lt;/source&gt;
      &lt;filter kubernetes.**&gt;
        @type parser
        key_name &amp;quot$.log&amp;quot
        hash_value_field &amp;quotlog&amp;quot
        reserve_data true
        &lt;parse&gt;
          @type json
        &lt;/parse&gt; 
         emit_invalid_record_to_error
      &lt;/filter&gt;
      # enrich with kubernetes metadata
      &lt;filter kubernetes.**&gt;
        @type kubernetes_metadata
      &lt;/filter&gt;
      &lt;match kubernetes.**&gt;
        @type rewrite_tag_filter
        &lt;rule&gt;
          key $.kubernetes.labels.app_kubernetes_io/name
          pattern ^(.+)$
          tag $1
        &lt;/rule&gt;
      &lt;/match&gt;
    fluentd-output.conf: |
      # Throw the healthcheck to the standard output instead of forwarding it
      &lt;match fluentd.healthcheck&gt;
        @type stdout
      &lt;/match&gt;
      # Forward all logs to the aggregators
      &lt;match **&gt;
        @type forward
        &lt;server&gt;
          host fluentd-0.fluentd-headless.logs.svc.cluster.local
          port 24224
        &lt;/server&gt;
        &lt;buffer tag,time&gt;
          @type file
          timekey 30s
          flush_mode interval
          total_limit_size 20GB
          path /opt/bitnami/fluentd/logs/buffers/logs.buffer_${tag}_${chunk_id}
          retry_forever true
          retry_type exponential_backoff
          retry_exponential_backoff_base 2
          retry_max_interval 1h
          flush_thread_count 2
          flush_interval 5s
        &lt;/buffer&gt;
      &lt;/match&gt;
    metrics.conf: |
      # Prometheus Exporter Plugin
      # input plugin that exports metrics
      &lt;source&gt;
        @type prometheus
        port {{ .Values.metrics.service.port }}
      &lt;/source&gt;
      # input plugin that collects metrics from MonitorAgent
      &lt;source&gt;
        @type prometheus_monitor
        &lt;labels&gt;
          host ${hostname}
        &lt;/labels&gt;
      &lt;/source&gt;
      # input plugin that collects metrics for output plugin
      &lt;source&gt;
        @type prometheus_output_monitor
        &lt;labels&gt;
          host ${hostname}
        &lt;/labels&gt;
      &lt;/source&gt;
      # input plugin that collects metrics for in_tail plugin
      &lt;source&gt;
        @type prometheus_tail_monitor
        &lt;labels&gt;
          host ${hostname}
        &lt;/labels&gt;
      &lt;/source&gt;
      &lt;filter **&gt;
        @type prometheus
        &lt;metric&gt;
          name fluentd_input_status_num_records_total
          type counter
          desc The total number of incoming records
          &lt;labels&gt;
            tag ${tag}
            hostname ${hostname}
          &lt;/labels&gt;
        &lt;/metric&gt;
      &lt;/filter&gt;حال در زیر به تعیین جز به جز کانفیگ فوق می پردازیم:       &lt;source&gt;
        @type tail
        path /var/log/containers/*.log
        pos_file /opt/bitnami/fluentd/logs/buffers/fluentd-docker.pos
        exclude_path /var/log/containers/*fluentd*.log
        tag kubernetes.*
        time_key @timestamp
        time_format %Y-%m-%dT%T.%L%Z
        read_from_head true
        &lt;parse&gt;
          @type json
        &lt;/parse&gt;
      &lt;/source&gt;@type tailمشخص می کند نوع منبع لاگ به چه صورتی باشد که tail یعنی به از یک فایل لاگ ها را بخواند.pathمسیر فایل لاگ را به fluentd می دهد.pos_fileمسیری را مشخص می کند که در آن تعیین می شود لاگ فایل تا چه سطری فرستاده شده است و از کجا باید ارسال لاگ ادامه پیدا کند.exclude_pathمسیر فایل هایی که نباید ارسال شوند را معین می کند.tagبه لاگ های ارسالی یک tag اضافه می کند که از آن برای تفکیک لاگ ها در ارسال به جاهای مختلف استفاده می شود (به صورت پیش فرض اسم فایل به عنوان tag انتخاب می شود و در این کانفیگ .kubernetes به اول tag اضافه می شود)time_keyاسم فیلد زمان را در لاگ ها را مشخص می کند.time_formatفرمت مقدار فیلد زمان را مشخص می کند.read_from_headدر زمان tail کردن فقط لاگ های جدیدی که اضافه شده اند ارسال می شوند ولی در با true کردن این مقدار شروع به tail کردن از اول فایل می کند.@type jsonاین قسمت که در pars قرار داد نوع لاگ های موجود در فایل لاگ را تعیین می کند.      &lt;filter kubernetes.**&gt;
        @type parser
        key_name &amp;quot$.log&amp;quot
        hash_value_field &amp;quotlog&amp;quot
        reserve_data true
        &lt;parse&gt;
          @type json
        &lt;/parse&gt; 
         emit_invalid_record_to_error
      &lt;/filter&gt;تنظیمات فوق برای تعیین نوع لاگ یک فیلد خاص می باشد. در parser پیشین ما فرمت کلی لاگ ارسال شده را مشخص کردیم ولی در اینجا فرمت یک فیلد خاص را مشخص می کنیم فیلد log فیلدی می باشد که اطلاع نوشته شده در فایل لاگ را در بردارد که در بالا مشخص شده است که این فیلد به صورت json هستند و لاگ های غیر josn دور ریخته می شوند.(پارامتر emit_invalid_record_to_error این لاگ ها به صورت error در ارسال می کند)      &lt;match kubernetes.**&gt;
        @type rewrite_tag_filter
        &lt;rule&gt;
          key $.kubernetes.labels.app_kubernetes_io/name
          pattern ^(.+)$
          tag $1
        &lt;/rule&gt;
      &lt;/match&gt;حال در این قسمت با استفاده از افزونه rewrite_tag_filter تگ لاگ ها را عوض کرده و بر اساس اسم برنامه قرار می دهیم ( می توان به جای kubernetes.labels.app_kubernetes_io/name.$ که یک فیلد از لاگ های ارسالی هست از متغییر های دیگری نیز استفاده کرد)&lt;match **&gt;
        @type forward
        &lt;server&gt;
          host fluentd-0.fluentd-headless.logs.svc.cluster.local
          port 24224
        &lt;/server&gt;
        &lt;buffer tag,time&gt;
          @type file
          timekey 30s
          flush_mode interval
          total_limit_size 20GB
          path /opt/bitnami/fluentd/logs/buffers/logs.buffer_${tag}_${chunk_id}
          retry_forever true
          retry_type exponential_backoff
          retry_exponential_backoff_base 2
          retry_max_interval 1h
          flush_thread_count 2
          flush_interval 5s
        &lt;/buffer&gt;
      &lt;/match&gt;در تنظیمات این قسمت لاگ ها از forwarder به سمت aggregator ارسال می کنیم.hostآدرس سرویس aggregator می باشد.portشماره port سرویس aggregator می باشد. &lt;buffer tag,time&gt;قسمت buffer برای جلوگیری از حذف شدن لاگ ها و هم افزایش performance با کاهش دفعات اتصال به aggregator می باشد. برای بافر کردن fluentd شروع به جمع کردن لاگ ها درون chunk file می کند که در این تنظیمات مشخص شده فایل ها بر اساس زمان و tag لاگ ها ایجاد شوند.typeنوع chunk ها مشخص می کند.timekeyاین قسمت تعیین می کند که فایل های جدید chunk با چه interval ایجاد شوندflush_modeفلاش یعنی زمانی که این chunk ها به سمت aggregator فرستاده می شوند و در این کانفیگ بر اساس interval عملیات فلاش صورت می گیرد.total_limit_size حداکثر حجم بافر را تعیین می کند.pathمحل ذخیره سازی chunk ها می باشد.retry_foreverبرای ارسال chunk مشخص می کند که بعد از به خطا خوردن تا ابد تلاش کند یا خیر.retry_typeنوع افزایش زمان انتظار بعد از هر تلاش ناموفق را مشخص می کند که در این قسمت به صورت نمایی انتخاب شده است.retry_exponential_backoff_baseعدد پایه نمودار نمایی برای افزایش زمان انتظار می باشد در این تنظیمات ۲ قرار داده شده است.retry_max_intervalحداکثر زمان انتظار را معیین می کند که در اینجا بیشتر از ۱ ساعت نمی شود.flush_thread_countتعداد فلاش های موازی را معین می کند.flush_intervalمدت زمان بین هر فلاش را تعیین می کند.      &lt;source&gt;
        @type prometheus
        port {{ .Values.metrics.service.port }}
      &lt;/source&gt;
      # input plugin that collects metrics from MonitorAgent
      &lt;source&gt;
        @type prometheus_monitor
        &lt;labels&gt;
          host ${hostname}
        &lt;/labels&gt;
      &lt;/source&gt;
      # input plugin that collects metrics for output plugin
      &lt;source&gt;
        @type prometheus_output_monitor
        &lt;labels&gt;
          host ${hostname}
        &lt;/labels&gt;
      &lt;/source&gt;
      # input plugin that collects metrics for in_tail plugin
      &lt;source&gt;
        @type prometheus_tail_monitor
        &lt;labels&gt;
          host ${hostname}
        &lt;/labels&gt;
      &lt;/source&gt;
      &lt;filter **&gt;
        @type prometheus
        &lt;metric&gt;
          name fluentd_input_status_num_records_total
          type counter
          desc The total number of incoming records
          &lt;labels&gt;
            tag ${tag}
            hostname ${hostname}
          &lt;/labels&gt;
        &lt;/metric&gt;
      &lt;/filter&gt;در تنظیمات این بخش متریک های مورد نیاز برای مانیتورینگ مقدار ورودی خروجی و بافر و ... fluentd استفاده می شودlabelsاین مقدار برای تعیین برچسب های متریک ها برای جدا سازی آن ها می باشد. (به عنوان مثال با تعیین tag به عنوان برچسب می توان فهمید هر برنامه چه تعداد لاگ ورودی دارد)در بخش دوم کانفیگ aggregator مورد بررسی قرار می گیرد.</description>
                <category>عرفان جعفری زمان</category>
                <author>عرفان جعفری زمان</author>
                <pubDate>Sat, 16 Jul 2022 15:34:20 +0430</pubDate>
            </item>
                    <item>
                <title>راه اندازی Prometheus Aalert Manager</title>
                <link>https://virgool.io/MobinTadbirSharif/%D8%B1%D8%A7%D9%87-%D8%A7%D9%86%D8%AF%D8%A7%D8%B2%DB%8C-prometheus-aalert-manager-veyhpmboxahb</link>
                <description>برای مدیریت اخطار ها در Prometheus از AlertManager استفاده می شود به طوری که اخطار ها را از سمت پرومتئوس می گیرد و کاربر نهایی را از طریق E-mail ، اسلک یا دیگر ابزارها مطلع می سازد. اخطار دهی منجر به این می شود همین که خطایی رخ داد، کاربر از آن مطلع شود.برای راه اندازی alertmanager به prometheus rule و کانفیگ خود alertmanager نیاز داریم. ابتدا با prometheus rule شرایط ایجاد خطا را مشخص می کنیم که نمونه کانفیگ آن در زیر آورده شده است:apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: mpaas
  labels:
    role: alert-rules
spec:
  groups:
    - name: mpaas
      rules:
      - alert: example
        annotations:
          annotation1: example1
          annotation2: example2
        expr: sum(container_cpu_usage_seconds_total{namespace=&amp;quotcdn-prod&amp;quot})&gt;0
        for: 5m
        labels:
          label1: example1
          label2: example2در تنظیمات بالا قسمت های مهم به صورت زیر پیکربندی می شوند:annotationsبرای این که هنگام ارسال هشدار توضیحاتی برای مشخص شدن مشکل وجود داشته باشد از این قسمت استفاده می شود و بهتر است محل وقوع خطا و شدت خطا و ... آورده شود.exprکویری پرومتئوسی که برای تشخیص خطا به کار می رود.forمدت زمانی که خطا وجود داشته باشد تا هشدار به وجود بیاید.labelsبرای جدا کردن الرت ها از همدیگر زمان ارسال هشدار استفاده می شود برای مثال هشدار با label1: example1 به کاربر ۱ ارسال گردد.بعد از تمام شدن کانفیگ prometheus rule با استفاده از kubectl apply -n namespace prometheus-rule.yamlریسورس آن ایجاد می شود.حالا باید برای ارسال هشدار به کاربر alertmanager را پیکریندی کنیم:config:
  global:
    resolve_timeout: 1m
  route:
    receiver: &#039;default-team&#039;
    group_wait: 30s
    group_interval: 30s
    repeat_interval: 1d
    group_by: [alertname]
    routes:
    - receiver: &#039;team1&#039;
      group_wait: 10s
      group_interval: 5m
      repeat_interval: 4h
      group_by: [alertname]
      matchers:
      - label1=~&amp;quotexample1|example2&amp;quot
      active_time_intervals:
        - offhours
        - holidays
      mute_time_intervals:
        - offhours
        - holidays
      continue: true

  receivers:
  - name: &#039;team1&#039;
    webhook_configs:
    - url: http://example.com
      send_resolved: true

  - name: &#039;email&#039;
    email_configs:
    - to: &#039;to@gmail.com&#039;
      from: &#039;from@gmail.com&#039;
      smarthost: smtp.gmail.com:587
      auth_username: &#039;from@gmail.com&#039;
      auth_identity: &#039;from@gmail.com&#039;
      auth_password: &#039;pass&#039;
در کانفیگ بالا route مشخص می کند که هشدار ها با label های مختلف به کدام کاربر ارسال شوند هر کانفیگی که زیر مجموعه route و بالای routes باشد به عنوان تنظیمات پیش فرض انتخاب می شود و در قسمت routes می توان آن ها را overwrite کرد.group_waitمدت زمانی که الرت منیجر بعد از ایجاد هشدار صبر می کند و سپس هشدار را وارد گروه مشخص شده می کند.group_intervalاگر هشدار قبلا در گروه وجود داشته مدت زمانی که الرت منیجر بعد از ایجاد هشدار صبر می کند و سپس هشدار را وارد گروه مشخض شده می کند.repeat_intervalاگر هشدار برطرف نشده باشد بعد از این مدت زمان دوباره پیام را ارسال می شود.matchersدر زمان تعریف prometheus rule لیبل هایی برای alert ها می شخص می شوند با استفاده از این لیبل ها می توان تعیین کرد به receiver مورد نظر کدام هشدار ارسال شود.active_time_intervalsزمان هایی که ارسال هشدار فعال است را مشخص می کند.mute_time_intervalsزمان هایی که ارسال هشدار غیر فعال است را مشخص می کند.continueتعیین می کند اگر هشدار با receiver اول مطابق شده و هشدار ارسال شد ایا receiver بعدی نیز چک شود.حال باید receivers تنظیم شوند برای این ها انواع مختلفی وجود دارد که در اینجا دو حالت email و webhook مورد بررسی قرار گرفته است. به عنوان مثال برای کانفیگ Gmail باید اکانت مورد نظر به صورت لاگین دو مرحله ای باشد و از قسمت security &gt; signing whit google مقدار password را کپی کرده و در auth_password قرار دهید. برای راه اندازی سرویس ارسال پیامک با استفاده از webhook باید یک fast api راه اندازی شده و درخواست را از alertmanager گرفته و به سمت سرویس ارسال پیامک ارسال کند و در درخواستی که به سمت fast api ارسال می گردد شماره تلفن به صورت query parameter به صورت زیر داده شود:url: http://example.com/?phone=09*********همچین فایل python مورد نیاز برای ارسال درخواست به صورت زیر نوشته می شود:from ctypes import Union
from lib2to3.pgen2 import grammar
from lib2to3.pgen2.token import NEWLINE
from typing import Optional, Type
from fastapi import FastAPI, Query
from pydantic import BaseModel
import requests
from urllib.parse import unquote
import urllib.parse
import json

class Book(BaseModel):
    version: str
    #...

app = FastAPI()
@app.post(&amp;quot/&amp;quot)
def req(phone: str,annotations: Annotations):
    return_list=[]
    return_list.append(f&amp;quotalertname : {annotations.alerts[0].get(&#039;labels&#039;).get(&#039;alertname&#039;)}&amp;quot)
    #...
    temp = &amp;quot&amp;quot
    nl= &#039;\n&#039;
    temp = f&amp;quot{nl.join(return_list)}&amp;quot
    uri = urllib.parse.quote(temp)
    url = &amp;quothttps://example?username=user&amp;password=pass&amp;from=from&amp;to=&amp;quot + phone + &amp;quot&amp;text=&amp;quot + uri
    payload={}
    headers = {
      &#039;example&#039;: &#039;example&#039;
    }
    response = requests.request(&amp;quotGET&amp;quot, url, headers=headers, data=payload)در کد بالا درخواست از سمت alertmanager ارسال می گردد و مقادیر مورد نیاز response body از آن با استفاده از Base model استخراج می شود به عنوان نمونه:version: str
...نمونه response body:{
  &amp;quotversion&amp;quot: &amp;quot4&amp;quot,
  &amp;quotgroupKey&amp;quot: &lt;string&gt;,              // key identifying the group of alerts (e.g. to deduplicate)
  &amp;quottruncatedAlerts&amp;quot: &lt;int&gt;,          // how many alerts have been truncated due to &amp;quotmax_alerts&amp;quot
  &amp;quotstatus&amp;quot: &amp;quot&lt;resolved|firing&gt;&amp;quot,
  &amp;quotreceiver&amp;quot: &lt;string&gt;,
  &amp;quotgroupLabels&amp;quot: &lt;object&gt;,
  &amp;quotcommonLabels&amp;quot: &lt;object&gt;,
  &amp;quotcommonAnnotations&amp;quot: &lt;object&gt;,
  &amp;quotexternalURL&amp;quot: &lt;string&gt;,           // backlink to the Alertmanager.
  &amp;quotalerts&amp;quot: [
    {
      &amp;quotstatus&amp;quot: &amp;quot&lt;resolved|firing&gt;&amp;quot,
      &amp;quotlabels&amp;quot: &lt;object&gt;,
      &amp;quotannotations&amp;quot: &lt;object&gt;,
      &amp;quotstartsAt&amp;quot: &amp;quot&lt;rfc3339&gt;&amp;quot,
      &amp;quotendsAt&amp;quot: &amp;quot&lt;rfc3339&gt;&amp;quot,
      &amp;quotgeneratorURL&amp;quot: &lt;string&gt;,      // identifies the entity that caused the alert
      &amp;quotfingerprint&amp;quot: &lt;string&gt;        // fingerprint to identify the alert
    },
    ...
  ]
}باید در هنگام راه اندازی fast apj مقدار response body الرت منیجر مشاهده شده و بر اساس آن Base mode تعریف شود.در قسمت return_list مقادیر مورد استخراج شده و به لیست خروجی که به صورت query parameter هست اضافه می شوندو در اخر براساس سرویس پیامک موجود url ساخته شده و مقادیر user و pass و ... در آن قرار می گیرد و با استفاده از‌ آن  یک درخواست get به سمت سرویس پیامکی ارسال می شود</description>
                <category>عرفان جعفری زمان</category>
                <author>عرفان جعفری زمان</author>
                <pubDate>Thu, 07 Jul 2022 16:15:27 +0430</pubDate>
            </item>
                    <item>
                <title>راه اندازی elasticsearch در kubernetes</title>
                <link>https://virgool.io/MobinTadbirSharif/%D8%B1%D8%A7%D9%87-%D8%A7%D9%86%D8%AF%D8%A7%D8%B2%DB%8C-elasticsearch-%D8%AF%D8%B1-kubernetes-dm9nylbcv5v9</link>
                <description>الاستیک سرچ (Elasticsearch)، یک موتور جستجوی اوپن سورس است که توسط شرکت آپاچی و بر اساس Apache Lucene ساخته شده است. مبنای الاستیک سرچ، معماری Rest است.برای راه اندازی الستیک سرچ در kubernetes از راه های مختلفی میشه استفاده کرد از جمله eck operator, helm و ... که در این مقاله از روش eck operator استفاده شده.حالا eck operator چیه manager الستیک سرچ هست که برای راه اندازی الستیک مورد استفاده قرار می گیره یعنی ما فقط eck را رو تو یک namespace بالا می یاریم و کانفیگ الستیک رو براش ارسال می کنیم و شروع به راه اندازی الستیک می کنه.برای راه اندازی eck مراحل زیر رو طی می کنیم:با استفاده از دستور زیر برای کوبرنتیز custom resource های مرتبط با الستیک ایجاد می شود:kubectl create -f https://download.elastic.co/downloads/eck/2.2.0/crds.yamlبعد نوبت نصب operator فرا می رسد:kubectl apply -f https://download.elastic.co/downloads/eck/2.2.0/operator.yamlکه namespace پیش فرض آن elastic-system می باشدحالا فقط کافیه به صورت زیر کانفیگ الستیک رو با استفاده از kubectl به سمت کوبرنتیز ارسال کنیمcat &lt;&lt;EOF | kubectl apply -n logs -f -
apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
  name: eck
spec:
  version: 7.16.2
  nodeSets:
    - name: master
      count: 1
      volumeClaimTemplates:
      - metadata:
          name: elasticsearch-data 
        spec:
          accessModes:
          - ReadWriteOnce
          resources:
            requests:
              storage: 5Gi
          storageClassName: hostpath
      podTemplate:
        spec:
          nodeSelector:
            type: tools
          containers:
            - name: elasticsearch
              readinessProbe:
                exec:
                  command:
                  - bash
                  - -c
                  - /mnt/elastic-internal/scripts/readiness-probe-script.sh
                failureThreshold: 3
                initialDelaySeconds: 60
                periodSeconds: 12
                successThreshold: 1
                timeoutSeconds: 60
              env:
              - name: READINESS_PROBE_PROTOCOL
                value: &amp;quothttp&amp;quot
      config:
        node.roles: [&amp;quotmaster&amp;quot]
        xpack.security.enabled: true
        node.store.allow_mmap: false
        xpack.security.http.ssl.enabled: false

    - name: data
      count: 1
      volumeClaimTemplates:
      - metadata:
          name: elasticsearch-data 
        spec:
          accessModes:
          - ReadWriteOnce
          resources:
            requests:
              storage: 100Gi
          storageClassName: openebs-hostpath
      podTemplate:
        spec:
          nodeSelector:
            type: tools
          containers:
            - name: elasticsearch
              readinessProbe:
                exec:
                  command:
                  - bash
                  - -c
                  - /mnt/elastic-internal/scripts/readiness-probe-script.sh
                failureThreshold: 3
                initialDelaySeconds: 60
                periodSeconds: 12
                successThreshold: 1
                timeoutSeconds: 60
              env:
              - name: READINESS_PROBE_PROTOCOL
                value: &amp;quothttp&amp;quot
      config:
        node.roles: [&amp;quotdata&amp;quot]
        xpack.security.enabled: true
        node.store.allow_mmap: false
        xpack.security.http.ssl.enabled: false

EOFدر کانفیک بالا تو قسمت nodeset تعداد و نوع pod ها مشخص شده هستند که الان فقط pod های master و data هر کدام یکی ساخته می شونداز بخش های مهم تنظیمات بالا به موارد زیر باید توجه بشه:-n logs برای مشخص کردن namespace ای هست که الستیک در آن بالا آورده می شود به باید از قبل در کوبرنتیز ساخته شودstorageClassNameاگر از storageclass استفاده نمی شود باید اسم pv و pvc به جای آن داده شودnodeSelectorاین قسمت برای بالا آوردن pod در node خاصی با استفاده از label موجود در node هست که اگر نیازی نیست حذف شودxpack.security.enabledبا فعال کردن این گزینه بخش xpack راه اندازی می شود که باعث اضافه کردن user و pass به لاگین الستیک می شود که user و pass در یک secret ذخیره شده می باشدعلاوه بر pod های بالا می توان انواع مختلفی مثل ingest, ml, transform و ... به کلاستر الستیک اضافه کرد.</description>
                <category>عرفان جعفری زمان</category>
                <author>عرفان جعفری زمان</author>
                <pubDate>Thu, 07 Jul 2022 11:23:57 +0430</pubDate>
            </item>
            </channel>
</rss>