mirror of
https://github.com/slurm-personal/school-dev-k8s.git
synced 2026-06-27 13:50:24 +00:00
@@ -1,70 +0,0 @@
|
||||
# Подготовка кластера
|
||||
|
||||
## 1. Создаем ns и RBAC
|
||||
|
||||
Для этого запускаем скрипт `setup.sh`, перед запуском `<Ваш номер логина> меняем на свой номер студента!!`.
|
||||
|
||||
```bash
|
||||
bash ~/slurm/practice/14.ci-cd/1.1.prepare_cluster/setup.sh s<Ваш номер логина>-xpaste production
|
||||
```
|
||||
|
||||
В конце своего выполнения скрипт выдаст нам токен, который необходимо сохранить.
|
||||
|
||||
## 2. Создание variables в gitlab
|
||||
|
||||
Для доступа из Gitlab в Kubernetes нам необходимо добавить в Gitlab переменную, в которой будет содержаться токен с предыдущего шага.
|
||||
|
||||
* Переходим в Gitlab
|
||||
|
||||
Для этого открываем в браузере свой форк xpaste. `<Ваш номер логина> меняем на свой номер студента`:
|
||||
|
||||
```bash
|
||||
https://gitlab.slurm.io/s<Ваш номер логина>/xpaste
|
||||
```
|
||||
|
||||
* Добавляем переменную
|
||||
|
||||
Для этого в левом меню находим `Settings -> CI/CD -> Variables` и нажимаем Expand. Жмем кнопку `Add Variable` и в поле `Key` вводим имя переменной:
|
||||
|
||||
```bash
|
||||
K8S_CI_TOKEN
|
||||
```
|
||||
|
||||
В поле `Value` вводим скопированный токен из вывода команды setup.sh (пункт 1) и нажимаем `Add Variable`.
|
||||
|
||||
## 3. Создаем token для доступа в registry
|
||||
|
||||
Для этого переходим в раздел `Settings -> Repository -> Deploy tokens` и нажимаем Expand.
|
||||
|
||||
В поле `Name` вводим
|
||||
|
||||
```bash
|
||||
k8s-pull-token
|
||||
```
|
||||
|
||||
Cтавим галочку рядом с `read_registry`. Все остальные поля оставляем пустыми. Нажимаем `Create deploy token`.
|
||||
|
||||
```!!НЕ ЗАКРЫВАЕМ ОКНО БРАУЗЕРА!!```
|
||||
|
||||
## 4. Создаем secret в kubernetes
|
||||
|
||||
Создаем secret, который будет использоваться для image pull. Для этого возвращаемся на первый master и выполняем команду:
|
||||
Вносим нужные данные в скрипт `docker_pull_secret.sh` и запускаем его:
|
||||
|
||||
Соответственно подставляя на место `<>` нужные параметры, которые получили на `шаге 3`.
|
||||
|
||||
```bash
|
||||
vim docker_pull_secret.sh
|
||||
./docker_pull_secret.sh
|
||||
```
|
||||
|
||||
## 6. Создание секрета для приложения
|
||||
|
||||
Создаем секрет, из которого при деплое будут взяты значения для переменных окружения, таких как доступы к БД и секретный ключ.
|
||||
Вносим нужные данные в скрипт xpaste_secret.sh и запускаем его:
|
||||
|
||||
```bash
|
||||
vim xpaste_secret.sh
|
||||
./xpaste_secret.sh
|
||||
```
|
||||
`secret-key-base xxxxxxxxxxxxx` это не плэйсхолдер. Можно так и оставить.
|
||||
@@ -1,12 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
NS=s<Ваш номер логина>-xpaste-production
|
||||
|
||||
kubectl delete secret xpaste-gitlab-registry --namespace "$NS"
|
||||
|
||||
kubectl create secret docker-registry xpaste-gitlab-registry \
|
||||
--docker-server registry.slurm.io \
|
||||
--docker-email 'student@slurm.io' \
|
||||
--docker-username '<первая строчка из окна создания токена в gitlab>' \
|
||||
--docker-password '<вторая строчка из окна создания токена в gitlab>' \
|
||||
--namespace "$NS"
|
||||
@@ -1,95 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
CI_PROJECT_PATH_SLUG=$1
|
||||
CI_ENVIRONMENT_NAME=$2
|
||||
|
||||
|
||||
GREEN='\033[0;32m'
|
||||
NC='\033[0m'
|
||||
|
||||
|
||||
usage() {
|
||||
echo "Usage: $0 CI_PROJECT_PATH_SLUG CI_ENVIRONMENT_NAME"
|
||||
}
|
||||
|
||||
base64_decode_key() {
|
||||
if [[ "$OSTYPE" == "linux"* ]]; then
|
||||
echo "-d"
|
||||
elif [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
echo "-D"
|
||||
else
|
||||
echo "--help"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
if [ -z "$CI_PROJECT_PATH_SLUG" ] || [ -z "$CI_ENVIRONMENT_NAME" ]; then
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
NS="$CI_PROJECT_PATH_SLUG-$CI_ENVIRONMENT_NAME"
|
||||
SA="$CI_PROJECT_PATH_SLUG-$CI_ENVIRONMENT_NAME"
|
||||
ROLE="$CI_PROJECT_PATH_SLUG-$CI_ENVIRONMENT_NAME"
|
||||
ROLEBIND="$CI_PROJECT_PATH_SLUG-$CI_ENVIRONMENT_NAME"
|
||||
|
||||
if kubectl get ns "$NS"; then
|
||||
echo -e "${GREEN}namespace for project already exists${NC}"
|
||||
else
|
||||
echo -e "${GREEN}creating namespace for project${NC}"
|
||||
kubectl create namespace "$NS"
|
||||
echo
|
||||
fi
|
||||
|
||||
if kubectl -n "$NS" get sa "$SA"; then
|
||||
echo -e "${GREEN}serviceaccount for project already exists${NC}"
|
||||
else
|
||||
echo
|
||||
echo -e "${GREEN}creating CI serviceaccount for project${NC}"
|
||||
kubectl create serviceaccount \
|
||||
--namespace "$NS" \
|
||||
"$SA"
|
||||
echo
|
||||
fi
|
||||
|
||||
if kubectl -n "$NS" get role "$ROLE"; then
|
||||
echo -e "${GREEN}role for project already exists${NC}"
|
||||
else
|
||||
echo -e "${GREEN}creating CI role for project${NC}"
|
||||
cat << EOF | kubectl apply --namespace $NS -f -
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: "$ROLE"
|
||||
rules:
|
||||
- apiGroups: ["", "extensions", "apps", "batch", "events", "certmanager.k8s.io", "cert-manager.io", "monitoring.coreos.com"]
|
||||
resources: ["*"]
|
||||
verbs: ["*"]
|
||||
EOF
|
||||
echo
|
||||
fi
|
||||
|
||||
if kubectl -n "$NS" get rolebinding "$ROLEBIND"; then
|
||||
echo -e "${GREEN}rolebinding for project already exists${NC}"
|
||||
else
|
||||
echo -e "${GREEN}creating CI rolebinding for project${NC}"
|
||||
kubectl create rolebinding \
|
||||
--namespace "$NS" \
|
||||
--serviceaccount "$NS":"$SA" \
|
||||
--role "$ROLE" \
|
||||
"$ROLEBIND"
|
||||
echo
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}access token for new CI user:${NC}"
|
||||
kubectl get secret \
|
||||
--namespace "$NS" \
|
||||
$( \
|
||||
kubectl get serviceaccount \
|
||||
--namespace "$NS" \
|
||||
"$SA" \
|
||||
-o jsonpath='{.secrets[].name}'\
|
||||
) \
|
||||
-o jsonpath='{.data.token}' | base64 $(base64_decode_key)
|
||||
echo
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
NS=s<Ваш номер логина>-xpaste-production
|
||||
|
||||
kubectl delete secret slurm-xpaste --namespace "$NS"
|
||||
|
||||
kubectl create secret generic slurm-xpaste \
|
||||
--from-literal secret-key-base=xxxxxxxxxxxxxxxxxxxxxxxxx \
|
||||
--from-literal db-user='s<Ваш номер логина>' \
|
||||
--from-literal db-password='<Ваш пароль от логина>' \
|
||||
--namespace "$NS"
|
||||
@@ -1,65 +0,0 @@
|
||||
variables:
|
||||
K8S_API_URL: https://172.20.100.2:6443
|
||||
|
||||
stages:
|
||||
- build
|
||||
- test
|
||||
- cleanup
|
||||
- push
|
||||
- deploy
|
||||
|
||||
build:
|
||||
stage: build
|
||||
script:
|
||||
- docker build -t $CI_REGISTRY/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME:$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID .
|
||||
|
||||
test:
|
||||
stage: test
|
||||
image:
|
||||
name: docker/compose:1.27.4
|
||||
entrypoint: [""]
|
||||
script:
|
||||
- docker-compose
|
||||
-p "$CI_PROJECT_NAME"_"$CI_PIPELINE_ID"
|
||||
up
|
||||
--abort-on-container-exit
|
||||
--exit-code-from app
|
||||
--quiet-pull
|
||||
|
||||
cleanup:
|
||||
stage: cleanup
|
||||
image:
|
||||
name: docker/compose:1.27.4
|
||||
entrypoint: [""]
|
||||
script:
|
||||
- docker-compose -p "$CI_PROJECT_NAME"_"$CI_PIPELINE_ID" down
|
||||
when: always
|
||||
|
||||
push:
|
||||
stage: push
|
||||
before_script:
|
||||
- docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN $CI_REGISTRY
|
||||
script:
|
||||
- docker push $CI_REGISTRY/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME:$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID
|
||||
only:
|
||||
- master
|
||||
|
||||
deploy:
|
||||
stage: deploy
|
||||
image: centosadmin/kubernetes-helm:3.3.4
|
||||
environment:
|
||||
name: production
|
||||
resource_group: deploy_production
|
||||
script:
|
||||
- kubectl config set-cluster k8s --insecure-skip-tls-verify=true --server=$K8S_API_URL
|
||||
- kubectl config set-credentials ci --token=$K8S_CI_TOKEN
|
||||
- kubectl config set-context ci --cluster=k8s --user=ci
|
||||
- kubectl config use-context ci
|
||||
- helm upgrade --install $CI_PROJECT_PATH_SLUG .helm
|
||||
--set image=$CI_REGISTRY/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME
|
||||
--set imageTag=$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID
|
||||
--debug
|
||||
--namespace $CI_PROJECT_PATH_SLUG-$CI_ENVIRONMENT_NAME
|
||||
only:
|
||||
- master
|
||||
|
||||
@@ -1,108 +0,0 @@
|
||||
# Добавляем конфиг CI/CD в Gitlab
|
||||
|
||||
В этой части добавляем последний шаг - конфиг для Gitlab CI/CD для сборки, тестирования и деплоя приложения в кластер k8s. Деплой производится с использованием утилиты Helm v3.
|
||||
|
||||
Gitlab CI/CD описывается в файле `.gitlab-ci.yml` в формате `yaml`. По умолчанию Gitlab ищет этот файл в корне проекта, путь до файла может быть переопределен в настройках проекта.
|
||||
|
||||
## 1. Подготавливаем CI/CD
|
||||
|
||||
Для этого скопируем заранее подготовленный шаблон `.gitlab-ci.yml` в проект `xpaste`, выполнив команду:
|
||||
|
||||
```bash
|
||||
cp ~/slurm/practice/14.ci-cd/1.2.deploy/.gitlab-ci.yml ~/xpaste/
|
||||
```
|
||||
|
||||
## 2. Адрес Kubernetes API
|
||||
|
||||
В файле `.gitlab-ci.yml` указан IP-адрес нашего общего kube api.
|
||||
|
||||
## 3. Настройка базы данных
|
||||
|
||||
Сервер базы данных общий для всех студентов, каждому студенту выделена своя база данных.
|
||||
Логин и пароль для доступа к БД мы указывали при создании секрета, а в параметрах чарта укажен название БД.
|
||||
|
||||
Для этого откроем `values.yaml`:
|
||||
|
||||
```bash
|
||||
vi ~/xpaste/.helm/values.yaml
|
||||
```
|
||||
|
||||
В начале файла необходимо заменить строку `<Ваш номер логина> - меняем на свой номер студента!!`:
|
||||
|
||||
```diff
|
||||
- DB_NAME: <номер своего логина>_xpaste
|
||||
+ DB_NAME: s000001_xpaste
|
||||
```
|
||||
|
||||
|
||||
## 3. Настройка ingress
|
||||
|
||||
Доступ к приложению будет осуществляться через ingress. Ingress устанавливается вместе с приложением, но для его корректной работы необходимо прописать ему адрес.
|
||||
Для этого откроем `values.yaml`:
|
||||
|
||||
```bash
|
||||
vi ~/xpaste/.helm/values.yaml
|
||||
```
|
||||
|
||||
В конце файла необходимо заменить строку `<Ваш номер логина> - меняем на свой номер студента!!`:
|
||||
|
||||
```diff
|
||||
- host: xpaste.s<Ваш номер логина>.mcs.slurm.io
|
||||
+ host: xpaste.s000001.mcs.slurm.io
|
||||
```
|
||||
|
||||
Сохраняем все изменения и пушим их в gitlab. Для этого необходимо выполнить команды:
|
||||
|
||||
```bash
|
||||
cd ~/xpaste
|
||||
git add .
|
||||
git commit -am "Add CI/CD config"
|
||||
git push
|
||||
```
|
||||
|
||||
## 4. Переключаемся в namespace приложения
|
||||
|
||||
До сих пор мы работали в неймспейсе кластера Kubernetes с названием `s<номер_студента>`
|
||||
|
||||
Но наше приложение xpaste устанавливается в другой namespace `s<номер_студента>-xpaste-production`.
|
||||
Для удобства работы, чтобы не набирать каждый раз опцию `--namespace` изменим namespace, который kubectl использует по умолчанию:
|
||||
|
||||
```bash
|
||||
kubectl config set-context --current --namespace=s<номер_студента>-xpaste-production
|
||||
```
|
||||
|
||||
## 5. Проверка результата
|
||||
|
||||
Для проверки результата необходимо перейти в Gitlab в раздел `ci/cd -> pipelines` форка проекта xpaste.
|
||||
Можно воспользоваться прямой ссылкой: `https://gitlab.slurm.io/sXXXXXX/xpaste/pipelines`. `sXXXXXX` необходимо заменить на номер своего студента.
|
||||
|
||||
В результате все job должны закончиться без ошибок.
|
||||
|
||||
## 6.Открываем приложение в браузере
|
||||
|
||||
В браузере открываем URL: http://xpaste.s<Ваш номер логина>.mcs.slurm.io. `<Ваш номер логина>` необходимо заменить на номер своего студента. Открывать нужно в режиме `инкогнито`.
|
||||
|
||||
Если вы увидели `503` ошибку, значит практику выполнили верно.
|
||||
|
||||
## 7. Самостоятельная работа
|
||||
|
||||
Самостоятельная работа продолжительностью 5 минут. Во время самостоятельной работы надо попробовать ответить на вопросы:
|
||||
|
||||
* Почему деплой закончился успешно, а приложение недоступно?
|
||||
* Что надо исправить в CI/CD ?
|
||||
* Что надо исправить в приложении или его настройках ?
|
||||
|
||||
Ошибку пока исправлять не надо.
|
||||
|
||||
## 8. Доработка CI/CD
|
||||
|
||||
* Для корректировки поведения CI/CD необходимо внести изменения в ci/cd, описанные в [snippet](https://gitlab.slurm.io/-/snippets/107)
|
||||
|
||||
Удаляем установленный релиз helm чарта:
|
||||
|
||||
```bash
|
||||
helm delete s<номер_студента>-xpaste
|
||||
```
|
||||
Далее пушим изменения и смотрим за процессом CI/CD.
|
||||
|
||||
После внесения изменений процесс деплоя должен завершиться с ошибкой.
|
||||
@@ -1,70 +0,0 @@
|
||||
variables:
|
||||
K8S_API_URL: https://172.20.100.2:6443
|
||||
|
||||
stages:
|
||||
- build
|
||||
- test
|
||||
- cleanup
|
||||
- push
|
||||
- deploy
|
||||
|
||||
build:
|
||||
stage: build
|
||||
script:
|
||||
- docker build -t $CI_REGISTRY/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME:$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID .
|
||||
|
||||
test:
|
||||
stage: test
|
||||
image:
|
||||
name: docker/compose:1.27.4
|
||||
entrypoint: [""]
|
||||
script:
|
||||
- docker-compose
|
||||
-p "$CI_PROJECT_NAME"_"$CI_PIPELINE_ID"
|
||||
up
|
||||
--abort-on-container-exit
|
||||
--exit-code-from app
|
||||
--quiet-pull
|
||||
|
||||
cleanup:
|
||||
stage: cleanup
|
||||
image:
|
||||
name: docker/compose:1.27.4
|
||||
entrypoint: [""]
|
||||
script:
|
||||
- docker-compose -p "$CI_PROJECT_NAME"_"$CI_PIPELINE_ID" down
|
||||
when: always
|
||||
|
||||
push:
|
||||
stage: push
|
||||
before_script:
|
||||
- docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN $CI_REGISTRY
|
||||
script:
|
||||
- docker push $CI_REGISTRY/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME:$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID
|
||||
only:
|
||||
- master
|
||||
|
||||
deploy:
|
||||
stage: deploy
|
||||
image: centosadmin/kubernetes-helm:3.3.4
|
||||
environment:
|
||||
name: production
|
||||
resource_group: deploy_production
|
||||
script:
|
||||
- kubectl config set-cluster k8s --insecure-skip-tls-verify=true --server=$K8S_API_URL
|
||||
- kubectl config set-credentials ci --token=$K8S_CI_TOKEN
|
||||
- kubectl config set-context ci --cluster=k8s --user=ci
|
||||
- kubectl config use-context ci
|
||||
- helm upgrade --install $CI_PROJECT_PATH_SLUG .helm
|
||||
--set image=$CI_REGISTRY/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME
|
||||
--set imageTag=$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID
|
||||
--timeout 180s
|
||||
--atomic
|
||||
--debug
|
||||
--namespace $CI_PROJECT_PATH_SLUG-$CI_ENVIRONMENT_NAME
|
||||
after_script:
|
||||
- kubectl -n $CI_PROJECT_PATH_SLUG-$CI_ENVIRONMENT_NAME logs -lcomponent=atomiclog --tail=-1
|
||||
- kubectl -n $CI_PROJECT_PATH_SLUG-$CI_ENVIRONMENT_NAME delete job -lcomponent=atomiclog
|
||||
only:
|
||||
- master
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
# Добавляем helm hook
|
||||
|
||||
## 1. Добавляем манифест job
|
||||
|
||||
```bash
|
||||
cp job.yaml ~/xpaste/.helm/templates/job.yaml
|
||||
|
||||
cd ~/xpaste
|
||||
```
|
||||
|
||||
## 2. Добавляем просмотр результатов работы job в CI/CD
|
||||
|
||||
Добавляем в `.gitlab-ci.yml` в шаг `deploy:` раздел `after_script:`
|
||||
|
||||
```yaml
|
||||
deploy:
|
||||
...
|
||||
after_script:
|
||||
- kubectl -n $CI_PROJECT_PATH_SLUG-$CI_ENVIRONMENT_NAME logs -lcomponent=atomiclog --tail=-1
|
||||
- kubectl -n $CI_PROJECT_PATH_SLUG-$CI_ENVIRONMENT_NAME delete job -lcomponent=atomiclog
|
||||
```
|
||||
|
||||
## 3. Пушим, смотрим в вывод CI/CD
|
||||
|
||||
```
|
||||
git add -A
|
||||
git commit -am "Add job template for getting k8s logs if deploy has failed"
|
||||
git push
|
||||
|
||||
```
|
||||
|
||||
## 4. Исправление настроек приложения
|
||||
|
||||
Ищем ошибку в выводе логов пода.
|
||||
|
||||
* Для исправления ошибки в работе приложения необходимо внести изменения в `values.yml` чарта, описанные в [snippet](https://gitlab.slurm.io/-/snippets/83)
|
||||
|
||||
Для проверки открываем в браузере URL: `http://xpaste.s<Ваш номер логина>.mcs.slurm.io`. `<Ваш номер логина>` необходимо заменить на номер своего студента. Открывать нужно в режиме `инкогнито`. Теперь приложение должно быть доступно.
|
||||
@@ -1,43 +0,0 @@
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: "{{ .Release.Name }}-atomiclog"
|
||||
annotations:
|
||||
"helm.sh/hook": pre-delete,pre-rollback
|
||||
"helm.sh/hook-weight": "1"
|
||||
"helm.sh/hook-delete-policy": before-hook-creation
|
||||
labels:
|
||||
app: {{ .Chart.Name }}
|
||||
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
|
||||
release: {{ .Release.Name }}
|
||||
heritage: {{ .Release.Service }}
|
||||
component: atomiclog
|
||||
spec:
|
||||
activeDeadlineSeconds: 100
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: {{ .Chart.Name }}
|
||||
release: {{ .Release.Name }}
|
||||
component: atomiclog
|
||||
spec:
|
||||
containers:
|
||||
- name: atomiclog
|
||||
image: centosadmin/kubernetes-helm:3.3.4
|
||||
imagePullPolicy: IfNotPresent
|
||||
command:
|
||||
- /bin/bash
|
||||
args:
|
||||
- /usr/local/bin/hooklog.sh
|
||||
- {{ .Release.Namespace }}
|
||||
- {{ .Release.Name }}
|
||||
resources:
|
||||
limits:
|
||||
cpu: 50m
|
||||
memory: 256Mi
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 128Mi
|
||||
dnsPolicy: ClusterFirst
|
||||
restartPolicy: Never
|
||||
serviceAccountName: {{ .Release.Namespace }}
|
||||
@@ -1,111 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -u
|
||||
#
|
||||
# file: https://galaxy.southbridge.io/templates/antools/-/blob/master/scripts/hooklog.sh
|
||||
# version: 0.1.0
|
||||
#
|
||||
# Use this script with Helm pre-rollback hook for logs and events printing.
|
||||
#
|
||||
# Nikolay Mesropyan and Southbridge LLC team, 2020 A.D.
|
||||
#
|
||||
|
||||
_main() {
|
||||
local fn=${FUNCNAME[0]}
|
||||
|
||||
trap '_except $LINENO' ERR
|
||||
|
||||
if [[ "${1:-NOP}" != NOP ]]; then
|
||||
local ns="$1"
|
||||
else
|
||||
_help; exit 0
|
||||
fi
|
||||
|
||||
if [[ "${2:-NOP}" != NOP ]]; then
|
||||
local release="$2"
|
||||
else
|
||||
_help; exit 0
|
||||
fi
|
||||
|
||||
printf '\033[1;31m%s\033[1;35m' "Get pods status: "
|
||||
printf -- '-%.0s' {1..130}
|
||||
printf '\033[0m\n'
|
||||
kubectl -n "$ns" get po -lrelease="$release" -o wide | grep -Fv atomiclog
|
||||
|
||||
printf '\033[1;31m%s\033[1;35m' "Tail of overall 'Warning' events: "
|
||||
printf -- '-%.0s' {1..108}
|
||||
printf '\033[0m\n'
|
||||
kubectl -n "$ns" get events --field-selector type=Warning --sort-by='.metadata.creationTimestamp' | tail
|
||||
|
||||
local -a Daemonsets=() Deployments=() Jobs=() Statefulsets=()
|
||||
|
||||
mapfile -t Daemonsets < <( kubectl -n "$ns" get daemonset -lrelease="$release" --no-headers -o custom-columns=":metadata.name" )
|
||||
mapfile -t Deployments < <( kubectl -n "$ns" get deployment -lrelease="$release" --no-headers -o custom-columns=":metadata.name" )
|
||||
mapfile -t Jobs < <( kubectl -n "$ns" get job -lrelease="$release" --no-headers -o custom-columns=":metadata.name" )
|
||||
mapfile -t Statefulsets < <( kubectl -n "$ns" get statefulset -lrelease="$release" --no-headers -o custom-columns=":metadata.name" )
|
||||
|
||||
for (( i = 0; i < ${#Daemonsets[@]}; i++ )); do
|
||||
__not_ready DaemonSet "${Daemonsets[i]}"
|
||||
done
|
||||
|
||||
for (( i = 0; i < ${#Deployments[@]}; i++ )); do
|
||||
__not_ready Deployment "${Deployments[i]}"
|
||||
done
|
||||
|
||||
for (( i = 0; i < ${#Jobs[@]}; i++ )); do
|
||||
__not_ready Job "${Jobs[i]}"
|
||||
done
|
||||
|
||||
for (( i = 0; i < ${#Statefulsets[@]}; i++ )); do
|
||||
__not_ready StatefulSet "${Statefulsets[i]}"
|
||||
done
|
||||
|
||||
exit 0
|
||||
}
|
||||
|
||||
__not_ready() {
|
||||
local not_ready_pod=""
|
||||
local text="of the first not-ready pod"
|
||||
|
||||
not_ready_pod=$(kubectl -n "$ns" get po -lrelease="$release" --no-headers | grep "^$2" \
|
||||
| gawk -F' *|/' '$4 !~ "Completed|Evicted" { print $0 }' \
|
||||
| gawk -F' *|/' '$2 != $3 || $4 != "Running" { print $1; exit }')
|
||||
|
||||
if [[ -n "$not_ready_pod" ]]; then
|
||||
__events "$@"
|
||||
__logs "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
__events() {
|
||||
printf '\033[1;31m%s\033[1;35m' "$1 ${2}: events ${text}: "
|
||||
printf -- '-%.0s' {1..76}
|
||||
printf '\033[0m\n'
|
||||
kubectl -n "$ns" get events --field-selector involvedObject.name="$not_ready_pod" || :
|
||||
}
|
||||
|
||||
__logs() {
|
||||
local -a Containers=()
|
||||
|
||||
mapfile -t Containers < <( kubectl -n "$ns" get po "$not_ready_pod" --no-headers -o jsonpath="{.spec.containers[*].name}" | sed 's/\s\+/\n/g' )
|
||||
|
||||
for (( i = 0; i < ${#Containers[@]}; i++ )); do
|
||||
printf '\033[1;31m%s\033[1;35m' "$1 ${2}: logs ${text}, container '${Containers[i]}': "
|
||||
printf -- '-%.0s' {1..56}
|
||||
printf '\033[0m\n'
|
||||
kubectl -n "$ns" logs "$not_ready_pod" "${Containers[i]}" --ignore-errors=true --tail=-1 || :
|
||||
done
|
||||
}
|
||||
|
||||
_except() {
|
||||
local ret=$?
|
||||
local no=${1:-no_line}
|
||||
|
||||
echo "error occured in function '$fn' near line ${no}, exit code ${ret}. Continuing..."
|
||||
}
|
||||
|
||||
_help() {
|
||||
echo "Usage: $0 <metadata.namespace> <metadata.labels.release>" >&2
|
||||
}
|
||||
|
||||
_main "$@"
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
variables:
|
||||
K8S_API_URL: https://172.20.100.2:6443
|
||||
|
||||
stages:
|
||||
- linter
|
||||
- build
|
||||
- test
|
||||
- cleanup
|
||||
- push
|
||||
- template
|
||||
- deploy
|
||||
|
||||
build:
|
||||
stage: build
|
||||
script:
|
||||
- docker build -t $CI_REGISTRY/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME:$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID .
|
||||
|
||||
test:
|
||||
stage: test
|
||||
image:
|
||||
name: docker/compose:1.27.4
|
||||
entrypoint: [""]
|
||||
script:
|
||||
- docker-compose
|
||||
-p "$CI_PROJECT_NAME"_"$CI_PIPELINE_ID"
|
||||
up
|
||||
--abort-on-container-exit
|
||||
--exit-code-from app
|
||||
--quiet-pull
|
||||
|
||||
cleanup:
|
||||
stage: cleanup
|
||||
image:
|
||||
name: docker/compose:1.27.4
|
||||
entrypoint: [""]
|
||||
script:
|
||||
- docker-compose -p "$CI_PROJECT_NAME"_"$CI_PIPELINE_ID" down
|
||||
when: always
|
||||
|
||||
push:
|
||||
stage: push
|
||||
before_script:
|
||||
- docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN $CI_REGISTRY
|
||||
script:
|
||||
- docker push $CI_REGISTRY/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME:$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID
|
||||
only:
|
||||
- master
|
||||
|
||||
deploy:
|
||||
stage: deploy
|
||||
image: centosadmin/kubernetes-helm:3.3.4
|
||||
environment:
|
||||
name: production
|
||||
resource_group: deploy_production
|
||||
script:
|
||||
- kubectl config set-cluster k8s --insecure-skip-tls-verify=true --server=$K8S_API_URL
|
||||
- kubectl config set-credentials ci --token=$K8S_CI_TOKEN
|
||||
- kubectl config set-context ci --cluster=k8s --user=ci
|
||||
- kubectl config use-context ci
|
||||
- helm upgrade --install $CI_PROJECT_PATH_SLUG .helm
|
||||
--set image=$CI_REGISTRY/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME
|
||||
--set imageTag=$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID
|
||||
--timeout 180s
|
||||
--atomic
|
||||
--namespace $CI_PROJECT_PATH_SLUG-$CI_ENVIRONMENT_NAME
|
||||
after_script:
|
||||
- kubectl -n $CI_PROJECT_PATH_SLUG-$CI_ENVIRONMENT_NAME logs -lcomponent=atomiclog --tail=-1
|
||||
- kubectl -n $CI_PROJECT_PATH_SLUG-$CI_ENVIRONMENT_NAME delete job -lcomponent=atomiclog
|
||||
only:
|
||||
- master
|
||||
|
||||
helm_lint:
|
||||
stage: linter
|
||||
image: centosadmin/kubernetes-helm:3.3.4
|
||||
environment:
|
||||
name: production
|
||||
script:
|
||||
- helm lint .helm
|
||||
--set image=$CI_REGISTRY/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME
|
||||
--set imageTag=$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID
|
||||
only:
|
||||
- master
|
||||
|
||||
template:
|
||||
stage: template
|
||||
image: centosadmin/kubernetes-helm:3.3.4
|
||||
environment:
|
||||
name: production
|
||||
script:
|
||||
- helm template $CI_PROJECT_PATH_SLUG .helm
|
||||
--set image=$CI_REGISTRY/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME
|
||||
--set imageTag=$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID
|
||||
only:
|
||||
- master
|
||||
@@ -1,56 +0,0 @@
|
||||
# Ещё больше улучшений в конфиге CI/CD
|
||||
|
||||
## 1. Добавляем helm linter и вывод манифестов.
|
||||
|
||||
Добавляем новые шаги:
|
||||
|
||||
```
|
||||
helm_lint:
|
||||
stage: linter
|
||||
image: centosadmin/kubernetes-helm:3.3.4
|
||||
environment:
|
||||
name: production
|
||||
script:
|
||||
- helm lint .helm
|
||||
--set image=$CI_REGISTRY/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME
|
||||
--set imageTag=$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID
|
||||
only:
|
||||
- master
|
||||
```
|
||||
|
||||
```
|
||||
template:
|
||||
stage: template
|
||||
image: centosadmin/kubernetes-helm:3.3.4
|
||||
environment:
|
||||
name: production
|
||||
script:
|
||||
- helm template $CI_PROJECT_PATH_SLUG .helm
|
||||
--set image=$CI_REGISTRY/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME
|
||||
--set imageTag=$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID
|
||||
only:
|
||||
- master
|
||||
```
|
||||
|
||||
Заносим их в список стейджей
|
||||
|
||||
```
|
||||
stages:
|
||||
- linter
|
||||
- build
|
||||
- test
|
||||
- cleanup
|
||||
- push
|
||||
- template
|
||||
- deploy
|
||||
```
|
||||
|
||||
Или копируем готовый файл `.gitlab-ci.yml` в репозиторий xpaste.
|
||||
|
||||
Пушим, смотрим результат.
|
||||
|
||||
## 2. Самостоятельная работа
|
||||
|
||||
Исправляем Error в выводе линтера, Warning можно пропустить.
|
||||
|
||||
PS: В принципе можно убрать ключ `--debug` из шага deploy.
|
||||
@@ -1,25 +0,0 @@
|
||||
# Запускаем приложение в несколько реплик
|
||||
|
||||
## 1. Копируем манифест deployment
|
||||
|
||||
```
|
||||
cp deployment.yaml ~/xpaste/.helm/templates/
|
||||
```
|
||||
|
||||
## 2. Пушим, ждем запуска, рассматриваем
|
||||
|
||||
```
|
||||
cd ~/xpaste
|
||||
git add .helm/templates/deployment.yaml
|
||||
git commit -m "Run app with nginx in separate containers"
|
||||
git push
|
||||
```
|
||||
|
||||
## 3. Смотрим описание пода, список запущенных процессов
|
||||
|
||||
```
|
||||
kubectl describe pod ...
|
||||
kubectl exec -it ...
|
||||
|
||||
ps ax
|
||||
```
|
||||
@@ -1,120 +0,0 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
app: {{ .Chart.Name }}
|
||||
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
|
||||
release: {{ .Release.Name }}
|
||||
heritage: {{ .Release.Service }}
|
||||
component: app
|
||||
name: {{ .Release.Name }}
|
||||
spec:
|
||||
progressDeadlineSeconds: 180
|
||||
replicas: {{ .Values.replicas }}
|
||||
selector:
|
||||
matchLabels:
|
||||
app: {{ .Chart.Name }}
|
||||
release: {{ .Release.Name }}
|
||||
component: app
|
||||
strategy:
|
||||
rollingUpdate:
|
||||
maxSurge: 1
|
||||
maxUnavailable: 1
|
||||
type: RollingUpdate
|
||||
revisionHistoryLimit: 5
|
||||
template:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
app: {{ .Chart.Name }}
|
||||
release: {{ .Release.Name }}
|
||||
component: app
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
command: ["/usr/sbin/nginx"]
|
||||
args: ["-g", "daemon off;"]
|
||||
image: {{ .Values.image }}:{{ .Values.imageTag }}
|
||||
imagePullPolicy: IfNotPresent
|
||||
volumeMounts:
|
||||
- mountPath: /var/run
|
||||
name: socket
|
||||
ports:
|
||||
- containerPort: {{ .Values.service.port }}
|
||||
name: http
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
failureThreshold: 30
|
||||
httpGet:
|
||||
path: /
|
||||
port: {{ .Values.service.port }}
|
||||
scheme: HTTP
|
||||
periodSeconds: 10
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
livenessProbe:
|
||||
initialDelaySeconds: 90
|
||||
failureThreshold: 3
|
||||
httpGet:
|
||||
path: /
|
||||
port: {{ .Values.service.port }}
|
||||
scheme: HTTP
|
||||
periodSeconds: 10
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 2
|
||||
resources:
|
||||
limits:
|
||||
cpu: 100m
|
||||
memory: 256Mi
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 256Mi
|
||||
- env:
|
||||
{{- range $key, $val := .Values.env }}
|
||||
- name: {{ $key | quote }}
|
||||
value: {{ $val | quote }}
|
||||
{{- end }}
|
||||
{{- range $key, $val := .Values.envSecret }}
|
||||
- name: {{ $key | quote }}
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
key: {{ $key | lower | replace "_" "-" }}
|
||||
name: {{ $val }}
|
||||
{{- end }}
|
||||
image: {{ .Values.image }}:{{ .Values.imageTag}}
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: app
|
||||
command: ["/bin/sh"]
|
||||
args: ["-c","bundle exec rake db:migrate && exec bundle exec puma -b unix:///var/run/puma.sock -e $RAILS_ENV config.ru"]
|
||||
volumeMounts:
|
||||
- mountPath: /var/run
|
||||
name: socket
|
||||
readinessProbe:
|
||||
failureThreshold: 30
|
||||
httpGet:
|
||||
path: /
|
||||
port: {{ .Values.service.port }}
|
||||
scheme: HTTP
|
||||
periodSeconds: 10
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
livenessProbe:
|
||||
initialDelaySeconds: 90
|
||||
failureThreshold: 3
|
||||
httpGet:
|
||||
path: /
|
||||
port: {{ .Values.service.port }}
|
||||
scheme: HTTP
|
||||
periodSeconds: 10
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 2
|
||||
resources:
|
||||
{{ toYaml .Values.resources | indent 12 }}
|
||||
dnsPolicy: ClusterFirst
|
||||
restartPolicy: Always
|
||||
terminationGracePeriodSeconds: 20
|
||||
imagePullSecrets:
|
||||
- name: {{ .Values.imagePullSecret }}
|
||||
volumes:
|
||||
- name: socket
|
||||
emptyDir: {}
|
||||
@@ -1,18 +0,0 @@
|
||||
# Добавляем pre-install hook с миграцией БД
|
||||
|
||||
## 1. Копируем манифест deployment и job.migrate
|
||||
|
||||
```
|
||||
cp job.migrate.yaml ~/xpaste/.helm/templates/
|
||||
cp deployment.yaml ~/xpaste/.helm/templates/
|
||||
```
|
||||
|
||||
## 2. Пушим, ждем запуска, рассматриваем
|
||||
|
||||
```
|
||||
cd ~/xpaste
|
||||
git add .helm/templates/job.migrate.yaml
|
||||
git add .helm/templates/deployment.yaml
|
||||
git commit -m "Add migrate job"
|
||||
git push
|
||||
```
|
||||
@@ -1,120 +0,0 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
app: {{ .Chart.Name }}
|
||||
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
|
||||
release: {{ .Release.Name }}
|
||||
heritage: {{ .Release.Service }}
|
||||
component: app
|
||||
name: {{ .Release.Name }}
|
||||
spec:
|
||||
progressDeadlineSeconds: 180
|
||||
replicas: {{ .Values.replicas }}
|
||||
selector:
|
||||
matchLabels:
|
||||
app: {{ .Chart.Name }}
|
||||
release: {{ .Release.Name }}
|
||||
component: app
|
||||
strategy:
|
||||
rollingUpdate:
|
||||
maxSurge: 1
|
||||
maxUnavailable: 1
|
||||
type: RollingUpdate
|
||||
revisionHistoryLimit: 5
|
||||
template:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
app: {{ .Chart.Name }}
|
||||
release: {{ .Release.Name }}
|
||||
component: app
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
command: ["/usr/sbin/nginx"]
|
||||
args: ["-g", "daemon off;"]
|
||||
image: {{ .Values.image }}:{{ .Values.imageTag }}
|
||||
imagePullPolicy: IfNotPresent
|
||||
volumeMounts:
|
||||
- mountPath: /var/run
|
||||
name: socket
|
||||
ports:
|
||||
- containerPort: {{ .Values.service.port }}
|
||||
name: http
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
failureThreshold: 30
|
||||
httpGet:
|
||||
path: /
|
||||
port: {{ .Values.service.port }}
|
||||
scheme: HTTP
|
||||
periodSeconds: 10
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
livenessProbe:
|
||||
initialDelaySeconds: 90
|
||||
failureThreshold: 3
|
||||
httpGet:
|
||||
path: /
|
||||
port: {{ .Values.service.port }}
|
||||
scheme: HTTP
|
||||
periodSeconds: 10
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 2
|
||||
resources:
|
||||
limits:
|
||||
cpu: 100m
|
||||
memory: 256Mi
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 256Mi
|
||||
- env:
|
||||
{{- range $key, $val := .Values.env }}
|
||||
- name: {{ $key | quote }}
|
||||
value: {{ $val | quote }}
|
||||
{{- end }}
|
||||
{{- range $key, $val := .Values.envSecret }}
|
||||
- name: {{ $key | quote }}
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
key: {{ $key | lower | replace "_" "-" }}
|
||||
name: {{ $val }}
|
||||
{{- end }}
|
||||
image: {{ .Values.image }}:{{ .Values.imageTag}}
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: app
|
||||
command: ["/bin/sh"]
|
||||
args: ["-c","exec bundle exec puma -b unix:///var/run/puma.sock -e $RAILS_ENV config.ru"]
|
||||
volumeMounts:
|
||||
- mountPath: /var/run
|
||||
name: socket
|
||||
readinessProbe:
|
||||
failureThreshold: 30
|
||||
httpGet:
|
||||
path: /
|
||||
port: {{ .Values.service.port }}
|
||||
scheme: HTTP
|
||||
periodSeconds: 10
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
livenessProbe:
|
||||
initialDelaySeconds: 90
|
||||
failureThreshold: 3
|
||||
httpGet:
|
||||
path: /
|
||||
port: {{ .Values.service.port }}
|
||||
scheme: HTTP
|
||||
periodSeconds: 10
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 2
|
||||
resources:
|
||||
{{ toYaml .Values.resources | indent 12 }}
|
||||
dnsPolicy: ClusterFirst
|
||||
restartPolicy: Always
|
||||
terminationGracePeriodSeconds: 20
|
||||
imagePullSecrets:
|
||||
- name: {{ .Values.imagePullSecret }}
|
||||
volumes:
|
||||
- name: socket
|
||||
emptyDir: {}
|
||||
@@ -1,56 +0,0 @@
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: "{{ .Release.Name }}-dbmigrate"
|
||||
annotations:
|
||||
"helm.sh/hook": pre-install,pre-upgrade
|
||||
"helm.sh/hook-weight": "1"
|
||||
"helm.sh/hook-delete-policy": before-hook-creation
|
||||
labels:
|
||||
app: {{ .Chart.Name }}
|
||||
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
|
||||
release: {{ .Release.Name }}
|
||||
heritage: {{ .Release.Service }}
|
||||
component: dbmigrate
|
||||
spec:
|
||||
activeDeadlineSeconds: 180
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: {{ .Chart.Name }}
|
||||
release: {{ .Release.Name }}
|
||||
component: dbmigrate
|
||||
spec:
|
||||
containers:
|
||||
- name: dbmigrate
|
||||
image: {{ .Values.image }}:{{ .Values.imageTag }}
|
||||
imagePullPolicy: IfNotPresent
|
||||
command:
|
||||
- bundle
|
||||
args:
|
||||
- exec
|
||||
- rake
|
||||
- db:migrate
|
||||
env:
|
||||
{{- range $key, $val := .Values.env }}
|
||||
- name: {{ $key | quote }}
|
||||
value: {{ $val | quote }}
|
||||
{{- end }}
|
||||
{{- range $key, $val := .Values.envSecret }}
|
||||
- name: {{ $key | quote }}
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
key: {{ $key | lower | replace "_" "-" }}
|
||||
name: {{ $val }}
|
||||
{{- end }}
|
||||
resources:
|
||||
limits:
|
||||
cpu: 50m
|
||||
memory: 128Mi
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 128Mi
|
||||
dnsPolicy: ClusterFirst
|
||||
restartPolicy: Never
|
||||
imagePullSecrets:
|
||||
- name: {{ .Values.imagePullSecret }}
|
||||
@@ -15,7 +15,7 @@ helm repo add gitlab https://charts.gitlab.io
|
||||
Как вы уже поняли, для установки мы пойдем знакомым путём Helm, выполнив команды:
|
||||
|
||||
```bash
|
||||
helm upgrade -i gitlab-runner gitlab/gitlab-runner -f values.yaml
|
||||
helm upgrade -i gitlab-runner gitlab/gitlab-runner -f values.yaml -n gitlab-runner --create-namespace
|
||||
```
|
||||
|
||||
## 3. Проверка регистрации раннера
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
## The GitLab Server URL (with protocol) that want to register the runner against
|
||||
## ref: https://docs.gitlab.com/runner/commands/README.html#gitlab-runner-register
|
||||
##
|
||||
gitlabUrl: http://gitlab.com/
|
||||
gitlabUrl: https://gitlab.com/
|
||||
|
||||
## The Registration Token for adding new Runners to the GitLab Server. This must
|
||||
## be retrieved from your GitLab Instance.
|
||||
@@ -14,7 +14,7 @@ runners:
|
||||
[[runners]]
|
||||
[runners.kubernetes]
|
||||
image = "alpine:3.14"
|
||||
cpu_request = "1000m"
|
||||
cpu_request = "100m"
|
||||
cpu_limit = "1000m"
|
||||
memory_limit = "2048Mi"
|
||||
memory_request = "1024Mi"
|
||||
@@ -30,7 +30,7 @@ rbac:
|
||||
|
||||
## Use the following Kubernetes Service Account name if RBAC is disabled in this Helm chart (see rbac.create)
|
||||
##
|
||||
serviceAccountName: s<номер_студента>
|
||||
# serviceAccountName: gitlabrunnersa
|
||||
|
||||
## Use podSecurity Policy
|
||||
## ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
Postgres мы устанавливаем в kubernetes кластер, делается это исключительно в учебных целях. Для установки будет использована утилита helm. Для установки необходимо выполнить следующую команду, заменив `<Ваш номер логина>` на номер своего студента:
|
||||
|
||||
```bash
|
||||
helm install postgresql postgresql --namespace xpaste --atomic --timeout 120s
|
||||
helm install postgresql postgresql --namespace xpaste-development --atomic --timeout 120s --create-namespace
|
||||
```
|
||||
|
||||
Postrgesql будет установлен с логином и паролем, указанными в values.yaml чарта.
|
||||
|
||||
@@ -62,7 +62,7 @@ else
|
||||
metadata:
|
||||
name: "$ROLE"
|
||||
rules:
|
||||
- apiGroups: ["", "extensions", "apps", "batch", "events", "certmanager.k8s.io", "cert-manager.io", "monitoring.coreos.com"]
|
||||
- apiGroups: ["", "extensions", "apps", "batch", "events", "networking.k8s.io", "certmanager.k8s.io", "cert-manager.io", "monitoring.coreos.com"]
|
||||
resources: ["*"]
|
||||
verbs: ["*"]
|
||||
EOF
|
||||
|
||||
@@ -20,9 +20,9 @@ build:
|
||||
- echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json
|
||||
- |
|
||||
/kaniko/executor --context $CI_PROJECT_DIR \
|
||||
--cache=true --cache-repo=$CI_REGISTRY/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME \
|
||||
--cache=true --cache-repo=$CI_REGISTRY_IMAGE \
|
||||
--dockerfile $CI_PROJECT_DIR/Dockerfile \
|
||||
--destination $CI_REGISTRY/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME:$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID
|
||||
--destination ${CI_REGISTRY_IMAGE}:$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID
|
||||
|
||||
deploy:dev:
|
||||
stage: deploy
|
||||
@@ -35,7 +35,7 @@ deploy:dev:
|
||||
- kubectl config set-context ci --cluster=k8s --user=ci
|
||||
- kubectl config use-context ci
|
||||
- helm upgrade --install xpaste .helm
|
||||
--set image=$CI_REGISTRY/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME
|
||||
--set image=$CI_REGISTRY_IMAGE
|
||||
--set imageTag=$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID
|
||||
--debug
|
||||
--atomic
|
||||
|
||||
@@ -9,31 +9,12 @@ Gitlab CI/CD описывается в файле `.gitlab-ci.yml` в форма
|
||||
Для этого скопируем заранее подготовленный шаблон `.gitlab-ci.yml` в проект `xpaste`, выполнив команду:
|
||||
|
||||
```bash
|
||||
cp ~/slurm/practice/14.ci-cd/1.2.deploy/.gitlab-ci.yml ~/xpaste/
|
||||
cp .gitlab-ci.yml ~/xpaste/
|
||||
```
|
||||
|
||||
## 2. Адрес Kubernetes API
|
||||
|
||||
В файле `.gitlab-ci.yml` указан IP-адрес нашего общего kube api.
|
||||
|
||||
## 3. Настройка базы данных
|
||||
|
||||
Сервер базы данных общий для всех студентов, каждому студенту выделена своя база данных.
|
||||
Логин и пароль для доступа к БД мы указывали при создании секрета, а в параметрах чарта укажен название БД.
|
||||
|
||||
Для этого откроем `values.yaml`:
|
||||
|
||||
```bash
|
||||
vi ~/xpaste/.helm/values.yaml
|
||||
```
|
||||
|
||||
В начале файла необходимо заменить строку `<Ваш номер логина> - меняем на свой номер студента!!`:
|
||||
|
||||
```diff
|
||||
- DB_NAME: <номер своего логина>_xpaste
|
||||
+ DB_NAME: s000001_xpaste
|
||||
```
|
||||
|
||||
В файле `.gitlab-ci.yml` указан адрес kube api. Так как runner запущен внутри кластера кубернтес, можем указать название сервиса kubernetes.default
|
||||
|
||||
## 3. Настройка ingress
|
||||
|
||||
@@ -44,11 +25,11 @@ vi ~/xpaste/.helm/values.yaml
|
||||
vi ~/xpaste/.helm/values.yaml
|
||||
```
|
||||
|
||||
В конце файла необходимо заменить строку `<Ваш номер логина> - меняем на свой номер студента!!`:
|
||||
В переменной host необходимо указать DNS название, которое вы выдали сайту xpaste:
|
||||
|
||||
```diff
|
||||
- host: xpaste.s<Ваш номер логина>.mcs.slurm.io
|
||||
+ host: xpaste.s000001.mcs.slurm.io
|
||||
- host: xpaste.s<Ваш номер логина>.edu.slurm.io
|
||||
+ host: xpaste.s000001.edu.slurm.io
|
||||
```
|
||||
|
||||
Сохраняем все изменения и пушим их в gitlab. Для этого необходимо выполнить команды:
|
||||
@@ -62,47 +43,20 @@ git push
|
||||
|
||||
## 4. Переключаемся в namespace приложения
|
||||
|
||||
До сих пор мы работали в неймспейсе кластера Kubernetes с названием `s<номер_студента>`
|
||||
|
||||
Но наше приложение xpaste устанавливается в другой namespace `s<номер_студента>-xpaste-production`.
|
||||
Наше приложение xpaste устанавливается в другой namespace `xpaste-development`.
|
||||
Для удобства работы, чтобы не набирать каждый раз опцию `--namespace` изменим namespace, который kubectl использует по умолчанию:
|
||||
|
||||
```bash
|
||||
kubectl config set-context --current --namespace=s<номер_студента>-xpaste-production
|
||||
kubectl config set-context --current --namespace=xpaste-development
|
||||
```
|
||||
|
||||
## 5. Проверка результата
|
||||
|
||||
Для проверки результата необходимо перейти в Gitlab в раздел `ci/cd -> pipelines` форка проекта xpaste.
|
||||
Можно воспользоваться прямой ссылкой: `https://gitlab.slurm.io/sXXXXXX/xpaste/pipelines`. `sXXXXXX` необходимо заменить на номер своего студента.
|
||||
Можно воспользоваться прямой ссылкой: `https://gitlab.com/sXXXXXX/xpaste/pipelines`. `sXXXXXX` необходимо заменить на свой каталог в гитлабе.
|
||||
|
||||
В результате все job должны закончиться без ошибок.
|
||||
|
||||
## 6.Открываем приложение в браузере
|
||||
|
||||
В браузере открываем URL: http://xpaste.s<Ваш номер логина>.mcs.slurm.io. `<Ваш номер логина>` необходимо заменить на номер своего студента. Открывать нужно в режиме `инкогнито`.
|
||||
|
||||
Если вы увидели `503` ошибку, значит практику выполнили верно.
|
||||
|
||||
## 7. Самостоятельная работа
|
||||
|
||||
Самостоятельная работа продолжительностью 5 минут. Во время самостоятельной работы надо попробовать ответить на вопросы:
|
||||
|
||||
* Почему деплой закончился успешно, а приложение недоступно?
|
||||
* Что надо исправить в CI/CD ?
|
||||
* Что надо исправить в приложении или его настройках ?
|
||||
|
||||
Ошибку пока исправлять не надо.
|
||||
|
||||
## 8. Доработка CI/CD
|
||||
|
||||
* Для корректировки поведения CI/CD необходимо внести изменения в ci/cd, описанные в [snippet](https://gitlab.slurm.io/-/snippets/107)
|
||||
|
||||
Удаляем установленный релиз helm чарта:
|
||||
|
||||
```bash
|
||||
helm delete s<номер_студента>-xpaste
|
||||
```
|
||||
Далее пушим изменения и смотрим за процессом CI/CD.
|
||||
|
||||
После внесения изменений процесс деплоя должен завершиться с ошибкой.
|
||||
В браузере открываем URL: http://xpaste.s<Ваш номер логина>.edu.slurm.io. Открывать нужно в режиме `инкогнито`.
|
||||
|
||||
@@ -22,9 +22,9 @@ build:
|
||||
- echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json
|
||||
- |
|
||||
/kaniko/executor --context $CI_PROJECT_DIR \
|
||||
--cache=true --cache-repo=$CI_REGISTRY/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME \
|
||||
--cache=true --cache-repo=$CI_REGISTRY_IMAGE \
|
||||
--dockerfile $CI_PROJECT_DIR/Dockerfile \
|
||||
--destination $CI_REGISTRY/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME:$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID
|
||||
--destination ${CI_REGISTRY_IMAGE}:$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID
|
||||
|
||||
deploy:dev:
|
||||
stage: deploy
|
||||
@@ -37,7 +37,7 @@ deploy:dev:
|
||||
- kubectl config set-context ci --cluster=k8s --user=ci
|
||||
- kubectl config use-context ci
|
||||
- helm upgrade --install xpaste .helm
|
||||
--set image=$CI_REGISTRY/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME
|
||||
--set image=$CI_REGISTRY_IMAGE
|
||||
--set imageTag=$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID
|
||||
--debug
|
||||
--atomic
|
||||
@@ -45,7 +45,6 @@ deploy:dev:
|
||||
--namespace $NAMESPACE-$CI_ENVIRONMENT_SLUG
|
||||
only:
|
||||
- master
|
||||
|
||||
helm_lint:
|
||||
stage: linter
|
||||
image: centosadmin/kubernetes-helm:3.6.3
|
||||
@@ -53,7 +52,7 @@ helm_lint:
|
||||
name: production
|
||||
script:
|
||||
- helm lint .helm
|
||||
--set image=$CI_REGISTRY/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME
|
||||
--set image=$CI_REGISTRY_IMAGE
|
||||
--set imageTag=$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID
|
||||
only:
|
||||
- master
|
||||
@@ -65,7 +64,7 @@ template:
|
||||
name: production
|
||||
script:
|
||||
- helm template $CI_PROJECT_PATH_SLUG .helm
|
||||
--set image=$CI_REGISTRY/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME
|
||||
--set image=$CI_REGISTRY_IMAGE
|
||||
--set imageTag=$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID
|
||||
only:
|
||||
- master
|
||||
|
||||
@@ -12,7 +12,7 @@ helm_lint:
|
||||
name: production
|
||||
script:
|
||||
- helm lint .helm
|
||||
--set image=$CI_REGISTRY/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME
|
||||
--set image=$CI_REGISTRY_IMAGE
|
||||
--set imageTag=$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID
|
||||
only:
|
||||
- master
|
||||
@@ -26,7 +26,7 @@ template:
|
||||
name: production
|
||||
script:
|
||||
- helm template $CI_PROJECT_PATH_SLUG .helm
|
||||
--set image=$CI_REGISTRY/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME
|
||||
--set image=$CI_REGISTRY_IMAGE
|
||||
--set imageTag=$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID
|
||||
only:
|
||||
- master
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
# CI/CD в Kubernetes с помощью Gitlab
|
||||
|
||||
## Список практик
|
||||
|
||||
[1.1 Prepare Cluster](1.1.prepare_cluster/README.md)
|
||||
|
||||
[1.2 Deploy](1.2.deploy/README.md)
|
||||
|
||||
[1.3 Show Logs](1.3.logs/README.md)
|
||||
|
||||
[1.4 Improvement_cicd](1.4.improvement_cicd/README.md)
|
||||
|
||||
[1.5 Two containers/](1.5.two_containers//README.md)
|
||||
|
||||
[1.6 Job for migration](1.6.job.migration/README.md)
|
||||
|
||||
## Форк проекта
|
||||
|
||||
> Открываем в браузере репозиторий xpaste. Он находится по адресу
|
||||
|
||||
https://github.com/Slurmio/xpaste
|
||||
|
||||
|
||||
> Справа на одной линии с названием проекта видим кнопку fork. Нажимаем ее.
|
||||
> И дожидаемся окончания процесса форка.
|
||||
> Последним шагом клонируем получившийся форк к себе.
|
||||
Reference in New Issue
Block a user