Описание выполненных домашних заданий.
Выполнены все основные и дополнительные пункты ДЗ.
- Установлен Helm;
- Tiller deprecated;
- Выполнена разработка Chart'ов для компоненов
ui
,post
,comment
иmongodb
; - Созданы шаблоны манифестов
deployment.yaml
,ingress.yaml
,service.yaml
; - Определены переменные в
values.yml
; - Создан хелпер в
_helpers.tpl
; - Установлено несколько релизов ui;
- С помощью механизма управления зависимостями создан единый Chart
reddit
, который объединяет все компоненты; - После выполнения
helm dep update
появился файлrequirements.lock
с фиксацией зависимостей, и создалась директорияcharts
с зависимостями в виде архивов; - В Yandex Cloud поднят k8s-кластер;
- Поднят Network LoadBalancer со статическим IP;
- Подготовлены доменные имена для GitLab в зоне
otus.kga.spb.ru
для корректного выпуска Let's Encrypt сертификатов и работы поhttps
; - Установлен
ingress-nginx
;
helm upgrade --install ingress-nginx ingress-nginx --repo https://kubernetes.github.io/ingress-nginx --namespace ingress-nginx --create-namespace
- Установлен GitLab с помощью Helm Chart'а;
$ helm repo add gitlab https://charts.gitlab.io/
$ helm repo update
$ helm upgrade --install gitlab gitlab/gitlab \
--namespace gitlab --create-namespace \
--timeout 600s \
--set global.hosts.domain=otus.kga.spb.ru \
--set global.hosts.https=true \
--set global.ingress.configureCertmanager=true \
--set certmanager-issuer.email=shr@kga.spb.ru \
--set global.kas.enabled=true \
--set global.edition=ce \
--set global.time_zone=Europe/Moscow \
--set postgresql.image.tag=13.6.0
- Компоненты GitLab успешно поднялись на доменных именах, сертификаты успешно выпустились;
$ kubectl get ingress -n gitlab
NAME CLASS HOSTS ADDRESS PORTS AGE
gitlab-minio gitlab-nginx minio.otus.kga.spb.ru 10.129.0.12 80, 443 153m
gitlab-registry gitlab-nginx registry.otus.kga.spb.ru 10.129.0.12 80, 443 153m
gitlab-kas gitlab-nginx kas.otus.kga.spb.ru 10.129.0.12 80, 443 153m
gitlab-webservice-default gitlab-nginx gitlab.otus.kga.spb.ru 10.129.0.12 80, 443 153m
- В GitLab запушены проекты
comment
,post
,reddit-deploy
,ui
; - Настроены GitLab agent'ы для подключения проектов к Kubernetes кластеру;
- В файле
.gitlab-ci.yml
описан универсальный пайплайн дляcomment
,post
, иui
, сборка всех образов выполняется успешно;
Файлы
.gitlab-ci.yml
см. в каталогеkubernetes/Charts/gitlab-ci
- Создан новый бранч
feature/3
в репозитории ui; - CI настроен на запуск отдельного окружения в Kubernetes по коммиту в feature-бранч (см.
kubernetes/Charts/gitlab-ci/.gitlab-ci-ui.yml
); - По адресу
http://${CI_ENVIRONMENT_SLUG}.${CI_PAGES_DOMAIN}
поднимается сайт для окружения; - Полученный файл
.gitlab-ci.yml
для ui скопирован в репозитории для post и comment; - Динамическое создание и удаление окружений работает для всех проектов;
$ kubectl get all,cm,secret,ing -n review
NAME READY STATUS RESTARTS AGE
pod/review-shrkga-ui-txcrrz-post-7494d56db9-nxc96 1/1 Running 0 5m4s
pod/review-shrkga-ui-txcrrz-ui-5f5f94c99d-fkcxd 1/1 Running 0 5m4s
pod/review-shrkga-ui-txcrrz-post-7494d56db9-kgx9c 1/1 Running 0 5m4s
pod/review-shrkga-ui-txcrrz-ui-5f5f94c99d-4vg9h 1/1 Running 0 5m4s
pod/review-shrkga-ui-txcrrz-post-7494d56db9-kpk7d 1/1 Running 0 5m4s
pod/review-shrkga-ui-txcrrz-ui-5f5f94c99d-6lmj6 1/1 Running 0 5m4s
pod/review-shrkga-ui-txcrrz-mongodb-867db6966d-6wfc7 1/1 Running 0 5m4s
pod/review-shrkga-ui-txcrrz-comment-5bd6445db7-nbqkj 1/1 Running 0 5m4s
pod/review-shrkga-ui-txcrrz-comment-5bd6445db7-hl9hc 1/1 Running 0 5m4s
pod/review-shrkga-ui-txcrrz-comment-5bd6445db7-xhk9k 1/1 Running 0 5m4s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/review-shrkga-ui-txcrrz-comment ClusterIP 10.43.27.161 <none> 9292/TCP 5m4s
service/review-shrkga-ui-txcrrz-ui NodePort 10.43.125.210 <none> 9292:30196/TCP 5m4s
service/review-shrkga-ui-txcrrz-post ClusterIP 10.43.155.18 <none> 5000/TCP 5m4s
service/review-shrkga-ui-txcrrz-mongodb ClusterIP 10.43.23.32 <none> 27017/TCP 5m4s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/review-shrkga-ui-txcrrz-post 3/3 3 3 5m4s
deployment.apps/review-shrkga-ui-txcrrz-ui 3/3 3 3 5m4s
deployment.apps/review-shrkga-ui-txcrrz-mongodb 1/1 1 1 5m4s
deployment.apps/review-shrkga-ui-txcrrz-comment 3/3 3 3 5m4s
NAME DESIRED CURRENT READY AGE
replicaset.apps/review-shrkga-ui-txcrrz-post-7494d56db9 3 3 3 5m4s
replicaset.apps/review-shrkga-ui-txcrrz-ui-5f5f94c99d 3 3 3 5m4s
replicaset.apps/review-shrkga-ui-txcrrz-mongodb-867db6966d 1 1 1 5m4s
replicaset.apps/review-shrkga-ui-txcrrz-comment-5bd6445db7 3 3 3 5m4s
NAME DATA AGE
configmap/kube-root-ca.crt 1 5m9s
NAME TYPE DATA AGE
secret/sh.helm.release.v1.review-shrkga-ui-txcrrz.v1 helm.sh/release.v1 1 5m4s
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress.networking.k8s.io/review-shrkga-ui-txcrrz-ui <none> review-shrkga-ui-txcrrz.pages.otus.kga.spb.ru 10.129.0.12 80 5m4s
- Для проекта
reddit-deploy
создан пайплайн деплоя на статичные окруженияstaging
иproduction
;
$ kubectl get all,cm,secret,ing -n staging
NAME READY STATUS RESTARTS AGE
pod/staging-post-76cb7c96fc-cz4d5 1/1 Running 0 3m27s
pod/staging-post-76cb7c96fc-crkqv 1/1 Running 0 3m27s
pod/staging-post-76cb7c96fc-kx9x6 1/1 Running 0 3m27s
pod/staging-mongodb-6f946974ff-475br 1/1 Running 0 3m27s
pod/staging-comment-5f8bf85f78-qvd5n 1/1 Running 0 3m27s
pod/staging-comment-5f8bf85f78-qn775 1/1 Running 0 3m27s
pod/staging-comment-5f8bf85f78-2xgst 1/1 Running 0 3m27s
pod/staging-ui-6c875b7cc9-djk64 1/1 Running 0 3m27s
pod/staging-ui-6c875b7cc9-gm2tg 1/1 Running 0 3m27s
pod/staging-ui-6c875b7cc9-d48gm 1/1 Running 0 3m27s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/staging-ui NodePort 10.43.144.235 <none> 9292:31363/TCP 3m28s
service/staging-comment ClusterIP 10.43.115.57 <none> 9292/TCP 3m28s
service/staging-post ClusterIP 10.43.185.101 <none> 5000/TCP 3m28s
service/staging-mongodb ClusterIP 10.43.118.121 <none> 27017/TCP 3m28s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/staging-post 3/3 3 3 3m28s
deployment.apps/staging-mongodb 1/1 1 1 3m28s
deployment.apps/staging-comment 3/3 3 3 3m28s
deployment.apps/staging-ui 3/3 3 3 3m28s
NAME DESIRED CURRENT READY AGE
replicaset.apps/staging-post-76cb7c96fc 3 3 3 3m28s
replicaset.apps/staging-mongodb-6f946974ff 1 1 1 3m28s
replicaset.apps/staging-comment-5f8bf85f78 3 3 3 3m28s
replicaset.apps/staging-ui-6c875b7cc9 3 3 3 3m28s
NAME DATA AGE
configmap/kube-root-ca.crt 1 36m
NAME TYPE DATA AGE
secret/sh.helm.release.v1.staging.v1 helm.sh/release.v1 1 3m29s
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress.networking.k8s.io/staging-ui <none> staging.pages.otus.kga.spb.ru 10.129.0.12 80 3m28s
$ kubectl get all,cm,secret,ing -n production
NAME READY STATUS RESTARTS AGE
pod/production-comment-fd586fdbd-htpxt 1/1 Running 1 (2m23s ago) 9m39s
pod/production-comment-fd586fdbd-7ljxh 1/1 Running 1 (2m23s ago) 9m39s
pod/production-comment-fd586fdbd-mlfdw 1/1 Running 1 (2m23s ago) 9m39s
pod/production-post-76c7757fcc-9cw5w 1/1 Running 1 (2m23s ago) 9m39s
pod/production-mongodb-56c75875f-dg5t8 1/1 Running 1 (2m23s ago) 9m39s
pod/production-post-76c7757fcc-2w7pr 1/1 Running 1 (2m23s ago) 9m39s
pod/production-ui-7d9c875547-8vtr2 1/1 Running 1 (2m23s ago) 9m39s
pod/production-ui-7d9c875547-dx5zb 1/1 Running 1 (2m23s ago) 9m39s
pod/production-post-76c7757fcc-z5xbq 1/1 Running 1 (2m23s ago) 9m39s
pod/production-ui-7d9c875547-fs6r7 1/1 Running 1 (2m23s ago) 9m39s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/production-mongodb ClusterIP 10.43.74.80 <none> 27017/TCP 9m41s
service/production-ui NodePort 10.43.249.109 <none> 9292:30660/TCP 9m41s
service/production-comment ClusterIP 10.43.212.202 <none> 9292/TCP 9m41s
service/production-post ClusterIP 10.43.126.250 <none> 5000/TCP 9m41s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/production-comment 3/3 3 3 9m40s
deployment.apps/production-mongodb 1/1 1 1 9m40s
deployment.apps/production-post 3/3 3 3 9m40s
deployment.apps/production-ui 3/3 3 3 9m40s
NAME DESIRED CURRENT READY AGE
replicaset.apps/production-comment-fd586fdbd 3 3 3 9m40s
replicaset.apps/production-mongodb-56c75875f 1 1 1 9m40s
replicaset.apps/production-post-76c7757fcc 3 3 3 9m40s
replicaset.apps/production-ui-7d9c875547 3 3 3 9m40s
NAME DATA AGE
configmap/kube-root-ca.crt 1 14m
NAME TYPE DATA AGE
secret/sh.helm.release.v1.production.v1 helm.sh/release.v1 1 9m41s
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress.networking.k8s.io/production-ui <none> production.pages.otus.kga.spb.ru 10.129.0.12 80 9m41s
- Пара скриншотов:
- В Helm все отображается;
$ helm ls -A
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
gitlab gitlab 1 2023-12-29 15:55:56.81478231 +0300 MSK deployed gitlab-7.7.0 v16.7.0
ingress-nginx ingress-nginx 1 2023-12-29 16:07:55.653597855 +0300 MSK deployed ingress-nginx-4.9.0 1.9.5
production production 1 2023-12-29 13:35:06.490380475 +0000 UTC deployed reddit-1.0.0 1.0.0
review-shrkga-ui-txcrrz review 1 2023-12-29 13:22:51.424355148 +0000 UTC deployed reddit-1.0.0 1.0.0
staging staging 1 2023-12-29 13:32:25.09763974 +0000 UTC deployed reddit-1.0.0 1.0.0
yc-k8s gitlab-agent-yc-k8s 4 2023-12-29 16:31:06.973599126 +0300 MSK deployed gitlab-agent-1.22.0 v16.7.0
- Все пайплайны написаны без использования
auto_devops
;
Итоговый пайплайн здесь:
kubernetes/Charts/gitlab-ci/.gitlab-ci-star.yml
Выполнены все основные и дополнительные пункты ДЗ.
- Изучено поведение плагина
kube-dns
при удалении подовkube-dns-autoscaler
иcoredns
; - Создан
LoadBalancer
для сервисаUI
, доступ к приложению успешно заработал поhttp
; - Запущен
Ingress Controller
на базе балансировщикаNginx
(версия из ДЗ не заработала, использовалась версияv1.8.2
);
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.2/deploy/static/provider/cloud/deploy.yaml
- Создан
Single Service Ingress
для сервисаUI
, доступ к приложению успешно заработал поhttp
; - Старый балансировщик
LoadBalancer
удален; - Создан TLS сертификат, на его основе создан
Secret
; - Ingress настроен на прием только HTTPS трафика;
- Доступ к приложению успешно заработал по
https
;
- Secret описан в файле
kubernetes/reddit/ui-secret.yml
;
- Создан объект
NetworkPolicy
для компонентаmongo
; - Доступ к подам с MongoDB разрешен от подов с label'ами
comment
иpost
; - Изучен функционал
PersitentVolume
для хранения данных MongoDB; - В Yandex Cloud создан дисковый ресурс;
- Создан манифест типа
PersitentVolume
для дискового ресурса в Yandex Cloud; - Создан манифест типа
PersistentVolumeClaim
для запроса на выдачу места изPersitentVolume
; - Выделенный диск примонтирован к поду mongo;
- Протестировано создание поста с последующим удалением и созданием деплоя mongo. Пост остался на месте.
Выполнены все основные и дополнительные пункты ДЗ.
- Используется хостовая машина под управлением Ubuntu 22.04.3;
- Установлена утилита
kubectl
; - Установлены утилиты
minikube
; - Успешно запущен Minikube-кластер;
- Изучены формат и содержимое файла
~/.kube/config
; - Созданы манифесты сущностей приложения Reddit в каталоге
kubernetes/reddit
; - Компоненты успешно запущены в
minicube
;
$ kubectl apply -f ./kubernetes/reddit/
- Для связи
ui
сpost
иcomment
созданы объекты типаService
; - Для связи
post
иcomment
сmongodb
посредством именpost-db
иcomment-db
, созданы сервисы с соответствующими именами; - В манифестах деплойментов
post
иcomment
заданы переменные окружения (хост и название БД) для подключения к MongoDB; - Создан Service для UI-компонента для обеспечения доступа к веб-интерфейсу извне;
- Подключен аддон Minikube
dashboard
;
minikube addons enable dashboard
minikube dashboard --url
- Dashboard успешно открылся http://127.0.0.1:43723/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/
- Изучен функционал Namespaces;
- Создано окружение
dev
, в нём запущено наше приложение; - Информация об окружении добавлена внутрь контейнера UI;
- Создан Kubernetes кластер под названием
test-cluster
через веб-интерфейс консоли Yandex Cloud; - Создана группа из двух узлов, входящих в кластер;
- Выполнено подключение к кластеру;
yc managed-kubernetes cluster get-credentials test-cluster --external
- В
test-cluster
созданоdev
namespace, куда задеплоены все компоненты приложенияreddit
; - Приложение успешно открывается по адресу одной из нод в
test-cluster
;
- В каталоге
kubernetes/terraform-k8s
подготовлена конфигурация Terraform для развертывания Kubernetes кластера с использованием ресурсовyandex_kubernetes_cluster
иyandex_kubernetes_node_group
;
- Dashboard UI отсутствует по умолчанию, выполнено его развертывание;
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml
- В каталоге
kubernetes/dashboard
подготовлены манифесты для сущностейServiceAccount
иClusterRoleBinding
для доступа к Dashboard UI;
kubectl apply -f ./kubernetes/dashboard/
- Получен
Bearer Token
дляServiceAccount
;
kubectl -n kubernetes-dashboard create token admin-user
- Запущен
kubectl proxy
; - Dashboard UI открывается через URL http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/
Выполнены все основные и дополнительные пункты ДЗ.
- Описаны Deployment манифесты приложений
comment
,mongo
,post
,ui
; - В YC развернуты две ВМ для master и worker нод кластера Kubernetes;
- С помощью команд
kubeadm init
иkubeadm join
развернут кластер k8s; - Установлен сетевой плагин
Calico
;
wget https://projectcalico.docs.tigera.io/manifests/calico.yaml
sed -i -r -e 's/^(\s*)#\s*(- name: CALICO_IPV4POOL_CIDR)\s*$/\1\2\n\1 value: "10.244.0.0\/16"/g' calico.yaml
kubectl apply -f calico.yaml
- Кластер работает, с помощью команды
kubectl apply -f manifest.yaml
задеплоены поды приложенийcomment
,mongo
,post
,ui
;
- В папке
kubernetes/terraform
подготовлена конфигурация Terraform для развертывания произвольного количества инстансов master и worker нод кластера Kubernetes; - В папке
kubernetes/ansible
подготовлена конфигурация Ansible для развертывания кластера k8s с автоматическим назначением нодам master и worker ролей; - Для предварительной конфигурации хостов написаны (скопипащены) таски отключения свопа, конфигурации параметров
sysctl
для k8s, загрузки модуля ядраbr_netfilter
, настройкиiptables
; - В плейбуке используются роли Ansible
geerlingguy.containerd
иgeerlingguy.kubernetes
, установленные из Ansible-galaxy; - Для сети настраивается плагин
Calico
; - После отработки команды
ansible-playbook -i inventory.yml playbooks/k8s.yml
кластер успешно поднимается;
$ ssh ubuntu@51.250.70.117 sudo kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master-0 Ready control-plane 3m26s v1.28.2
k8s-worker-1 Ready <none> 3m4s v1.28.2
$ ssh ubuntu@51.250.70.117 sudo kubectl get pods --all-namespaces -o wide
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
kube-system calico-kube-controllers-7ddc4f45bc-rtpm5 1/1 Running 0 3m21s 10.244.72.3 k8s-master-0 <none> <none>
kube-system calico-node-4h49c 1/1 Running 0 3m16s 10.128.0.10 k8s-worker-1 <none> <none>
kube-system calico-node-6b9kp 1/1 Running 0 3m21s 10.128.0.32 k8s-master-0 <none> <none>
kube-system coredns-5dd5756b68-692q4 1/1 Running 0 3m21s 10.244.72.1 k8s-master-0 <none> <none>
kube-system coredns-5dd5756b68-lbs9n 1/1 Running 0 3m21s 10.244.72.2 k8s-master-0 <none> <none>
kube-system etcd-k8s-master-0 1/1 Running 0 3m34s 10.128.0.32 k8s-master-0 <none> <none>
kube-system kube-apiserver-k8s-master-0 1/1 Running 0 3m34s 10.128.0.32 k8s-master-0 <none> <none>
kube-system kube-controller-manager-k8s-master-0 1/1 Running 0 3m36s 10.128.0.32 k8s-master-0 <none> <none>
kube-system kube-proxy-2pbdg 1/1 Running 0 3m21s 10.128.0.32 k8s-master-0 <none> <none>
kube-system kube-proxy-hd7dd 1/1 Running 0 3m16s 10.128.0.10 k8s-worker-1 <none> <none>
- Задеплоены поды приложений
comment
,mongo
,post
,ui
, все работает.
# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
comment-deployment-687bccf5fd-hzs5h 1/1 Running 0 2m17s 10.244.230.2 k8s-worker-1 <none> <none>
mongo-deployment-79d69f4666-l6pnm 1/1 Running 0 2m43s 10.244.230.1 k8s-worker-1 <none> <none>
post-deployment-68db465f9c-84dwr 1/1 Running 0 2m12s 10.244.230.3 k8s-worker-1 <none> <none>
ui-deployment-7d84b9f894-8k4dk 1/1 Running 0 2m8s 10.244.230.4 k8s-worker-1 <none> <none>
Выполнены все основные и дополнительные пункты ДЗ.
- Подготовлено окружение:
- Скачана новая ветка reddit;
- Выполнена сборка logging-enabled образов с тэгами
logging
; - В YC создана docker-machine;
- Создан compose-файл для системы логирования ElasticSearch + Fluentd + Kibana;
- Созданы Dockerfile и конфигурации для Fluentd, выполнена сборка образа;
- Изучен сбор структурированных логов с использованием сервиса
post
; - Изучен сбор неструктурированных логов с использованием сервиса
ui
; - Изучены Grok-шаблоны;
- Составлена конфигурация Fluentd для разборки формата логов UI-сервиса с
path
,remote_addr
,method
,response_status
;
$ cat logging/fluentd/fluent.conf
...
<filter service.ui>
@type parser
<parse>
@type grok
<grok>
pattern service=%{WORD:service} \| event=%{WORD:event} \| path=%{GREEDYDATA:path} \| request_id=%{GREEDYDATA:request_id} \| remote_addr=%{IPV4:remote_addr} \| method= %{WORD:method} \| response_status=%{INT:response_status}
</grok>
</parse>
key_name message
# reserve_data true
</filter>
...
- В compose-файл для сервисов логирования добавлен сервис распределенного трейсинга Zipkin;
- Сервисы настроены на использование Zipkin;
- Изучен функционал трейсов через web-интерфейс Zipkin;
- Загружен репозиторий со сломанным кодом приложения в каталог
src-bugged
; - В процессе билда багнутого кода снова посыпались проблемы с тем, что все устарело и ничего не собирается 😡
- Поэтому буду краток: тормоза при посте из-за того, что в багнутом коде присутствует команда
time.sleep(3)
;
$ cat src-bugged/post-py/post_app.py
...
else:
stop_time = time.time() # + 0.3
resp_time = stop_time - start_time
app.post_read_db_seconds.observe(resp_time)
time.sleep(3) # <<<<<<<<<<<<<<< BUG <<<<<<<<<<<<<<<
log_event('info', 'post_find',
'Successfully found the post information',
{'post_id': id})
return dumps(post)
...
Выполнены все основные и дополнительные пункты ДЗ.
- Создан Docker хост в Yandex Cloud, локальное окружение настроено на работу с ним;
- Prometheus запущен из образа
prom/prometheus
; - Изучены метрики по умолчанию;
- Изучен раздел Targets (цели) и формат собираемых метрик, доступных по адресу
host:port/metrics
; - Создан кастомный Docker образ Prometheus на основе собственного файла конфигурации
prometheus.yml
; - Создан
docker-compose.yml
файл для поднятия Prometheus совместно с микросервисамиui
,post
,comment
,mongo_db
; - Изучен функционал Prometheus на основе новых целей и Endpoint'ов наших микросервисов;
- Добавлен сбор метрик Docker хоста при помощи Node exporter:
- Добавлен новый сервис в
docker-compose.yml
; - Добавлен новый Job в
prometheus.yml
;
- Добавлен новый сервис в
- Изучено изменение динамики нагрузки хоста на графике при повышении загруженности CPU
- В Prometheus добавлен мониторинг MongoDB с использованием экспортера
percona/mongodb_exporter
;
$ cat docker/docker-compose.yml
...
mongodb_exporter:
image: percona/mongodb_exporter:0.40
command:
- '--mongodb.uri=mongodb://mongo_db:27017'
- '--compatible-mode'
- '--mongodb.direct-connect=true'
# ports:
# - 9216:9216/tcp
networks:
- back_net
- front_net
depends_on:
- mongo_db
...
$ cat monitoring/prometheus/prometheus.yml
...
- job_name: 'mongodb'
static_configs:
- targets:
- 'mongodb_exporter:9216'
...
- В Prometheus добавлен мониторинг сервисов comment, post, ui с использованием экспортера
prom/blackbox-exporter
; - Собран и запушен на DockerHub кастомный образ с измененным файлом конфигурации
config.yml
;
$ cat monitoring/blackbox/Dockerfile
FROM prom/blackbox-exporter:latest
ADD config.yml /etc/blackbox_exporter/
$ cat monitoring/blackbox/config.yml
modules:
http_2xx:
prober: http
timeout: 5s
http:
valid_http_versions: ["HTTP/1.1", "HTTP/2.0"]
valid_status_codes: []
method: GET
follow_redirects: false
$ cat docker/docker-compose.yml
...
blackbox-exporter:
image: ${USERNAME}/blackbox-exporter
# ports:
# - 9115:9115/tcp
networks:
- front_net
depends_on:
- ui
- post
- comment
...
$ cat monitoring/prometheus/prometheus.yml
...
- job_name: 'blackbox'
metrics_path: /metrics
params:
module: [http_2xx]
static_configs:
- targets:
- http://ui:9292
- http://comment:9292
- http://post:9292
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: blackbox-exporter:9115
...
Итоговый список целей выглядит так:
- Реализованы сценарии билда и пуша в DockerHub любого, или всех сразу, образов;
- Автоматическая генерация справки при запуске
make help
, либо простоmake
без аргументов.
$ cd monitoring/
$ make help
build-all Build all images
build-blackbox Build Blackbox exporter image
build-comment Build Comment image
build-post Build Post image
build-prometheus Build Prometheus exporter image
build-ui Build UI image
help Display this help screen
push-all Push all images to Docker Hub
push-blackbox Push Blackbox exporter image to Docker Hub
push-comment Push Comment image to Docker Hub
push-post Push Post image to Docker Hub
push-prometheus Push Prometheus image to Docker Hub
push-ui Push UI image to Docker Hub
Выполнены все основные и дополнительные пункты ДЗ.
- Облачная инфраструктура описана с использованием подхода IaC;
- В папке
gitlab-ci/infra/terraform
подготовлена конфигурация Terraform для развертывания ВМ в YC; - В папке
gitlab-ci/infra/ansible
подготовлена конфигурация Ansible для установки на ВМDocker
,GitLab CE
иGitLab Runner
:playbooks/docker.yml
-- плейбук для установки докера;playbooks/gitlab-ce.yml
-- плейбук для omnibus-установки гитлаба;playbooks/gitlab-runner.yml
-- пелйбук для установки гитлаб раннера;playbooks/site.yml
-- плейбук для установки всех вышеперечисленных компонентов;
- В файле
gitlab-ci/docker-compose.yml
описана установка gitlab-ce черезdocker compose
; - Запуск через
docker compose up -d
отработал успешно, GitLab поднялся по адресу http://yc-vm-ip/;
- Выполнена автоматизация развёртывания GitLab с помощью модуля Ansible
docker_container
(см. плейбукgitlab-ci/infra/ansible/playbooks/gitlab-ce.yml
);
- В GitLab созданы группа
homework
и проектexample
; - В файле
.gitlab-ci.yml
описан CI/CD Pipeline; - Установлен и зарегистрирован GitLab Runner;
- Пайплайн успешно отработал;
- Тесты в пайплайне изменены в соответствии с ДЗ;
- Определены окружения
dev
,beta
иproduction
; - Определены окружения
stage
иproduction
для выкатывания кода с явно зафиксированной версией (помеченного с помощью тэга в git); - Добавлены динамические окружения для каждой ветки в репозитории, кроме ветки master;
- В этап пайплайна
build
добавлен запуск контейнера с приложениемreddit
; - Контейнер с reddit деплоится на окружение, динамически создаваемое для каждой ветки в GitLab;
build_job:
stage: build
image: docker:latest
environment:
name: branch/${CI_COMMIT_REF_NAME}
script:
- echo 'Building'
- docker build -t reddit:${CI_ENVIRONMENT_SLUG} docker-monolith/
- docker rm -f reddit-${CI_ENVIRONMENT_SLUG}
- docker run --name reddit-${CI_ENVIRONMENT_SLUG} --publish-all --detach reddit:${CI_ENVIRONMENT_SLUG}
- REDDIT_PORT=$(docker port reddit-${CI_ENVIRONMENT_SLUG} 9292/tcp | head -n 1 | awk -F ':' '{print $2}')
- echo "Application URL -- http://${CI_SERVER_HOST}:${REDDIT_PORT}/"
- Выполнена автоматизация развёртывания GitLab Runner с помощью модуля Ansible
docker_container
(см. плейбукgitlab-ci/infra/ansible/playbooks/gitlab-runner.yml
);
$ cd gitlab-ci/infra/terraform/
$ terraform apply -auto-approve=true
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
...
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Outputs:
external_ip_address_docker = [
"51.250.7.91",
]
$ cd ../ansible/
$ ansible-playbook playbooks/site.yml
PLAY [Install Docker] *****************************************************************
TASK [Gathering Facts] ****************************************************************
ok: [51.250.7.91]
TASK [Add Docker GPG apt Key] *********************************************************
changed: [51.250.7.91]
TASK [Add Docker Repository] **********************************************************
changed: [51.250.7.91]
TASK [Update apt and install packages] ************************************************
changed: [51.250.7.91]
TASK [Install Docker Module for Python] ***********************************************
changed: [51.250.7.91]
PLAY [Install GitLab CE] **************************************************************
TASK [Gathering Facts] ****************************************************************
ok: [51.250.7.91]
TASK [Create gitlab-ce container] *****************************************************
changed: [51.250.7.91]
PLAY [Install GitLab Runner] **********************************************************
TASK [Gathering Facts] ****************************************************************
ok: [51.250.7.91]
TASK [Create gitlab-runner container] *************************************************
changed: [51.250.7.91]
PLAY RECAP ****************************************************************************
51.250.7.91 : ok=9 changed=6 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
$ ssh ubuntu@51.250.7.91 sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
07eca80677fb gitlab/gitlab-runner:latest "/usr/bin/dumb-init …" 5 minutes ago Up 5 minutes gitlab-runner
6ee1bedadbce gitlab/gitlab-ce:latest "/assets/wrapper" 5 minutes ago Up 5 minutes (healthy) 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp, 0.0.0.0:2222->22/tcp gitlab-ce
Выполнены все основные и дополнительные пункты ДЗ.
- Изучена работа контейнера с сетевыми драйверами
none
,host
,bridge
; - Проанализирован вывод команды
ifconfig
при запуске контейнера в сетевом пространстве docker-хоста:- Команда выводит состояние активных интерфейсов хостовой машины, т.к. в случае драйвера
host
устраняется сетевая изолированность между контейнером и хостом docker и напрямую используются сетевые ресурсы хоста;
- Команда выводит состояние активных интерфейсов хостовой машины, т.к. в случае драйвера
- Проведен эксперимент многократного запуска контейнера
nginx
с сетьюhost
:docker ps
вывел активное состояние только первого запущенного контейнера. Это связано с тем, что остальные контейнеры не смогли сделать bind на 80 порт, т.к. его занял первый контейнер. Остальные nginx контейнеры выдали ошибку:
nginx: [emerg] bind() to [::]:80 failed (98: Address already in use)
- Исследовано поведение net-namespaces при запуске контейнеров с драйверами
none
иhost
; - Изучен функционал сетевых алиасов при запуске проекта reddit с использованием bridge-сети;
- Изучена работа контейнеров одновременно в нескольких сетях;
- Исследовано поведение сетевого стека Linux при запуске контейнеров с
bridge
сетями; - Исследовано изменение цепочек
iptables
при запуске контейнеров сbridge
сетями;
- Проект reddit описан в файле
docker-compose.yml
; - Файл изменен под кейс с множеством сетей, сетевых алиасов;
docker-compose.yml
параметризирован с помощью переменных окружения, описанных в файле.env
:
COMPOSE_PROJECT_NAME=reddit
UI_PORT=9292
DB_TAG=4
UI_TAG=3.0
COMMENT_TAG=2.0
POST_TAG=1.0
DB_PATH=/data/db/
USERNAME=shrkga
- Базовое имя проекта изменено при помощи переменной
COMPOSE_PROJECT_NAME=reddit
; - Создан файл
docker-compose.override.yml
с целью переопределения инструкцииcommand
контейнеровcomment
иui
, а также пробрасывания папки с кодом с хоста внутрь контейнеров:
version: '3.3'
services:
ui:
volumes:
- ./ui/:/app/
command: ["puma", "--debug", "-w", "2"]
comment:
volumes:
- ./comment/:/app/
command: ["puma", "--debug", "-w", "2"]
post:
volumes:
- ./post-py/:/app/
Выполнены все основные и дополнительные пункты ДЗ.
- Созданы
Dockerfile
для сервисовpost-py
,comment
,ui
; - Собраны образы для всех трех сервисов с тэгом
1.0
; - Сборка
ui
началась не с первого шага по той причине, что начальные шаги сборки идентичны сервисуcomment
, которые уже ранее выполнялись и были закэшированы докером: - Создана bridge-сеть для контейнеров под названием
reddit
; - Контейнеры успешно запушены с указанием сетевых алиасов;
- Сервис доступен по адресу
http://<docker-host-ip>:9292/
; - Т.к. работаем с настолько древним кодом, что уже не существует нужных репозиториев, то для сборки образов на основе ruby:2.2 пришлось подключить архивный репозиторий
deb http://archive.debian.org/debian stretch main
:
FROM ruby:2.2
RUN set -x \
&& echo "deb http://archive.debian.org/debian stretch main" > /etc/apt/sources.list \
&& apt-get update -qq \
&& apt-get install -y build-essential \
&& apt-get clean
- Контейнеры запущены с другими сетевыми алиасами;
- Переменные окружения при этом заданы через параметр
--env
без необходимости пересоздания образа:
docker run -d --network=reddit \
--network-alias=post_db_star --network-alias=comment_db_star \
mongo:4
docker run -d --network=reddit \
--network-alias=post_star \
--env POST_DATABASE_HOST=post_db_star \
shrkga/post:1.0
docker run -d --network=reddit \
--network-alias=comment_star \
--env POST_DATABASE_HOST=comment_db_star \
shrkga/comment:1.0
docker run -d --network=reddit -p 9292:9292 \
--env POST_SERVICE_HOST=post_star \
--env COMMENT_SERVICE_HOST=comment_star \
shrkga/ui:1.0
- Сервис
ui
пересобран с тэгом2.0
на базеubuntu:16.04
; - Сборка началась с первого шага, закешированных действий в данном случае нет;
- Размер образа 2.0 составил 487MB, в отличии от 1.0, который был 998MB;
- Сервис
ui
пересобран с тэгом3.0
на базеalpine:3.14
(крайний образ, в репозиториях которого есть ruby версии 2); - Выполнены дополнительные оптимизации с целью сокращения количества слоев UnionFS и удаления лишних данных из образа:
# shrkga/ui:3.0
FROM alpine:3.14
WORKDIR /app
COPY Gemfile* ./
RUN set -x \
&& apk --no-cache --update add ruby-full ruby-dev build-base \
&& gem install bundler:1.17.2 --no-document \
&& bundle install \
&& apk del ruby-dev build-base
COPY . ./
ENV POST_SERVICE_HOST=post POST_SERVICE_PORT=5000 COMMENT_SERVICE_HOST=comment COMMENT_SERVICE_PORT=9292
EXPOSE 9292/tcp
CMD ["puma"]
- Сервис
comment
пересобран с тэгом2.0
на базеalpine:3.14
, аналогично выполнены дополнительные оптимизации (см.src/comment/Dockerfile
); - Пересборка сервиса
post
на базеalpine:3.9
не принесла результатов, и образ стал даже немного больше. Поэтому оставлен оригинальный образ на базеpython:3.6-alpine
, к которому применены оптимизации с целью сокращения количества слоев UnionFS и удаления лишних данных из образа (см.src/post-py/Dockerfile
); - Итоговые размеры разных версий образов:
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
shrkga/ui 3.0 d04bf139a9ce 14 hours ago 92.6MB
shrkga/ui 2.0 51d523797874 15 hours ago 487MB
shrkga/ui 1.0 014be69f7086 16 hours ago 998MB
shrkga/comment 2.0 ee448af09ab0 15 hours ago 89.4MB
shrkga/comment 1.0 7523ae8028e8 16 hours ago 996MB
shrkga/post 2.0 1ea0d0e474ce 15 hours ago 69.8MB
shrkga/post 1.0 658e947326f0 16 hours ago 67.2MB
- Создан Docker volume
reddit_db
и подключен в контейнер с MongoDB по пути/data/db
; - После перезапуска контейнеров написанный пост остался на месте;
- Финальный набор команд такой:
docker build -t shrkga/post:1.0 ./post-py
docker build -t shrkga/comment:2.0 ./comment
docker build -t shrkga/ui:3.0 ./ui
docker network create reddit
docker run -d --network=reddit --network-alias=post_db --network-alias=comment_db \
-v reddit_db:/data/db \
mongo:4
docker run -d --network=reddit --network-alias=post shrkga/post:1.0
docker run -d --network=reddit --network-alias=comment shrkga/comment:2.0
docker run -d --network=reddit -p 9292:9292 shrkga/ui:3.0
Выполнены все основные и дополнительные пункты ДЗ.
- Установлены Docker, docker-compose, docker-machine;
- Запущен контейнер
hello-world
; - Изучены и выполнены основные команды docker;
- На основе вывода команд описаны отличия контейнера от образа в файле
/docker-monolith/docker-1.log
;
- Установлен и инициализирован Yandex Cloud CLI;
- Создан инстанс в YC;
- Инициализировано окружение Docker через
docker-machine
; - Повторена практика из демо на лекции;
- Создана требуемая структура репозитория;
- Выполнена сборка образа
reddit:latest
; - На инстансе в YC запущен контейнер
reddit
; - По ссылке http://<IP_адрес_инстанса>:9292 успешно открылось приложение;
- Выполнена регистрация в Docker Hub;
- Выполнена docker аутентификация на Docker Hub;
- Созданный образ загружен на Docker Hub с тэгом
shrkga/otus-reddit:1.0
; - Выполнена проверка запуска контейнера в локальном докере на другом хосте;
- Выполнены все дополнительные проверки, указанные в ДЗ;
Задание со ⭐: автоматизация поднятие нескольких инстансов в Yandex Cloud, установка на них докера и запуск там образа shrkga/otus-reddit:1.0
- Задача реализована в виде прототипа в директории
/docker-monolith/infra/
; - Создан шаблон Packer, который делает образ с уже установленным Docker;
- Используется провеженер
ansible
, для установки докера и модуля python написан плейбукansible/playbooks/packer_docker.yml
; - Данный плейбук может использоваться для развертывания с помощью ansible, если необходимо сделать это не при помощи packer;
- Используется провеженер
- Инстансы поднимаются с помощью Terraform, их количество задается переменной
docker_count
;- Развертывание инстансов реализовано через модуль
terraform/modules/docker
;
- Развертывание инстансов реализовано через модуль
- Написаны несколько плейбуков Ansible с использованием динамического инвентори для установки докера и запуска там образа приложения;
- Приложение успешно поднимается в инстансах и доступно по адресу http://<IP_адрес_инстанса>:9292