-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Denis Ponizovskii
committed
Nov 9, 2023
0 parents
commit 3273c77
Showing
104 changed files
with
29,453 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# Binaries for programs and plugins | ||
*.exe | ||
*.exe~ | ||
*.dll | ||
*.so | ||
*.dylib | ||
|
||
# Test binary, built with `go test -c` | ||
*.test | ||
|
||
# Output of the go coverage tool, specifically when used with LiteIDE | ||
*.out | ||
|
||
# Dependency directories (remove the comment below to include it) | ||
vendor/ | ||
.idea/ | ||
.vscode/ | ||
.DS_Store | ||
|
||
**/.terraform/* | ||
*.tfstate | ||
*.tfstate.* | ||
*.hcl | ||
*.tfvars | ||
.terraformrc | ||
terraform.rc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
stages: | ||
- module-pipelines | ||
- deploy | ||
|
||
frontend: | ||
stage: module-pipelines | ||
trigger: | ||
include: | ||
- "/frontend/.gitlab-ci.yml" | ||
strategy: depend | ||
only: | ||
changes: | ||
- frontend/**/* | ||
|
||
backend: | ||
stage: module-pipelines | ||
trigger: | ||
include: | ||
- "/backend/.gitlab-ci.yml" | ||
strategy: depend | ||
only: | ||
changes: | ||
- backend/**/* | ||
|
||
charts: | ||
stage: module-pipelines | ||
trigger: | ||
include: | ||
- "/infrastructure/momo-store-chart/.gitlab-ci.yml" | ||
strategy: depend | ||
only: | ||
changes: | ||
- infrastructure/momo-store-chart/**/* | ||
|
||
|
||
deploy-to-prod: | ||
stage: deploy | ||
image: alpine/helm:3.10.0 | ||
|
||
when: manual | ||
#rules: | ||
# - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' | ||
# when: manual | ||
# - if: '$CI_COMMIT_BRANCH == "main"' | ||
# when: manual | ||
|
||
before_script: | ||
- mkdir -p ~/.kube | ||
- chmod 600 ~/.kube | ||
- echo "$KUBECONFIG" > ~/.kube/config | ||
- cat ~/.kube/config | ||
- chmod 600 ~/.kube/config | ||
- ls -alh ~/.kube | ||
|
||
script: | ||
- cd infrastructure/momo-store-chart | ||
- helm upgrade --install --atomic momo-store . | ||
- rm ~/.kube/config |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
# Momo Store aka Пельменная №2 | ||
|
||
<img width="900" alt="image" src="https://user-images.githubusercontent.com/9394918/167876466-2c530828-d658-4efe-9064-825626cc6db5.png"> | ||
|
||
## Frontend | ||
|
||
```bash | ||
npm install | ||
NODE_ENV=production VUE_APP_API_URL=http://localhost:8081 npm run serve | ||
|
||
``` | ||
|
||
``` | ||
## Backend | ||
```bash | ||
go run ./cmd/api | ||
go test -v ./... | ||
``` | ||
|
||
## Приложение [Momo-store](https://momo-store.lightstandart.com/) | ||
|
||
## CI/CD | ||
|
||
- используется единый [репозиторий](https://gitlab.praktikum-services.ru/d.ponizovskiy/momo-store) | ||
- развертывание приложение осуществляется с использованием [Downstream pipeline] | ||
- при изменениях в соответствующих директориях триггерятся pipeline для backend, frontend и infrastructure (momo-store-chart) | ||
- backend и frontend проходят этапы сборки, тестирования, релиза | ||
- momo-store-helm проходит этапы релиза и деплоя в prod-окружение (k8s) | ||
|
||
## Versioning | ||
|
||
- мажорные и минорные версии приложения изменяются вручную в файлах `backend/.gitlab-ci.yaml` и `frontend/.gitlab-ci.yaml` в переменной `VERSION` | ||
- патч-версии изменяются автоматически на основе переменной `CI_PIPELINE_ID` | ||
- для инфраструктуры мажорные и минорные версии меняются в в файле `infrastructure/momo-store-chart/Chart.yaml` приложения изменяется автоматически на основе переменной `CI_PIPELINE_ID` | ||
|
||
## Infrastructure | ||
|
||
- код ---> [Gitlab](https://gitlab.praktikum-services.ru/) | ||
- helm-charts ---> [Nexus](https://nexus.praktikum-services.ru/) | ||
- анализ кода ---> [SonarQube](https://sonarqube.praktikum-services.ru/) | ||
- docker-images ---> [Gitlab Container Registry](https://gitlab.praktikum-services.ru/d.ponizovksiy/momo-store/container_registry) | ||
- терраформ бэкэнд и статика ---> [Yandex Object Storage](https://cloud.yandex.ru/services/storage) | ||
- продакшн ---> [Yandex Managed Service for Kubernetes](https://cloud.yandex.ru/services/managed-kubernetes) | ||
|
||
## Init kubernetes | ||
|
||
- клонировать репозиторий на машину с установленным terraform | ||
- через консоль Yandex Cloud создать сервисный аккаунт с ролью `editor`, получить статический ключ доступа, сохранить секретный ключ в файле `infrastructure/terraform/backend.tfvars` | ||
``` | ||
#Keys for service account | ||
access_key="........." | ||
secret_key="........." | ||
``` | ||
- получить [iam-token](https://cloud.yandex.ru/docs/iam/operations/iam-token/create) | ||
- сохранить [iam-token] [cloud_id] [folder_id] [network_zone] в файле `infrastructure/terraform/terraform.tfvars` | ||
|
||
- через консоль Yandex Cloud создать Object Storage, внести параметры подключения в файл `infrastructure/terraform/provider.tf` | ||
- выполнить следующие комманды: | ||
``` | ||
cd infrastructure/terraform | ||
terraform init -backend-config=backend.tfvars | ||
terraform apply | ||
``` | ||
|
||
## Init production | ||
|
||
# устанавливаем cert-manager | ||
``` | ||
cd infrastructure/momo-store-chart/ | ||
helm repo add jetstack https://charts.jetstack.io | ||
helm repo update | ||
helm upgrade --install --atomic -n default cert-manager jetstack/cert-manager --version v1.9.1 --set installCRDs=true | ||
``` | ||
|
||
# получаем kubeconfig | ||
``` | ||
yc managed-kubernetes cluster get-credentials momo-store-k8s-cluster --external | ||
``` | ||
|
||
# устанавливаем ingress-controller | ||
``` | ||
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx | ||
helm repo update | ||
helm install ingress-nginx ingress-nginx/ingress-nginx | ||
``` | ||
|
||
# устанавливаем приложение | ||
``` | ||
helm upgrade --install --atomic -n default momo-store . | ||
``` | ||
|
||
# смотрим IP load balancer, прописываем А-записи для приложения и мониторинга | ||
``` | ||
kubectl get svc | ||
``` | ||
|
||
|
||
## Backlog | ||
|
||
- развернуть мониторинг состояния кластера и приложения | ||
- добавить тестовое окружение (отдельная ВМ, отдельный кластер или отдельный namespace) | ||
- вывести мониторинг из чарта самого приложения (ускорить деплой) | ||
- поднять Vault для хранения секретов |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
# В нашем Gitlab для сборки контейнеров воспользуемся Докером в Докере :) | ||
# https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#use-the-kubernetes-executor-with-docker-in-docker | ||
# Для сборки образов с использованием Docker-in-Docker: | ||
# добавить в код Downstream пайплайнов в секцию include подготовленный шаблон, содержащий необходимые настройки: | ||
# https://gitlab.praktikum-services.ru/templates/ci/-/blob/main/DockerInDockerTemplate.yml | ||
# использовать в задачах сборки в качестве образа стабильную версию образа Docker:dind docker:20.10.12-dind-rootless | ||
# | ||
|
||
include: | ||
- project: 'templates/ci' | ||
file: 'DockerInDockerTemplate.yml' | ||
|
||
variables: | ||
VERSION: 1.0.${CI_PIPELINE_ID} | ||
|
||
stages: | ||
- build | ||
- test | ||
- release | ||
|
||
build-backend: | ||
stage: build | ||
image: docker:20.10.12-dind-rootless | ||
before_script: | ||
- until docker info; do sleep 1; done | ||
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY | ||
script: | ||
- cd backend | ||
- > | ||
docker build | ||
--build-arg VERSION=$VERSION | ||
--tag $CI_REGISTRY_IMAGE/momo-backend:$VERSION | ||
. | ||
- docker push $CI_REGISTRY_IMAGE/momo-backend:$VERSION | ||
|
||
unit-test: | ||
stage: test | ||
image: golang:1.17 | ||
script: | ||
- cd backend | ||
- go test -v ./... | ||
|
||
sonarqube-backend-test: | ||
stage: test | ||
image: | ||
name: sonarsource/sonar-scanner-cli:latest | ||
script: | ||
- cd backend | ||
- > | ||
sonar-scanner -Dsonar.qualitygate.wait=true | ||
-Dsonar.projectKey=${KEY_BACK_SONAR} | ||
-Dsonar.host.url=${URL_SONAR} | ||
-Dsonar.login=${LOGIN_BACK_SONAR} | ||
upload-backend-latest: | ||
variables: | ||
GIT_STRATEGY: none | ||
image: docker:20.10.12-dind-rootless | ||
stage: release | ||
before_script: | ||
- until docker info; do sleep 1; done | ||
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY | ||
script: | ||
- docker pull $CI_REGISTRY_IMAGE/momo-backend:$VERSION | ||
- docker tag $CI_REGISTRY_IMAGE/momo-backend:$VERSION $CI_REGISTRY_IMAGE/momo-backend:latest | ||
- docker push $CI_REGISTRY_IMAGE/momo-backend:latest | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
FROM golang:1.20-alpine as builder | ||
WORKDIR /build | ||
COPY . . | ||
RUN go mod download | ||
RUN CGO_ENABLED=0 GOOS=linux go build -o /main ./cmd/api | ||
|
||
FROM alpine:3.18 | ||
|
||
COPY --from=builder /main /bin/main | ||
EXPOSE 8081 | ||
ENTRYPOINT ["/bin/main"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
package app | ||
|
||
import ( | ||
"net/http" | ||
|
||
"github.com/prometheus/client_golang/prometheus" | ||
"github.com/prometheus/client_golang/prometheus/promhttp" | ||
|
||
"gitlab.praktikum-services.ru/Stasyan/momo-store/internal/store/dumplings" | ||
) | ||
|
||
// Instance represents API app instance | ||
type Instance struct { | ||
store dumplings.Store | ||
|
||
// metrics | ||
metricsRegistry *prometheus.Registry | ||
responseTimings *prometheus.HistogramVec | ||
ordersCounter prometheus.Counter | ||
requestCounter prometheus.Counter | ||
dumplingsListingCounter *prometheus.CounterVec | ||
} | ||
|
||
// NewInstance returns new app instance | ||
func NewInstance(store dumplings.Store) (*Instance, error) { | ||
metricsRegistry := prometheus.NewRegistry() | ||
|
||
responseTimingsHistogram := prometheus.NewHistogramVec( | ||
prometheus.HistogramOpts{ | ||
Name: "response_timing_ms", | ||
Help: "Response timings in milliseconds", | ||
Buckets: prometheus.LinearBuckets(0, 50, 10), | ||
}, | ||
[]string{"handler"}, | ||
) | ||
|
||
dumplingsListingCounter := prometheus.NewCounterVec( | ||
prometheus.CounterOpts{ | ||
Name: "dumplings_listing_count", | ||
Help: "Number of times dumplings pack has been listed", | ||
}, | ||
[]string{"id"}, | ||
) | ||
|
||
ordersCounter := prometheus.NewCounter( | ||
prometheus.CounterOpts{ | ||
Name: "orders_count", | ||
Help: "Number of dumplings orders", | ||
}, | ||
) | ||
requestCounter := prometheus.NewCounter( | ||
prometheus.CounterOpts{ | ||
Name: "requests_count", | ||
Help: "Number of HTTP requests made", | ||
}, | ||
) | ||
|
||
// register metrics | ||
metricsRegistry.MustRegister(responseTimingsHistogram) | ||
metricsRegistry.MustRegister(ordersCounter) | ||
metricsRegistry.MustRegister(requestCounter) | ||
metricsRegistry.MustRegister(dumplingsListingCounter) | ||
|
||
return &Instance{ | ||
store: store, | ||
|
||
metricsRegistry: metricsRegistry, | ||
responseTimings: responseTimingsHistogram, | ||
ordersCounter: ordersCounter, | ||
requestCounter: requestCounter, | ||
dumplingsListingCounter: dumplingsListingCounter, | ||
}, nil | ||
} | ||
|
||
func (i *Instance) HealthcheckController(w http.ResponseWriter, _ *http.Request) { | ||
w.WriteHeader(http.StatusOK) | ||
} | ||
|
||
func (i *Instance) MetricsHandler() http.Handler { | ||
return promhttp.HandlerFor( | ||
i.metricsRegistry, | ||
promhttp.HandlerOpts{ | ||
// Opt into OpenMetrics to support exemplars. | ||
EnableOpenMetrics: true, | ||
}, | ||
) | ||
} |
Oops, something went wrong.