ایک ورژنڈ دستاویزی سائٹ کی مثال کا استعمال کرتے ہوئے werf کے ساتھ ڈوکر امیجز کی متحرک اسمبلی اور تعیناتی

ہم پہلے ہی اپنے GitOps ٹول کے بارے میں ایک سے زیادہ بار بات کر چکے ہیں۔ werf، اور اس بار ہم سائٹ کو اسمبل کرنے کے اپنے تجربے کو پروجیکٹ کی دستاویزات کے ساتھ شیئر کرنا چاہیں گے۔ werf.io (اس کا روسی ورژن ہے۔ en.werf.io)۔ یہ ایک عام جامد سائٹ ہے، لیکن اس کی اسمبلی اس لحاظ سے دلچسپ ہے کہ اسے نمونے کی ایک متحرک تعداد کا استعمال کرتے ہوئے بنایا گیا ہے۔

ایک ورژنڈ دستاویزی سائٹ کی مثال کا استعمال کرتے ہوئے werf کے ساتھ ڈوکر امیجز کی متحرک اسمبلی اور تعیناتی

سائٹ کے ڈھانچے کی باریکیوں میں جائیں: تمام ورژنز کے لیے ایک مشترکہ مینو بنانا، ریلیز کے بارے میں معلومات والے صفحات وغیرہ۔ - ہم نہیں کریں گے۔ اس کے بجائے، آئیے متحرک اسمبلی کے مسائل اور خصوصیات پر توجہ مرکوز کریں اور اس کے ساتھ موجود CI/CD عمل پر تھوڑا سا توجہ مرکوز کریں۔

تعارف: سائٹ کیسے کام کرتی ہے۔

شروع کرنے کے لیے، werf دستاویزات کو اس کے کوڈ کے ساتھ محفوظ کیا جاتا ہے۔ یہ کچھ ترقیاتی تقاضے عائد کرتا ہے جو عام طور پر اس مضمون کے دائرہ کار سے باہر ہیں، لیکن کم از کم یہ کہا جا سکتا ہے کہ:

  • نئے werf فنکشنز کو دستاویزات کو اپ ڈیٹ کیے بغیر جاری نہیں کیا جانا چاہیے اور، اس کے برعکس، دستاویزات میں کسی قسم کی تبدیلی کا مطلب werf کے نئے ورژن کا اجراء ہے۔
  • اس منصوبے میں کافی گہری ترقی ہے: نئے ورژن دن میں کئی بار جاری کیے جا سکتے ہیں۔
  • دستاویزات کے نئے ورژن کے ساتھ سائٹ کو تعینات کرنے کے لیے کوئی بھی دستی کارروائی کم از کم تکلیف دہ ہوتی ہے۔
  • پراجیکٹ ایک معنوی نقطہ نظر اپناتا ہے۔ ورژن بنانا، 5 استحکام چینلز کے ساتھ۔ ریلیز کے عمل میں چینلز کے ذریعے ورژنز کی ترتیب وار گزرنا شامل ہے تاکہ استحکام میں اضافہ ہو: الفا سے لے کر راک سالڈ تک؛
  • سائٹ کا روسی زبان کا ورژن ہے، جو مرکزی (یعنی انگریزی زبان) ورژن کے متوازی طور پر "زندگی اور ترقی کرتا ہے" (یعنی جس کا مواد اپ ڈیٹ ہوتا ہے) ہے۔

اس تمام "اندرونی باورچی خانے" کو صارف سے چھپانے کے لیے، اسے کچھ ایسی پیشکش کی جو "صرف کام کرتی ہے"، ہم نے ایسا کیا۔ الگ الگ werf انسٹالیشن اور اپ ڈیٹ ٹول ہے - multiwerf. آپ کو صرف ریلیز نمبر اور اسٹیبلٹی چینل کی وضاحت کرنے کی ضرورت ہے جسے آپ استعمال کرنے کے لیے تیار ہیں، اور multiwerf چیک کرے گا کہ آیا چینل پر کوئی نیا ورژن موجود ہے اور اگر ضروری ہو تو اسے ڈاؤن لوڈ کریں۔

ویب سائٹ پر ورژن سلیکشن مینو میں، werf کے تازہ ترین ورژن ہر چینل میں دستیاب ہیں۔ پہلے سے طے شدہ طور پر، ایڈریس کے ذریعہ werf.io/documentation تازہ ترین ریلیز کے لیے سب سے مستحکم چینل کا ورژن کھلتا ہے - اسے سرچ انجنوں کے ذریعے بھی ترتیب دیا جاتا ہے۔ چینل کے لیے دستاویزات علیحدہ پتوں پر دستیاب ہیں (مثال کے طور پر، werf.io/v1.0-beta/documentation بیٹا ریلیز 1.0 کے لیے)۔

مجموعی طور پر، سائٹ کے درج ذیل ورژن دستیاب ہیں:

  1. جڑ (بطور ڈیفالٹ کھلتا ہے)
  2. ہر ریلیز کے ہر ایک فعال اپ ڈیٹ چینل کے لیے (مثال کے طور پر، werf.io/v1.0-beta).

کسی سائٹ کا مخصوص ورژن تیار کرنے کے لیے، عام طور پر، اسے استعمال کرکے مرتب کرنا کافی ہے۔ Jekyll کیڈائرکٹری میں چلانے سے /docs werf repository متعلقہ کمانڈ (jekyll build)، مطلوبہ ورژن کے Git ٹیگ پر سوئچ کرنے کے بعد۔

