Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
Denis Ponizovskii committed Nov 9, 2023
0 parents commit 3273c77
Show file tree
Hide file tree
Showing 104 changed files with 29,453 additions and 0 deletions.
26 changes: 26 additions & 0 deletions .gitignore
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
58 changes: 58 additions & 0 deletions .gitlab-ci.yml
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
105 changes: 105 additions & 0 deletions README.md
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 для хранения секретов
67 changes: 67 additions & 0 deletions backend/.gitlab-ci.yml
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

11 changes: 11 additions & 0 deletions backend/Dockerfile
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"]
87 changes: 87 additions & 0 deletions backend/cmd/api/app/app.go
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,
},
)
}
Loading

0 comments on commit 3273c77

Please sign in to comment.