سلام!
به مسابقه *DevOps* *کدکاپ ۶* خوش آمدید.
به عنوان تمرین اول از شما میخواهیم تا اسکریپتی بنویسید که به دوآپس سلام کند! یعنی پس از اجرا صرفا عبارت زیر را چاپ کند.
```
Hello DevOps!
```
به علامتهای نگارشی و بزرگی و کوچکی **توجه کنید.** خروجی اسکریپت شما باید دقیقا برابر مقدار خواسته شده باشد.
## مثال
برای مثال اگر اسکریپت شما را مانند زیر اجرا کنیم:
```bash
./hello.sh
```
باید خروجی زیر را دهد:
```
Hello DevOps!
```
## پروژه اولیه
برای دریافت پروژه اولیه [این لینک](/contest/assignments/35054/download_problem_initial_project/127099/) را دانلود کنید. درون لینک ساختار فایلی زیر را مشاهده میکنید:
```
Hello_DevOps
└── hello.sh
```
راهحل خود را درون فایل `hello.sh` پیادهسازی کنید.
## توجه کنید
+ فراموش نکنید که اسکریپتی کامل را در پاسختان تحویل دهید.
+ فراموش نکنید که اسکریپت خود را درون فایلی با نام `hello.sh` وارد نمایید.
+ برای ارسال پاسخ خود کافیست فایل `hello.sh` را آپلود کنید.
سلام DevOps
*عبدالله* اخیرا به برنامهنویسی و نرمافزار علاقهمند شده و در مسابقات کدکاپ ثبتنام کرده است. اما متأسّفانه مسابقه *DevOps* کدکاپ با کنسرت *عبدالله* همزمان شده است و به کمک شما نیاز دارد. *عبدالله* دوست دارد در زمینهی *Docker* هم ستاره شود و منتور *عبدالله* به او گفته است **«انسان در محدودیتها ستاره میشود»** حالا او میخواهد چند محدودیت در منابع یک *container* قدیمی اعمال کند.
به *عبدالله* کمک کنید محدویتهای زیر را در منابع یک *container* داکر *Redis* اضافه کند:
- **Memory Limit**: `30M`
- **CPU Shares**: `70`
برای دانلود پروژهی اولیه روی [این لینک](/contest/assignments/35054/download_problem_initial_project/126761/) کلیک کنید.
## نکات تکمیلی
۱. شما اجازهی *build* کردن یک *Image* جدید **نخواهید داشت** و باید از *Imageهای* استاندارد استفاده کنید. بهطور خاص، برای *Redis* میتوانید از *Image* با آدرس زیر استفاده کنید:
```
registry.gitlab.com/qio/standard/redis:latest
```
۲. نام *container* باید `limited_redis` باشد.
۳. سیستم داوری کوئرا بهصورت خودکار فایل `docker-compose.yml` را با کامند `up` اجرا میکند. **شما نیازی به کد یا اسکریپتی برای اجرای این کار ندارید.**
۴. **توجه داشته باشید** که ورژن `docker-compose.yml` باید `2` باشد.
## نحوه ارسال پاسخ
شما تنها مجاز به ارسال فایل `docker-compose.yml` هستید.
``` yaml docker-compose.yml
version: "2"
# Do not forget that the only available
# redis image is accessible with the following url:
# registry.gitlab.com/qio/standard/redis:latest
```
ستارهی دنبالهدار
حتماً با اپلیکیشن مزخرفی بهنام واتساپ کار کردهاید. واتساپ در تیم مزخرف خود، به همکار خوبی مثل شما نیاز دارد تا بهعنوان یک مهندس، بتوانید این اپلیکیشن را بهبود دهید. یکی از مهمترین کارهایی که برای نگهداری و کارایی واتساپ نیاز است، ایجاد چندین سرور و پخش نمودن درخواستهای کاربران میان آنهاست.
برای دانلود پروژهی اولیه روی [این لینک](/contest/assignments/35054/download_problem_initial_project/126765/) کلیک کنید.
## سیستم *apiها*
واتساپ، از قبل ۴ کانتینر برای *apiهای* خود تدارک دیده که شما از جزئیات *apiها* کاملاً بیخبر هستید و محتویات این *apiها* **کاملاً محرمانه** میباشد. این *apiها،* در فایل `docker-compose.yml` وجود دارند و تنها کاری که شما باید انجام دهید، اضافه کردن یک سیستم لودبالانس بر روی پورت `80` این سیستم، در کنار بقیهی کانتینرها میباشد.
## لودبالانس
اضافه کردن یک *container* در فایل `docker-compose.yml` که بر روی پورت `80` سرور فعال باشد و میان ۴ سرویس موجود، عملیات لودبالانس را بهصورت **کاملاً مساوی** انجام دهد. به این نکته توجه داشته باشید که این لودبالانس میان سرویسها باید کاملاً مساوی اتفاق بیوفتد و تمامی ریکوئستها دقیقاً میان سرویسها بهطور برابر پخش شوند.
فراموش نکنید که **تنها** میتوانید از ایمیجهای *[Standard](https://gitlab.com/qio/standard/container_registry)* در رجیستری کوئرا استفاده نمایید. فرقی نمیکند با چه ایمیج یا تکنولوژیای این کار را انجام دهید. حتی میتوانید خودتان برنامهای بنویسید که لودبالانس انجام دهد. تنها نکتهی مهم این است که بر روی پورت `80` آن برنامه را اجرا نمایید.
همچنین توجه داشته باشید ممکن است برچسب ایمیج موردنظر شما لزوما `:latest` **نباشد**، برای مثال ایمیج `HAProxy` تنها به دو صورت `registry.gitlab.com/qio/standard/haproxy:2.5` و `registry.gitlab.com/qio/standard/haproxy:2.5-alpine` وجود دارند.
### نکتهی مهم
شما اجازهی *build* کردن ایمیج جدید **نخواهید داشت** و در صورتی که میخواهید خودتان برنامهای بنویسید که کار لودبالانس را انجام دهد، باید از پوشهی `data` که برای ایجاد *volume* در نظر گرفتیم استفاده کنید و برنامهی خود را به درون کانتینرهای موجود *volume* کنید. مثلاً برنامهای پایتونی نوشتهاید که در ایمیج پایتون استاندارد کوئرا *volume* میشود و در *entrypoint* آن را اجرا میکنید.
## ایجاد *Volume*
در صورتیکه نیاز دارید فایل یا مسیری را به درون هریک از *containerها Volume* کنید، میتوانید از پوشهای بهنام `data` استفاده کنید. و برای ایجاد *Volume* از *Relative Path* استفاده کنید. برای مثال:
```
services:
sample_container:
image: "registry.gitlab.com/qio/standard/someimage:latest"
volumes:
- ./data/somefile:/somefile
```
فراموش نکنید که فایل `somefile` را درون پوشهی `data` قرار داده و آن را برای داوری ارسال نمایید. برای مثال، پوشهی ارسالی شما برای داوری کوئرا به شکل زیر میتواند باشد:
```
.
├── data
│ └── somefile
└── docker-compose.yml
```
اگر محتوای پوشه `data`تان خالی است، میتوانید این پوشه را ارسال نکنید.
**توجه:** سیستم داوری کوئرا بهصورت خودکار فایل `docker-compose.yml` را با کامند `up` اجرا میکند. شما نیازی به کد یا اسکریپتی برای اجرای این کار ندارید.
## نحوه ارسال پاسخ
شما فقط میتوانید مسیرهای هایلایت شده را تغییر دهید:
```
.
├── <mark class="yellow" title="این پوشه را میتوانید تغییر دهید"> data </mark>
│ └── ...
├── <mark class="yellow" title="این فایل را میتوانید تغییر دهید"> docker-compose.yml </mark>
└── requirements.txt
```
در نهایت این پوشه را *zip* کرده و ارسال کنید. توجه کنید که پس از *extract* کردن فایل *zip* شما، باید فایل `docker-compose.yml` را ببینیم.
پخشم کن
*پیمان* مسئول *DevOps* یک سایت شده که چند کاربر بَلا دارد که ریکوئستهای زیادی میزنند و *پیمان* میخواهد آنها را بلاک کند.
به *پیمان* کمک کنید از روی فایل لاگ `nginx` بتواند آن دسته از *IPهایی* که **بیشتر از** `n` **ریکوئست در دقیقه** زدهاند را با استفاده از `iptables` بلاک کند. او برای این کار یک اسکریپت **bash** نیاز دارد که *argumentهای* **آدرس فایل لاگ** و **عدد n** را دریافت کند.
برای دانلود پروژهی اولیه روی [این لینک](/contest/assignments/35054/download_problem_initial_project/126867/) کلیک کنید.
## نکات تکمیلی
۱. نمونه لاگ `nginx` که در داوری استفاده میشود در فایل `nginx_logs_sample` در پروژهی اولیه ( [این لینک](/contest/assignments/35054/download_problem_initial_project/126867/) ) قرار دارد. بخشی از این لاگ نمونه:
```
148.251.49.20 - - [20/May/2021:19:05:24 +0000] "GET /downloads/product_2 HTTP/1.1" 200 931 "-" "Wget/1.13.4 (linux-gnu)"
104.131.19.181 - - [20/May/2021:19:05:31 +0000] "GET /downloads/product_1 HTTP/1.1" 404 328 "-" "Debian APT-HTTP/1.3 (1.0.1ubuntu2)"
37.16.72.129 - - [20/May/2021:19:05:25 +0000] "GET /downloads/product_1 HTTP/1.1" 304 0 "-" "Debian APT-HTTP/1.3 (0.8.10.3)"
37.16.72.129 - - [20/May/2021:19:05:01 +0000] "GET /downloads/product_1 HTTP/1.1" 404 340 "-" "Debian APT-HTTP/1.3 (0.8.10.3)"
37.16.72.129 - - [20/May/2021:19:05:41 +0000] "GET /downloads/product_1 HTTP/1.1" 404 337 "-" "Debian APT-HTTP/1.3 (0.8.10.3)"
```
۲. برای نمونه اسکریپتی که شما مینویسید با دستور زیر اجرا و داوری خواهد شد:
```sh
bash blocker.sh nginx_logs_sample 7
```
پس از اجرای دستور فوق با فایل لاگ نمونه که در پروژه اولیه در اختیارتان است، باید IP های زیر در **iptables** بلاک شوند:
```
129.67.24.6
130.199.3.165
137.117.180.46
137.117.183.81
137.117.184.211
137.117.184.219
148.251.112.153
148.251.23.199
173.255.243.139
174.103.128.249
178.62.213.239
180.179.174.219
185.20.227.198
186.67.186.2
192.133.141.142
193.84.27.10
200.28.3.2
200.28.3.3
209.177.145.225
216.46.173.126
217.168.17.5
50.57.209.100
54.144.73.8
54.165.189.135
54.172.110.13
54.172.164.189
54.173.226.7
54.194.93.59
54.213.131.92
54.244.94.5
54.77.28.244
54.84.191.5
5.63.153.125
5.63.157.73
65.39.197.164
72.32.152.84
74.125.60.158
80.91.33.133
84.208.15.12
85.21.237.138
89.191.68.234
94.236.106.132
94.242.57.74
94.242.58.153
94.242.58.216
```
## نحوه ارسال پاسخ
شما تنها مجاز به ارسال فایل `blocker.sh` هستید.
``` bash blocker.sh
#!/bin/bash
log_path=$1
n=$2
# TODO: Block IPs with more than n request per minute by iptables
```
بِلاکر بَلایا
ایلانماسک برای ارسال یک ماهواره به مدار زمین، نیازمند یک کلاستر ردیس میباشد؛ اما او، پس از ریزش شدید *dogecoin،* بهشدت بیپول شده است و نمیتواند هزینهی اجارهی چند سرور ابری برای ایجاد یک کلاستر ردیس را پرداخت کند. بنابراین میخواهد یک کلاستر ردیس را بر روی چند *docker container* با کمک *Ansible* بالا بیاورد. او در این مسیر نیازمند کمک شماست.
برای دانلود پروژهی اولیه روی [این لینک](/contest/assignments/35054/download_problem_initial_project/126763/) کلیک کنید.
## کانتینرهای **Redis**
در ابتدای کار، برای ایجاد کانتینرهای ردیس، نیاز است که فایل `docker-compose.yml` را تکمیل کنید. توجه داشته باشید که شما اجازهی *build* کردن یک *Image* جدید **نخواهید داشت** و باید از *Imageهای* استاندارد استفاده کنید. بهطور خاص، برای *Redis* میتوانید از *Image* زیر استفاده کنید:
```
registry.gitlab.com/qio/standard/redis:latest
```
توجه داشته باشید که باید فایل `docker-compose.yml` را بهشکلی تکمیل کنید که پس از `up` کردن آن، ۶ کانتینر *Redis* اجرا شوند که ۳ تا از آنها برای *Nodeهای master* و ۳ تای دیگر آنها برای *Nodeهای slave* استفاده خواهند شد. **پس توجه داشته باشید که ما از شما انتظار داریم که به ازای هر *Node* اصلی، یک *replica* ایجاد شود** همچنین *network* همهی کانتینرها `host` باشد و در نظر داشته باشید ایمیج `registry.gitlab.com/qio/standard/redis:latest` برابر با همان ایمیج `redis` اصلی است و داکیومنت آن در [این لینک](https://hub.docker.com/_/redis) قابل مشاهده است.
### شرایط *containerها*
**۱. نام containerها باید حتماً به شکل زیر باشد:**
```
master1
master2
master3
slave1
slave2
slave3
```
توجه کنید، آن کانتینری که نامش با *master* شروع میشود، در انتهای کار، باید واقعاً حاوی یک *Node* از ردیس *Master* باشد و آن کانتینری که نامش با *slave* شروع میشود، در انتهای کار، باید واقعاً حاوی یک *Node* از ردیس *Slave* یا *replica* باشد.
**۲. هریک از این containerها باید روی پورت مشخصی که مربوط به آنها میباشد قرار گیرند.** دقیقاً به شکل زیر:
```
port of master1 = 7000
port of master2 = 7001
port of master3 = 7002
port of slave1 = 7003
port of slave2 = 7004
port of slave3 = 7005
```
### ایجاد *Volume*
در صورتیکه نیاز دارید فایل یا مسیری را به درون هریک از *containerها Volume* کنید، میتوانید از پوشهای بهنام `data` استفاده کنید. و برای ایجاد *Volume* از *Relative Path* استفاده کنید. برای مثال:
```yaml docker-compose.yml
services:
sample_container:
image: "registry.gitlab.com/qio/standard/redis:latest"
network_mode: host
volumes:
- ./data/somefile:/somefile
```
فراموش نکنید که فایل `somefile` را درون پوشهی `data` قرارداده و آن را برای داوری ارسال نمایید. برای مثال، پوشهی ارسالی شما برای داوری کوئرا به شکل زیر میتواند باشد:
```
.
├── data
│ └── somefile
├── docker-compose.yml
├── requirements.txt
├── roles
│ └── redis
│ ├── handlers
│ ├── tasks
│ │ ├── cluster.yml
│ │ └── main.yml
│ └── templates
└── site.yml
```
درصورتی که علاقهمند به استفاده از پوشهی `data` نیستید نیز مشکلی نیست و میتوانید آن را ارسال نکنید.
**توجه:** سیستم داوری کوئرا بهصورت خودکار فایل `docker-compose.yml` را با کامند `up` اجرا میکند. شما نیازی به کد یا اسکریپتی برای اجرای این کار ندارید.
## ایجاد *cluster* با *Ansible*
پس از بالا آمدن *containerهای Redis،* که سیستم داوری کوئرا بهصورت خودکار آنها را با استفاده از فایل `docker-compose.yml` شما بالا میآورد، شما نیازمند ایجاد هماهنگی میان این *Nodeهای Redis* خواهید بود. برای ایجاد این هماهنگی (یا اصطلاحاً ایجاد *cluster*)، میتوانید از *Ansible* استفاده کنید.
پس از بالا آمدن کامل همهی *containerهای Redis،* فایل `site.yml` با دستور `ansible-playbook` اجرا خواهد شد. شما میتوانید فایل `cluster.yml` را به هر صورتی که نیاز دارید تغییر دهید، بهشکلی که *cluster* مربوط به *Nodeهای Redis* ایجاد شود.
**توجه:** شما در سیستم *host،* به `redis-cli` دسترسی ندارید. در واقع، `redis-server` در سیستم *host* نصب نیست. (راهنمایی: اما در تمامی *Nodeها* نصب است!)
## شرایط نمرهدهی
در صورتی که علاقهمند به استفاده از *Ansible* برای اجرای کلاستر نیستید، میتوانید از آن استفاده نکنید. تمامی نمرهای که شما دریافت میکنید، مربوط به اجرای درست و دقیق کلاستر خواهد بود. پس اگر میتوانید بدون استفاده از *Ansible،* یک کلاستر ردیس میان ۶ کانتینر ایجاد کنید، این کار را انجام دهید. بههرحال این امکان برای شما وجود دارد که از *Ansible* برای اجرای دستوراتی که علاقهمند به اجرای آنها در سیستم *host* هستید استفاده کنید.
## نحوه ارسال پاسخ
شما فقط میتوانید مسیرهای هایلایت شده را تغییر دهید:
```
.
├── <mark class="yellow" title="این پوشه را میتوانید تغییر دهید"> data </mark>
│ └── ...
├── <mark class="yellow" title="این فایل را میتوانید تغییر دهید"> docker-compose.yml </mark>
├── requirements.txt
├── roles
│ └── redis
│ ├── handlers
│ ├── tasks
│ │ ├── <mark class="yellow" title="این فایل را میتوانید تغییر دهید"> cluster.yml </mark>
│ │ └── main.yml
│ └── templates
└── site.yml
```
در نهایت این پوشه را *zip* کرده و ارسال کنید. توجه کنید که پس از *extract* کردن فایل *zip* شما، باید فایل `docker-compose.yml` را ببینیم.