یہ صرف شامل کرنا باقی ہے:

  • افادیت خود (werf) اسمبلی کے لئے استعمال کیا جاتا ہے؛
  • CI/CD عمل GitLab CI کی بنیاد پر بنائے گئے ہیں۔
  • اور یہ سب کچھ، یقیناً، Kubernetes میں چلتا ہے۔

ٹاسکس

اب آئیے ایسے کاموں کو مرتب کرتے ہیں جو تمام بیان کردہ تفصیلات کو مدنظر رکھتے ہیں:

  1. کسی بھی اپ ڈیٹ چینل پر ورف ورژن کو تبدیل کرنے کے بعد سائٹ پر دستاویزات کو خود بخود اپ ڈیٹ کیا جانا چاہئے۔.
  2. ترقی کے لیے آپ کو کبھی کبھی قابل ہونے کی ضرورت ہوتی ہے۔ سائٹ کے پیش نظارہ ورژن دیکھیں.

متعلقہ گٹ ٹیگز سے کسی بھی چینل پر ورژن کو تبدیل کرنے کے بعد سائٹ کو دوبارہ مرتب کرنا ہوگا، لیکن تصویر بنانے کے عمل میں ہمیں درج ذیل خصوصیات حاصل ہوں گی۔

  • چونکہ چینلز پر ورژن کی فہرست تبدیل ہوتی ہے، اس لیے صرف ان چینلز کے لیے دستاویزات کو دوبارہ بنانا ضروری ہے جہاں ورژن تبدیل ہوا ہے۔ سب کے بعد، ہر چیز کو دوبارہ تعمیر کرنا بہت اچھا نہیں ہے.
  • ریلیز کے لیے چینلز کا سیٹ تبدیل ہو سکتا ہے۔ کسی وقت، مثال کے طور پر، چینلز پر ابتدائی رسائی 1.1 ریلیز سے زیادہ مستحکم نہیں ہو سکتا، لیکن وقت گزرنے کے ساتھ وہ ظاہر ہوں گے - اس صورت میں، کیا آپ کو اسمبلی کو دستی طور پر تبدیل نہیں کرنا چاہیے؟

یہ پتہ چلا ہے کہ اسمبلی بیرونی ڈیٹا کو تبدیل کرنے پر منحصر ہے۔.

Реализация

ایک نقطہ نظر کا انتخاب

متبادل طور پر، آپ Kubernetes میں ہر مطلوبہ ورژن کو الگ پوڈ کے طور پر چلا سکتے ہیں۔ یہ آپشن کلسٹر میں اشیاء کی ایک بڑی تعداد کو ظاہر کرتا ہے، جو مستحکم ورف ریلیز کی تعداد میں اضافے کے ساتھ بڑھے گی۔ اور یہ، بدلے میں، زیادہ پیچیدہ دیکھ بھال کا مطلب ہے: ہر ورژن کا اپنا HTTP سرور ہے، اور ایک چھوٹا بوجھ کے ساتھ۔ یقیناً، اس میں وسائل کے زیادہ اخراجات بھی شامل ہیں۔

ہم نے وہی راستہ اختیار کیا۔ تمام ضروری ورژنز کو ایک تصویر میں جمع کرنا. سائٹ کے تمام ورژنز کے مرتب کردہ اعدادوشمار NGINX والے کنٹینر میں موجود ہیں، اور متعلقہ تعیناتی کے لیے ٹریفک NGINX Ingress کے ذریعے آتا ہے۔ ایک سادہ ڈھانچہ - ایک اسٹیٹ لیس ایپلی کیشن - آپ کو بذات خود Kubernetes کا استعمال کرتے ہوئے آسانی سے تعیناتی (لوڈ پر منحصر) کی پیمائش کرنے کی اجازت دیتی ہے۔

زیادہ درست ہونے کے لیے، ہم دو تصاویر جمع کر رہے ہیں: ایک پروڈکشن سرکٹ کے لیے، دوسری دیو سرکٹ کے لیے اضافی ہے۔ اضافی تصویر صرف دیو سرکٹ پر مرکزی تصویر کے ساتھ استعمال کی جاتی ہے (لانچ کی جاتی ہے) اور اس میں جائزے کے عہد سے سائٹ کا ورژن ہوتا ہے، اور ان کے درمیان روٹنگ Ingress وسائل کا استعمال کرتے ہوئے کی جاتی ہے۔

werf بمقابلہ گٹ کلون اور نمونے

جیسا کہ پہلے ہی ذکر کیا جا چکا ہے، دستاویزات کے مخصوص ورژن کے لیے سائٹ کے اعدادوشمار تیار کرنے کے لیے، آپ کو مناسب ریپوزٹری ٹیگ پر سوئچ کر کے بنانے کی ضرورت ہے۔ آپ ہر بار جب بھی بناتے ہیں ذخیرہ کو کلون کرکے، فہرست سے مناسب ٹیگز منتخب کرکے بھی ایسا کرسکتے ہیں۔ تاہم، یہ ایک بہت زیادہ وسائل پر مبنی آپریشن ہے اور اس کے علاوہ، غیر معمولی ہدایات لکھنے کی ضرورت ہے... ایک اور سنگین نقصان یہ ہے کہ اس نقطہ نظر سے اسمبلی کے دوران کسی چیز کو کیش کرنے کا کوئی طریقہ نہیں ہے۔

یہاں werf افادیت خود ہماری مدد کے لئے آتا ہے، لاگو کرنا سمارٹ کیشنگ اور آپ کو استعمال کرنے کی اجازت دیتا ہے۔ بیرونی ذخیرے. ریپوزٹری سے کوڈ شامل کرنے کے لئے werf کا استعمال کرنے سے تعمیر میں نمایاں طور پر تیزی آئے گی، کیونکہ werf بنیادی طور پر ایک بار ذخیرہ کو کلون کرتا ہے اور پھر اس پر عمل درآمد کرتا ہے۔ صرف fetch اگر ضروری ہوا۔ اس کے علاوہ، ریپوزٹری سے ڈیٹا شامل کرتے وقت، ہم صرف ضروری ڈائریکٹریز کا انتخاب کر سکتے ہیں (ہمارے معاملے میں یہ ڈائریکٹری ہے docs)، جو شامل کردہ ڈیٹا کی مقدار کو نمایاں طور پر کم کر دے گا۔

چونکہ جیکیل ایک ایسا ٹول ہے جسے جامد ڈیٹا کو مرتب کرنے کے لیے ڈیزائن کیا گیا ہے اور حتمی تصویر میں اس کی ضرورت نہیں ہے، اس لیے اس میں مرتب کرنا منطقی ہوگا۔ werf artifact، اور حتمی تصویر میں صرف تالیف کا نتیجہ درآمد کریں۔.

ہم werf.yaml لکھتے ہیں۔

لہٰذا، ہم نے فیصلہ کیا کہ ہم ہر ورژن کو ایک الگ ورف آرٹفیکٹ میں مرتب کریں گے۔ تاہم ہم ہم نہیں جانتے کہ اسمبلی کے دوران ان میں سے کتنے نمونے ہوں گے۔، لہذا ہم ایک فکسڈ بلڈ کنفیگریشن نہیں لکھ سکتے ہیں (سختی سے بولیں تو ہم اب بھی کر سکتے ہیں، لیکن یہ مکمل طور پر موثر نہیں ہوگا)۔

werf آپ کو استعمال کرنے کی اجازت دیتا ہے۔ ٹیمپلیٹس پر جائیں۔ آپ کی کنفیگریشن فائل میں (werf.yaml)، اور یہ اسے ممکن بناتا ہے۔ فلائی پر تشکیل بنائیں بیرونی ڈیٹا پر منحصر ہے (جس کی آپ کو ضرورت ہے!) ہمارے معاملے میں بیرونی ڈیٹا ورژن اور ریلیز کے بارے میں معلومات ہے، جس کی بنیاد پر ہم نمونے کی مطلوبہ تعداد جمع کرتے ہیں اور اس کے نتیجے میں ہمیں دو تصاویر ملتی ہیں: werf-doc и werf-dev مختلف سرکٹس پر چلانے کے لیے۔

بیرونی ڈیٹا ماحولیاتی متغیرات سے گزرتا ہے۔ ان کی ترکیب یہ ہے:

  • RELEASES - ریلیز کی فہرست اور werf کے متعلقہ موجودہ ورژن کے ساتھ ایک لائن، فارمیٹ میں اقدار کی جگہ سے الگ کردہ فہرست کی شکل میں <НОМЕР_РЕЛИЗА>%<НОМЕР_ВЕРСИИ>. ایک مثال: 1.0%v1.0.4-beta.20
  • CHANNELS - چینلز کی فہرست اور werf کے متعلقہ موجودہ ورژن کے ساتھ ایک لائن، فارمیٹ میں اقدار کی جگہ سے الگ کردہ فہرست کی شکل میں <КАНАЛ>%<НОМЕР_ВЕРСИИ>. ایک مثال: 1.0-beta%v1.0.4-beta.20 1.0-alpha%v1.0.5-alpha.22
  • ROOT_VERSION — werf ریلیز ورژن کو سائٹ پر بطور ڈیفالٹ ڈسپلے کیا جائے گا (یہ ہمیشہ ضروری نہیں ہوتا ہے کہ دستاویزات کو سب سے زیادہ ریلیز نمبر کے ذریعے ظاہر کیا جائے)۔ مثال: v1.0.4-beta.20
  • REVIEW_SHA - جائزہ کمٹ کی ہیش جس سے آپ کو ٹیسٹ لوپ کے لیے ورژن بنانے کی ضرورت ہے۔

یہ متغیرات GitLab CI پائپ لائن میں پُر کیے جائیں گے، اور نیچے کیسے لکھا گیا ہے۔

سب سے پہلے، سہولت کے لیے، ہم اس کی وضاحت کرتے ہیں۔ werf.yaml ٹیمپلیٹ متغیرات پر جائیں، انہیں ماحولیاتی متغیرات سے قدریں تفویض کرتے ہوئے:

{{ $_ := set . "WerfVersions" (cat (env "CHANNELS") (env "RELEASES") | splitList " ") }}
{{ $Root := . }}
{{ $_ := set . "WerfRootVersion" (env "ROOT_VERSION") }}
{{ $_ := set . "WerfReviewCommit" (env "REVIEW_SHA") }}

سائٹ کے جامد ورژن کو مرتب کرنے کے لیے نمونے کی تفصیل عام طور پر ان تمام صورتوں کے لیے ایک جیسی ہوتی ہے جن کی ہمیں ضرورت ہوتی ہے (بشمول روٹ ورژن بنانا، نیز دیو سرکٹ کا ورژن)۔ لہذا، ہم فنکشن کا استعمال کرتے ہوئے اسے ایک علیحدہ بلاک میں منتقل کریں گے۔ define - بعد میں دوبارہ استعمال کرنے کے لیے include. ہم درج ذیل دلائل کو ٹیمپلیٹ میں منتقل کریں گے:

  • Version - تیار کردہ ورژن (ٹیگ کا نام)؛
  • Channel - اپ ڈیٹ چینل کا نام جس کے لیے آرٹفیکٹ تیار کیا گیا ہے۔
  • Commit - کمٹ ہیش، اگر آرٹفیکٹ جائزہ لینے کے لیے تیار کیا گیا ہو۔
  • خیال، سیاق۔

آرٹفیکٹ ٹیمپلیٹ کی تفصیل

{{- define "doc_artifact" -}}
{{- $Root := index . "Root" -}}
artifact: doc-{{ .Channel }}
from: jekyll/builder:3
mount:
- from: build_dir
  to: /usr/local/bundle
ansible:
  install:
  - shell: |
      export PATH=/usr/jekyll/bin/:$PATH
  - name: "Install Dependencies"
    shell: bundle install
    args:
      executable: /bin/bash
      chdir: /app/docs
  beforeSetup:
{{- if .Commit }}
  - shell: echo "Review SHA - {{ .Commit }}."
{{- end }}
{{- if eq .Channel "root" }}
  - name: "releases.yml HASH: {{ $Root.Files.Get "releases.yml" | sha256sum }}"
    copy:
      content: |
{{ $Root.Files.Get "releases.yml" | indent 8 }}
      dest:  /app/docs/_data/releases.yml
{{- else }}
  - file:
      path: /app/docs/_data/releases.yml
      state: touch
{{- end }}
  - file:
      path: "{{`{{ item }}`}}"
      state: directory
      mode: 0777
    with_items:
    - /app/main_site/
    - /app/ru_site/
  - file:
      dest: /app/docs/pages_ru/cli
      state: link
      src: /app/docs/pages/cli
  - shell: |
      echo -e "werfVersion: {{ .Version }}nwerfChannel: {{ .Channel }}" > /tmp/_config_additional.yml
      export PATH=/usr/jekyll/bin/:$PATH
{{- if and (ne .Version "review") (ne .Channel "root") }}
{{- $_ := set . "BaseURL" ( printf "v%s" .Channel ) }}
{{- else if ne .Channel "root" }}
{{- $_ := set . "BaseURL" .Channel }}
{{- end }}
      jekyll build -s /app/docs  -d /app/_main_site/{{ if .BaseURL }} --baseurl /{{ .BaseURL }}{{ end }} --config /app/docs/_config.yml,/tmp/_config_additional.yml
      jekyll build -s /app/docs  -d /app/_ru_site/{{ if .BaseURL }} --baseurl /{{ .BaseURL }}{{ end }} --config /app/docs/_config.yml,/app/docs/_config_ru.yml,/tmp/_config_additional.yml
    args:
      executable: /bin/bash
      chdir: /app/docs
git:
- url: https://github.com/flant/werf.git
  to: /app/
  owner: jekyll
  group: jekyll
{{- if .Commit }}
  commit: {{ .Commit }}
{{- else }}
  tag: {{ .Version }}
{{- end }}
  stageDependencies:
    install: ['docs/Gemfile','docs/Gemfile.lock']
    beforeSetup: '**/*'
  includePaths: 'docs'
  excludePaths: '**/*.sh'
{{- end }}

آرٹفیکٹ کا نام منفرد ہونا چاہیے۔ ہم اسے حاصل کر سکتے ہیں، مثال کے طور پر، چینل کا نام شامل کرکے (متغیر کی قدر .Channel) نمونے کے نام کے لاحقہ کے طور پر: artifact: doc-{{ .Channel }}. لیکن آپ کو یہ سمجھنے کی ضرورت ہے کہ نمونے سے درآمد کرتے وقت، آپ کو انہی ناموں کا حوالہ دینا ہوگا۔

کسی نمونے کو بیان کرتے وقت، درج ذیل werf خصوصیت استعمال کی جاتی ہے: بڑھتے ہوئے. سروس ڈائرکٹری کی نشاندہی کرنے والا اضافہ build_dir آپ کو پائپ لائن رنز کے درمیان جیکیل کیشے کو بچانے کی اجازت دیتا ہے، جو نمایاں طور پر reassembly کی رفتار.

آپ نے فائل کے استعمال کو بھی دیکھا ہوگا۔ releases.yml ایک YAML فائل ہے جس سے ریلیز ڈیٹا کی درخواست کی گئی ہے۔ گیتوب (پائپ لائن کو چلاتے وقت حاصل کردہ ایک نمونہ)۔ سائٹ کو مرتب کرتے وقت اس کی ضرورت ہوتی ہے، لیکن مضمون کے تناظر میں یہ ہمارے لیے دلچسپ ہے کیونکہ یہ اس کی حالت پر منحصر ہے۔ صرف ایک نمونے کی دوبارہ جوڑنا - سائٹ کے روٹ ورژن کا ایک نمونہ (دوسرے نمونے میں اس کی ضرورت نہیں ہے)۔

یہ مشروط بیان کا استعمال کرتے ہوئے لاگو کیا جاتا ہے if ٹیمپلیٹس اور ڈیزائن دیکھیں {{ $Root.Files.Get "releases.yml" | sha256sum }} مرحلے میں مراحل. یہ اس طرح کام کرتا ہے: جب روٹ ورژن (متغیر .Channel کے برابر ہے root) فائل ہیش releases.yml پورے مرحلے کے دستخط کو متاثر کرتا ہے، کیونکہ یہ جوابی کام کے نام کا حصہ ہے (پیرامیٹر name)۔ اس طرح، جب تبدیل ہوتا ہے مواد فائل releases.yml متعلقہ نمونے کو دوبارہ جمع کیا جائے گا۔

براہ کرم بیرونی ذخیرہ کے ساتھ کام کرنے پر بھی توجہ دیں۔ سے ایک نمونے کی تصویر میں werf ذخیرہ، صرف ڈائریکٹری شامل کی گئی ہے۔ /docs، اور منظور شدہ پیرامیٹرز پر منحصر ہے، مطلوبہ ٹیگ یا جائزہ کمٹ کا ڈیٹا فوری طور پر شامل کیا جاتا ہے۔

چینلز اور ریلیز کے منتقل شدہ ورژن کے نمونے کی تفصیل پیدا کرنے کے لیے آرٹفیکٹ ٹیمپلیٹ کا استعمال کرنے کے لیے، ہم متغیر پر ایک لوپ کو منظم کرتے ہیں۔ .WerfVersions в werf.yaml:

{{ range .WerfVersions -}}
{{ $VersionsDict := splitn "%" 2 . -}}
{{ dict "Version" $VersionsDict._1 "Channel" $VersionsDict._0 "Root" $Root | include "doc_artifact" }}
---
{{ end -}}

کیونکہ لوپ کئی نمونے تیار کرے گا (ہم امید کرتے ہیں)، ان کے درمیان جداکار کو مدنظر رکھنا ضروری ہے - ترتیب --- (کنفیگریشن فائل نحو کے بارے میں مزید معلومات کے لیے، دیکھیں دستاویزات)۔ جیسا کہ پہلے بیان کیا گیا ہے، جب کسی ٹیمپلیٹ کو لوپ میں کال کرتے ہیں، تو ہم ورژن کے پیرامیٹرز، یو آر ایل اور روٹ سیاق و سباق کو پاس کرتے ہیں۔

اسی طرح، لیکن بغیر کسی لوپ کے، ہم آرٹفیکٹ ٹیمپلیٹ کو "خصوصی کیسز" کے لیے کہتے ہیں: روٹ ورژن کے لیے، نیز جائزہ کمٹ کے ورژن کے لیے:

{{ dict "Version" .WerfRootVersion "Channel" "root" "Root" $Root  | include "doc_artifact" }}
---
{{- if .WerfReviewCommit }}
{{ dict "Version" "review" "Channel" "review" "Commit" .WerfReviewCommit "Root" $Root  | include "doc_artifact" }}
{{- end }}

براہ کرم نوٹ کریں کہ جائزہ کمٹ کے لیے نمونہ تب ہی بنایا جائے گا جب متغیر سیٹ ہو۔ .WerfReviewCommit.

نمونے تیار ہیں - یہ درآمد شروع کرنے کا وقت ہے!

حتمی تصویر، جسے Kubernetes پر چلانے کے لیے ڈیزائن کیا گیا ہے، ایک باقاعدہ NGINX ہے جس میں سرور کنفیگریشن فائل شامل کی گئی ہے۔ nginx.conf اور نمونے سے جامد۔ سائٹ کے روٹ ورژن کے نمونے کے علاوہ، ہمیں متغیر پر لوپ کو دہرانے کی ضرورت ہے .WerfVersions چینل کے نمونے درآمد کرنے اور ورژن جاری کرنے کے لیے + نمونے کے نام کے اصول کی پیروی کریں جسے ہم نے پہلے اپنایا تھا۔ چونکہ ہر آرٹفیکٹ سائٹ کے ورژن کو دو زبانوں کے لیے اسٹور کرتا ہے، اس لیے ہم انہیں کنفیگریشن کے ذریعے فراہم کردہ جگہوں پر درآمد کرتے ہیں۔

حتمی تصویر werf-doc کی تفصیل

image: werf-doc
from: nginx:stable-alpine
ansible:
  setup:
  - name: "Setup /etc/nginx/nginx.conf"
    copy:
      content: |
{{ .Files.Get ".werf/nginx.conf" | indent 8 }}
      dest: /etc/nginx/nginx.conf
  - file:
      path: "{{`{{ item }}`}}"
      state: directory
      mode: 0777
    with_items:
    - /app/main_site/assets
    - /app/ru_site/assets
import:
- artifact: doc-root
  add: /app/_main_site
  to: /app/main_site
  before: setup
- artifact: doc-root
  add: /app/_ru_site
  to: /app/ru_site
  before: setup
{{ range .WerfVersions -}}
{{ $VersionsDict := splitn "%" 2 . -}}
{{ $Channel := $VersionsDict._0 -}}
{{ $Version := $VersionsDict._1 -}}
- artifact: doc-{{ $Channel }}
  add: /app/_main_site
  to: /app/main_site/v{{ $Channel }}
  before: setup
{{ end -}}
{{ range .WerfVersions -}}
{{ $VersionsDict := splitn "%" 2 . -}}
{{ $Channel := $VersionsDict._0 -}}
{{ $Version := $VersionsDict._1 -}}
- artifact: doc-{{ $Channel }}
  add: /app/_ru_site
  to: /app/ru_site/v{{ $Channel }}
  before: setup
{{ end -}}

اضافی تصویر، جو کہ مرکزی تصویر کے ساتھ، دیو سرکٹ پر لانچ کی گئی ہے، اس میں سائٹ کے صرف دو ورژن ہیں: جائزہ کمٹ کا ورژن اور سائٹ کا روٹ ورژن (عام اثاثے ہیں اور، اگر آپ کو یاد ہو ، ڈیٹا جاری کریں)۔ اس طرح، اضافی تصویر صرف درآمدی حصے میں (اور ظاہر ہے، نام میں) اہم تصویر سے مختلف ہوگی:

image: werf-dev
...
import:
- artifact: doc-root
  add: /app/_main_site
  to: /app/main_site
  before: setup
- artifact: doc-root
  add: /app/_ru_site
  to: /app/ru_site
  before: setup
{{- if .WerfReviewCommit  }}
- artifact: doc-review
  add: /app/_main_site
  to: /app/main_site/review
  before: setup
- artifact: doc-review
  add: /app/_ru_site
  to: /app/ru_site/review
  before: setup
{{- end }}

جیسا کہ اوپر بیان کیا گیا ہے، جائزے کے عہد کے لیے نمونہ تب ہی تیار کیا جائے گا جب سیٹ ماحولیاتی متغیر چلایا جائے REVIEW_SHA. اگر کوئی ماحولیاتی متغیر نہیں ہے تو یہ ممکن ہے کہ werf-dev امیج کو بالکل بھی تیار نہ کیا جائے۔ REVIEW_SHA، لیکن کرنے کے لئے پالیسیوں کی طرف سے صفائی werf میں Docker امیجز نے werf-dev امیج کے لیے کام کیا، ہم پائپ لائن کی ساخت کو آسان بنانے کے لیے اسے صرف روٹ ورژن آرٹفیکٹ (یہ پہلے سے ہی بنایا گیا ہے) کے ساتھ بنایا جانا چھوڑ دیں گے۔

اسمبلی تیار ہے! آئیے CI/CD اور اہم باریکیوں کی طرف چلتے ہیں۔

GitLab CI میں پائپ لائن اور متحرک تعمیر کی خصوصیات

تعمیر کو چلاتے وقت ہمیں ماحولیاتی متغیرات کو ترتیب دینے کی ضرورت ہوتی ہے جس میں استعمال کیا جاتا ہے۔ werf.yaml. اس کا اطلاق REVIEW_SHA متغیر پر نہیں ہوتا، جسے ہم GitHub ہک سے پائپ لائن کال کرتے وقت سیٹ کریں گے۔

ہم باش اسکرپٹ میں ضروری بیرونی ڈیٹا تیار کریں گے۔ generate_artifacts، جو دو GitLab پائپ لائن نمونے تیار کرے گا:

  • файл releases.yml ریلیز ڈیٹا کے ساتھ،
  • файл common_envs.sh، برآمد کیے جانے والے ماحولیاتی متغیرات پر مشتمل ہے۔

فائل کے مواد generate_artifacts آپ کو ہمارے میں مل جائے گا مثالوں کے ساتھ ذخیرے. ڈیٹا وصول کرنا خود مضمون کا موضوع نہیں بلکہ فائل ہے۔ common_envs.sh ہمارے لئے اہم ہے، کیونکہ werf کا کام اس پر منحصر ہے. اس کے مواد کی ایک مثال:

export RELEASES='1.0%v1.0.6-4'
export CHANNELS='1.0-alpha%v1.0.7-1 1.0-beta%v1.0.7-1 1.0-ea%v1.0.6-4 1.0-stable%v1.0.6-4 1.0-rock-solid%v1.0.6-4'
export ROOT_VERSION='v1.0.6-4'

آپ ایسی اسکرپٹ کا آؤٹ پٹ استعمال کر سکتے ہیں، مثال کے طور پر، Bash فنکشن کا استعمال کرتے ہوئے source.

اب آتا ہے مزے کا حصہ۔ درخواست کی تعمیر اور تعیناتی دونوں کے صحیح طریقے سے کام کرنے کے لیے، اس بات کو یقینی بنانا ضروری ہے۔ werf.yaml تھا ایسا ہی کم سے کم ایک پائپ لائن کے اندر. اگر اس شرط کو پورا نہیں کیا جاتا ہے، تو ان مراحل کے دستخط جو werf اسمبلی کے دوران حساب کرتے ہیں اور، مثال کے طور پر، تعیناتی، مختلف ہوں گے۔ یہ تعیناتی کی خرابی کا باعث بنے گا، کیونکہ... تعیناتی کے لیے درکار تصویر غائب ہو جائے گی۔

دوسرے لفظوں میں، اگر سائٹ امیج کی اسمبلی کے دوران ریلیزز اور ورژنز کے بارے میں معلومات ایک جیسی ہیں، اور تعیناتی کے وقت ایک نیا ورژن جاری کیا جاتا ہے اور ماحولیاتی متغیرات کی قدریں مختلف ہوتی ہیں، تو تعیناتی غلطی کے ساتھ ناکام ہو جائے گی: سب کے بعد، نئے ورژن کے artifact کو ابھی تک تعمیر نہیں کیا گیا ہے.

اگر نسل werf.yaml بیرونی ڈیٹا پر منحصر ہے (مثال کے طور پر، موجودہ ورژن کی فہرست، جیسا کہ ہمارے معاملے میں)، پھر اس طرح کے ڈیٹا کی ساخت اور اقدار کو پائپ لائن میں ریکارڈ کیا جانا چاہیے۔ یہ خاص طور پر اہم ہے اگر بیرونی پیرامیٹرز کثرت سے تبدیل ہوں۔

ہم کریں گے بیرونی ڈیٹا وصول اور ریکارڈ کریں۔ گٹ لیب میں پائپ لائن کے پہلے مرحلے پر (پری بلڈ) اور انہیں فارم میں مزید منتقل کریں۔ GitLab CI آرٹفیکٹ. یہ آپ کو اسی ترتیب کے ساتھ پائپ لائن جابز (تعمیر، تعینات، صفائی) چلانے اور دوبارہ شروع کرنے کی اجازت دے گا۔ werf.yaml.

اسٹیج کے مشمولات پری بلڈ فائل .gitlab-ci.yml:

Prebuild:
  stage: prebuild
  script:
    - bash ./generate_artifacts 1> common_envs.sh
    - cat ./common_envs.sh
  artifacts:
    paths:
      - releases.yml
      - common_envs.sh
    expire_in: 2 week

آرٹفیکٹ میں بیرونی ڈیٹا حاصل کرنے کے بعد، آپ GitLab CI پائپ لائن کے معیاری مراحل کا استعمال کرتے ہوئے تعمیر اور تعینات کر سکتے ہیں: بنائیں اور تعینات کریں۔ ہم پائپ لائن خود ہی werf GitHub ریپوزٹری سے ہکس کا استعمال کرتے ہوئے شروع کرتے ہیں (یعنی جب GitHub ریپوزٹری میں تبدیلیاں آتی ہیں)۔ ان کے لیے ڈیٹا سیکشن میں GitLab پروجیکٹ کی خصوصیات میں پایا جا سکتا ہے۔ CI/CD سیٹنگز -> پائپ لائن ٹرگرز، اور پھر GitHub میں متعلقہ Webhook بنائیں (ترتیبات -> ویب ہکس).

تعمیر کا مرحلہ اس طرح نظر آئے گا:

Build:
  stage: build
  script:
    - type multiwerf && . $(multiwerf use 1.0 alpha --as-file)
    - type werf && source <(werf ci-env gitlab --tagging-strategy tag-or-branch --verbose)
    - source common_envs.sh
    - werf build-and-publish --stages-storage :local
  except:
    refs:
      - schedules
  dependencies:
    - Prebuild

GitLab اسٹیج سے تعمیر کے مرحلے میں دو نمونے شامل کرے گا۔ پری بلڈ، لہذا ہم کنسٹرکٹ کا استعمال کرتے ہوئے تیار کردہ ان پٹ ڈیٹا کے ساتھ متغیرات برآمد کرتے ہیں۔ source common_envs.sh. ہم تمام صورتوں میں تعمیراتی مرحلہ شروع کرتے ہیں، سوائے ایک شیڈول کے مطابق پائپ لائن شروع کرنے کے۔ شیڈول کے مطابق، ہم صفائی کے لئے ایک پائپ لائن چلائیں گے - اس صورت میں اسمبلی کو انجام دینے کی ضرورت نہیں ہے.

تعیناتی کے مرحلے پر، ہم دو کاموں کی وضاحت کریں گے - YAML ٹیمپلیٹ کا استعمال کرتے ہوئے، پروڈکشن اور دیو سرکٹس میں تعیناتی کے لیے:

.base_deploy: &base_deploy
  stage: deploy
  script:
    - type multiwerf && . $(multiwerf use 1.0 alpha --as-file)
    - type werf && source <(werf ci-env gitlab --tagging-strategy tag-or-branch --verbose)
    - source common_envs.sh
    - werf deploy --stages-storage :local
  dependencies:
    - Prebuild
  except:
    refs:
      - schedules

Deploy to Production:
  <<: *base_deploy
  variables:
    WERF_KUBE_CONTEXT: prod
  environment:
    name: production
    url: werf.io
  only:
    refs:
      - master
  except:
    variables:
      - $REVIEW_SHA
    refs:
      - schedules

Deploy to Test:
  <<: *base_deploy
  variables:
    WERF_KUBE_CONTEXT: dev
  environment:
    name: test
    url: werf.test.flant.com
  except:
    refs:
      - schedules
  only:
    variables:
      - $REVIEW_SHA

کام بنیادی طور پر صرف کلسٹر سیاق و سباق کی نشاندہی کرنے میں مختلف ہوتے ہیں جس میں werf کو تعیناتی انجام دینا چاہئے (WERF_KUBE_CONTEXT)، اور لوپ ماحول کے متغیرات کو ترتیب دینا (environment.name и environment.url) جو پھر ہیلم چارٹ ٹیمپلیٹس میں استعمال ہوتے ہیں۔ ہم ٹیمپلیٹس کا مواد فراہم نہیں کریں گے، کیونکہ... زیر بحث موضوع کے لیے وہاں کوئی دلچسپ چیز نہیں ہے، لیکن آپ انہیں تلاش کر سکتے ہیں۔ مضمون کے لئے ذخیرہ.

آخری ٹچ

چونکہ werf ورژن اکثر جاری کیے جاتے ہیں، نئی تصاویر کثرت سے بنائی جائیں گی، اور Docker رجسٹری مسلسل بڑھے گی۔ لہذا، پالیسیوں کی بنیاد پر خودکار امیج کلین اپ کو ترتیب دینا ضروری ہے۔ یہ کرنا بہت آسان ہے۔

لاگو کرنے کے لئے آپ کو ضرورت ہو گی:

  • میں صفائی کا ایک قدم شامل کریں۔ .gitlab-ci.yml;
  • صفائی کے کام کی وقتاً فوقتاً عملدرآمد شامل کریں۔
  • تحریری رسائی کے ٹوکن کے ساتھ ماحولیاتی متغیر ترتیب دیں۔

میں صفائی کا مرحلہ شامل کرنا .gitlab-ci.yml:

Cleanup:
  stage: cleanup
  script:
    - type multiwerf && . $(multiwerf use 1.0 alpha --as-file)
    - type werf && source <(werf ci-env gitlab --tagging-strategy tag-or-branch --verbose)
    - source common_envs.sh
    - docker login -u nobody -p ${WERF_IMAGES_CLEANUP_PASSWORD} ${WERF_IMAGES_REPO}
    - werf cleanup --stages-storage :local
  only:
    refs:
      - schedules

ہم نے پہلے ہی یہ سب کچھ تھوڑا اونچا دیکھا ہے - صرف اسے صاف کرنے کے لیے آپ کو سب سے پہلے ڈوکر رجسٹری میں ایک ٹوکن کے ساتھ لاگ ان کرنے کی ضرورت ہے جس میں ڈوکر رجسٹری میں تصاویر کو حذف کرنے کے حقوق ہیں (خودکار طور پر جاری کردہ GitLab CI ٹاسک ٹوکن ایسا نہیں کرتا ہے۔ ایسے حقوق رکھتے ہیں)۔ ٹوکن کو GitLab میں پہلے سے ہی بنایا جانا چاہیے اور اس کی قدر ماحولیاتی متغیر میں بتائی جانی چاہیے۔ WERF_IMAGES_CLEANUP_PASSWORD پروجیکٹ (CI/CD ترتیبات -> متغیرات).

مطلوبہ نظام الاوقات کے ساتھ صفائی کے کام کو شامل کرنا اندر کیا جاتا ہے۔ CI/CD ->
شیڈولز
.

بس: ڈوکر رجسٹری میں ایک پروجیکٹ اب غیر استعمال شدہ امیجز سے مسلسل بڑھے گا۔

عملی حصے کے آخر میں، میں آپ کو یاد دلاتا ہوں کہ مضمون کی مکمل فہرستیں دستیاب ہیں۔ جاؤ:

نتیجہ

  1. ہمیں ایک منطقی اسمبلی کا ڈھانچہ موصول ہوا: فی ورژن ایک نمونہ۔
  2. اسمبلی آفاقی ہے اور جب werf کے نئے ورژن جاری کیے جاتے ہیں تو اسے دستی تبدیلیوں کی ضرورت نہیں ہوتی: ویب سائٹ پر موجود دستاویزات خود بخود اپ ڈیٹ ہو جاتی ہیں۔
  3. دو تصاویر مختلف شکلوں کے لیے جمع کی جاتی ہیں۔
  4. یہ تیزی سے کام کرتا ہے، کیونکہ کیشنگ کو زیادہ سے زیادہ استعمال کیا جاتا ہے - جب werf کا نیا ورژن جاری کیا جاتا ہے یا ایک GitHub ہک کو جائزہ لینے کے لیے بلایا جاتا ہے، صرف تبدیل شدہ ورژن کے ساتھ متعلقہ آرٹفیکٹ کو دوبارہ بنایا جاتا ہے۔
  5. غیر استعمال شدہ تصاویر کو حذف کرنے کے بارے میں سوچنے کی ضرورت نہیں: werf پالیسیوں کے مطابق صفائی Docker رجسٹری کو ترتیب میں رکھے گی۔

نتائج

  • werf کا استعمال اسمبلی کو خود اسمبلی کی کیشنگ اور بیرونی ذخیروں کے ساتھ کام کرتے وقت کیشنگ کی وجہ سے تیزی سے کام کرنے کی اجازت دیتا ہے۔
  • بیرونی گٹ ریپوزٹریز کے ساتھ کام کرنے سے ہر بار پوری ریپوزٹری کو کلون کرنے یا مشکل آپٹیمائزیشن منطق کے ساتھ پہیے کو دوبارہ ایجاد کرنے کی ضرورت ختم ہوجاتی ہے۔ werf ایک کیشے کا استعمال کرتا ہے اور کلوننگ صرف ایک بار کرتا ہے، اور پھر استعمال کرتا ہے۔ fetch اور صرف جب ضروری ہو.
  • تعمیر کنفیگریشن فائل میں گو ٹیمپلیٹس استعمال کرنے کی اہلیت werf.yaml آپ کو ایک ایسی اسمبلی کی وضاحت کرنے کی اجازت دیتا ہے جس کا نتیجہ بیرونی ڈیٹا پر منحصر ہوتا ہے۔
  • werf میں ماؤنٹ کا استعمال نمایاں طور پر نمونے جمع کرنے کی رفتار کو تیز کرتا ہے - کیشے کی وجہ سے، جو تمام پائپ لائنوں میں عام ہے۔
  • werf صفائی کو ترتیب دینا آسان بناتا ہے، جو کہ متحرک طور پر تعمیر کرتے وقت خاص طور پر اہم ہے۔

PS

ہمارے بلاگ پر بھی پڑھیں:

ماخذ: www.habr.com

DDoS تحفظ، VPS VDS سرورز والی سائٹوں کے لیے قابل اعتماد ہوسٹنگ خریدیں۔ DDoS تحفظ، VPS VDS سرورز کے ساتھ قابل اعتماد ویب سائٹ ہوسٹنگ خریدیں۔ ProHoster