Kubernetes: Kubernetes 작업 및 Helm hook을 사용하여 SQL 마이그레이션 실행
21015 단어 devopskubernetessqltutorial
Kubernetes에서 실행되는 프로젝트가 있습니다. 배포 중에 SQL 마이그레이션을 실행해야 합니다.
마이그레이션을 실행하려면 Github 저장소를 복제하고 실제 마이그레이션을 실행해야 합니다.
현재 이것은 Kubernetes initContainers로 완성된 것으로 그 중 두 개가 있다 — 첫 번째 저장소
git
는 마이그레이션 파일이 있는 저장소를 복제하여 Kubernetes Volume 로 옮긴 다음 다른 저장소 sql-migrate
는 공유 볼륨에서 마이그레이션을 실행합니다.그럼에도 불구하고 이러한 방법에는 몇 가지 문제가 존재한다.
주의: 여기 kk는kubectl의 별명입니다.
준비
Docker 이미지
우선, 21시와git, 그리고 https://github.com/rubenv/sql-migrate로 우리만의 Docker 이미지를 만듭니다.
Dockerfile 만들기:
FROM golang:alpine AS builder
RUN apk add --no-cache git gcc g++
RUN go get -v github.com/rubenv/sql-migrate/sql-migrate
RUN mv /go/bin/sql-migrate /bin/sql-migrate
구축 및 추진:$ docker build -t projectname/sql-migrate-git .
$ docker push projectname/sql-migrate-git
Git 인증
두 번째는 Github 인증입니다.
이 때, 우리의git 용기는 Kubernetes Secrets에 저장된 RSA 키를 통해 인증을 한 다음, 환경 변수를 통해pod로 전달하고, bash 스크립트
/opt/git/git.sh
에서 이 키를 가져옵니다. 이 스크립트는 용기 안에 키 파일/root/.ssh/id_rsa
을 만드는 데 사용되며, 이 키는 인증에 사용됩니다.현재 배포 중인
initContainers
은 다음과 같습니다....
initContainers:
- name: git-clone
image: projectname/git-cloner
env:
- name: SSH_PRIVATE_KEY
valueFrom:
secretKeyRef:
name: git-ssh-key
key: id_rsa
- name: REPOSITORY_URL
value: {{ .Values.git.repo }}
- name: GIT_BRANCH
value: {{ .Values.git.branch }}
command: ['sh', '-c', '/opt/git/git.sh']
volumeMounts:
- name: git-volume
mountPath: "/git"
readOnly: false
- name: init-migration
image: fufuhu/sql-migrate:latest
command: ['sh', '-c', 'while [! -d /git/db/migrations]; do sleep 2; done && sleep 2; /bin/sql-migrate up -config=/config/config.yaml -env=main']
volumeMounts:
- name: migration-config
mountPath: "/config/"
readOnly: true
- name: git-volume
mountPath: "/git"
readOnly: false
...
많은 절차, 많은 대상, 복잡한 과정.대신 환경 변수를 컨테이너에 전달하고 HTTPS를 통해 저장소를 복제할 수 있는 로그인 이름과 Github token을 사용합니다.
테스트를 해보겠습니다.
~ # export GIT_AUTHUSER=backend-user
~ # export GIT_AUTHKEY=cdc***0fe
~ # git clone
[https://$GIT_AUTHUSER:[email protected]/projectname-dev/backend-services.git](https://%24GIT_AUTHUSER:%[email protected]/projectname-dev/backend-services.git)
Cloning into ‘backend-services’…
…
Receiving objects: 100% (5115/5115), 846.55 KiB | 1.30 MiB/s, done.
Resolving deltas: 100% (2826/2826), done.
좋아, "효과가 있어")Kubernetes의 SQL 마이그레이션
이제 Kubernetes 작업을 설명하기 위해 목록 파일
templates/appname-api-migrations.yaml
을 작성할 수 있습니다. 이 작업은 나중에 Helm 연결로 시작됩니다.Kubernetes 작업
git 클론
우선, 업무가 정상적으로 진행되도록 확보하다 — Helm 변수와 값이 없는 상태에서 작성합니다. 모든pod의 환경 변수는 순수한 텍스트 값으로 설정됩니다.
apiVersion: batch/v1
kind: Job
metadata:
name: "migration-job"
labels:
annotations:
spec:
backoffLimit: 0
template:
metadata:
name: "migration-job-pod"
spec:
restartPolicy: Never
containers:
- name: db-migrations
image: projectname/sql-migrate-git:latest
command: ["/bin/sh", "-c"]
args:
- git clone --single-branch --branch develop [https://backend-user:cdc***[email protected]/projectname/backend-services.git](https://backend-user:cdc***[email protected]/projectname/backend-services.git) &&
ls -l backend-services/db/migrations
git clone
에서, 우리는 용기가 실패할 때 용기를 다시 시작하지 않도록 설정했습니다. 왜냐하면 우리는 이전 실패를 보고 싶기 때문입니다. restartPolicy
에서도 마찬가지입니다. 실패하면pod를 다시 만들지 않고 실패 상태만 유지하는 작업입니다.backoffLimit=0
에서 Jenkins 작업 설정 분기, git clone
에서 사용자 및 URL을 설정하고 인증 토큰을 Helm secrets 에 보관한 후 환경 변수로 이동합니다.작업을 만들려면 다음과 같이 하십시오.
$ kk -n eks-dev-1-appname-api-ns apply -f appname-api-jobs.yaml
job.batch/migration-job created
로그 확인:$ kk -n eks-dev-1-appname-api-ns logs job/migration-job
Cloning into ‘backend-services’…
total 20
-rw-r — r — 1 root root 538 Oct 24 12:20 BS_1_init_schema.up.sql
-rw-r — r — 1 root root 180 Oct 24 12:20 BS_2_add_brand_field.up.sql
-rw-r — r — 1 root root 225 Oct 24 12:20 BS_3_alter_table.up.sql
-rw-r — r — 1 root root 194 Oct 24 12:20 BS_4_add_created_at_field.sql
-rw-r — r — 1 root root 272 Oct 24 12:20 BS_5_alter_table_nourishment_diet.up.sql
저장소가 복제되어 마이그레이션 파일에 액세스할 수 있습니다.크레인 상태 검사:
$ kk -n eks-dev-1-appname-api-ns get pod
NAME READY STATUS RESTARTS AGE
migration-job-f72vs 0/1 Completed 0 9s
작업 상태:$ kk -n eks-dev-1-appname-api-ns get job
NAME COMPLETIONS DURATION AGE
migration-job 1/1 2s 5s
이제 정확한 마이그레이션 프로세스를 계속 수행할 수 있습니다.비밀.
마이그레이션을 실행하려면 Kubernetes ConfigMap 에 저장되는 구성 파일을 만들어야 하지만 이 파일에는 데이터베이스 암호를 설정해야 합니다.
ConfigMap 및 파일에 명문으로 저장하는 것은 좋지 않지만
values.yaml
파일에서 환경 변수를 사용할 수 있도록 하려면 문서를 확인하십시오 - https://github.com/rubenv/sql-migrate#as-a-standalone-tool따라서pod에
sql-migrate
라는 변수를 만들고 실제 암호를 Kubernetes 기밀에 보관합니다. 나중에 Helm에서 Helm secrets 암호화를 사용하여 도표의 값에 저장합니다.마찬가지로 본 기밀에서는
$DB_PASSWORD
명령에 사용할 환경 변수의 값을 저장합니다.여전히
$GIT_TOKEN
에 비밀을 추가합니다....
---
apiVersion: v1
kind: Secret
metadata:
name: backend-db-password
type: Opaque
stringData:
db_password: password
git_token: cdc***0fe
작업의 git clone
에 변수를 추가하고 templates/appname-api-migrations.yaml
를 업데이트하여 spec.containers.env
변수를 사용합니다....
containers:
- name: db-migrations
image: projectname/sql-migrate-git:latest
command: ["/bin/sh", "-c"]
args:
- git clone --single-branch --branch develop [https://backend-user:[email protected]/projectnamev/backend-services.git](https://backend-user:%[email protected]/projectnamev/backend-services.git) &&
ls -l backend-services/db/migrations;
cat /config/config.yaml
env:
- name: GIT_TOKEN
valueFrom:
secretKeyRef:
name: backend-db-password
key: git_token
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: backend-db-password
key: db_password
...
매핑 구성
다음으로 ConfigMap을 작성하여
git clone
의$GIT_TOKEN
컨텐트를 보존하고 /config/config.yaml
변수를 사용합니다....
---
apiVersion: v1
kind: ConfigMap
metadata:
name: migration-config
data:
config.yaml: |
main:
dialect: mysql
datasource: backend-user:${DB_PASSWORD}@tcp(stage.backend-db3-master.example.com:3306)/dbname?parseTime=true
dir: backend-services/db/migrations
table: backend_services_migrations
작업의 pod 템플릿에 볼륨을 추가하고 sql-migrate
에서 볼륨을 로드하여 ConfigMap을 $DB_PASSWORD
파일로 만듭니다.작업의 전체 목록은 다음 목록입니다.
apiVersion: batch/v1
kind: Job
metadata:
name: "migration-job"
labels:
annotations:
spec:
backoffLimit: 0
template:
metadata:
name: "migration-job-pod"
spec:
restartPolicy: Never
containers:
- name: db-migrations
image: projectname/sql-migrate-git:latest
command: ["/bin/sh", "-c"]
args:
- git clone --single-branch --branch develop [https://backend-user:[email protected]/projectname/backend-services.git](https://backend-user:%[email protected]/projectname/backend-services.git) &&
ls -l backend-services/db/migrations;
cat /config/config.yaml
env:
- name: GIT_TOKEN
valueFrom:
secretKeyRef:
name: backend-db-password
key: git_token
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: backend-db-password
key: db_password
volumeMounts:
- name: migration-config
mountPath: "/config/config.yaml"
subPath: "config.yaml"
readOnly: true
volumes:
- name: migration-config
configMap:
name: migration-config
items:
- key: "config.yaml"
path: "config.yaml"
...
실행:$ kk -n eks-dev-1-appname-api-ns apply -f appname-api-jobs.yaml
job.batch/migration-job created
secret/backend-db-password created
configmap/migration-config created
검사:$ kk -n eks-dev-1-appname-api-ns logs job/migration-job
Cloning into ‘backend-services’…
total 20
-rw-r — r — 1 root root 538 Oct 24 13:41 BS_1_init_schema.up.sql
-rw-r — r — 1 root root 180 Oct 24 13:41 BS_2_add_brand_field.up.sql
-rw-r — r — 1 root root 225 Oct 24 13:41 BS_3_alter_table.up.sql
-rw-r — r — 1 root root 194 Oct 24 13:41 BS_4_add_created_at_field.sql
-rw-r — r — 1 root root 272 Oct 24 13:41 BS_5_alter_table_nourishment_diet.up.sql
main:
dialect: mysql
datasource: backend-user:${DB_PASSWORD}@tcp(stage.backend-db3-master.example.com:3306)/dbname?parseTime=true
dir: backend-services/db/migrations
table: backend_services_migrations
좋다 — 저장소가 복제되고 구성 파일이 생성되었습니다.마이그레이션 실행
현재 마이그레이션 프로세스는
spec.containers
옵션과 두 번째 명령으로 설명할 수 있습니다....
args:
- git clone --single-branch --branch develop [https://backend-user:[email protected]/projectname/backend-services.git](https://backend-user:%[email protected]/projectname/backend-services.git) &&
ls -l backend-services/db/migrations &&
cat /config/config.yaml &&
/bin/sql-migrate up -config=/config/config.yaml -env=main -dryrun &&
/bin/sql-migrate status -config=/config/config.yaml -env=main
...
로그를 실행하고 확인합니다.$ kk -n eks-dev-1-appname-test-migrations-ns logs job/migration-job
Cloning into ‘backend-services’…
total 20
-rw-r — r — 1 root root 538 Oct 24 14:02 BS_1_init_schema.up.sql
-rw-r — r — 1 root root 180 Oct 24 14:02 BS_2_add_brand_field.up.sql
-rw-r — r — 1 root root 225 Oct 24 14:02 BS_3_alter_table.up.sql
-rw-r — r — 1 root root 194 Oct 24 14:02 BS_4_add_created_at_field.sql
-rw-r — r — 1 root root 272 Oct 24 14:02 BS_5_alter_table_nourishment_diet.up.sql
main:
dialect: mysql
datasource: backnd-user:${DB_PASSWORD}@tcp(stage.backend-db3-master.example.com:3306)/dbname?parseTime=true
dir: backend-services/db/migrations
table: backend_services_migrations
+ — — — — — — — — — — — — — — — — — — — — — + — — — — — — — — — — — — — — — -+
| MIGRATION | APPLIED |
+ — — — — — — — — — — — — — — — — — — — — — + — — — — — — — — — — — — — — — -+
| BS_1_init_schema.up.sql | 2020–05–07 12:21:25 +0000 UTC |
| BS_2_add_brand_field.up.sql | 2020–05–12 14:31:17 +0000 UTC |
| BS_3_alter_table.up.sql | 2020–05–13 06:17:25 +0000 UTC |
| BS_4_add_created_at_field.sql | 2020–07–21 09:55:49 +0000 UTC |
| BS_5_alter_table_nourishment_diet.up.sql | 2020–07–21 09:55:49 +0000 UTC |
+ — — — — — — — — — — — — — — — — — — — — — + — — — — — — — — — — — — — — — -+
이제 키잡이에 들어갈 수 있습니다.투구 틀
낡은 도표에서 우리는 무엇을 해야 합니까?
volumeMounts
/config/config.yaml
에서 새 변수 값 이동-dryrun
로 이동initContainers
작업에 추가:apiVersion: batch/v1
kind: Job
metadata:
name: {{ .Chart.Name }}-migration-job
labels:
annotations:
"helm.sh/hook": pre-install,pre-upgrade
"helm.sh/hook-weight": "-1"
"helm.sh/hook-delete-policy": before-hook-creation
spec:
backoffLimit: 0
...
여기:values.yaml
: secrets.yaml
또는 annotations
이전에 작업을 실행합니다(우리의 Jenkins 파이프에서 "helm.sh/hook": pre-install,pre-upgrade
부터)helm install
: 우선 작업에 사용할 ConfigMap과 Secret을 만들어야 하기 때문에 리소스 생성 우선 순위를 작업보다 작게 설정합니다upgrade
: 기본값은 갈고리를 만들기 전 (검사 documentation, 테스트 목적에 if를 설정한 다음 갈고리로 변경할 수 있습니다 (단, 이 경우 마이그레이션에 실패하면 로그를 검사할 수 없습니다) helm secrets upgrade --install
블록을 추가하고 작업에서 보다 작은 "helm.sh/hook-weight": "-1"
블록을 사용하여 비밀을 유지합니다.ConfigMap 목록에는 현재 전체 내용이 포함되어 있습니다.
---
apiVersion: v1
kind: ConfigMap
metadata:
name: migration-config
annotations:
"helm.sh/hook": pre-install,pre-upgrade
"helm.sh/hook-weight": "-5"
"helm.sh/hook-delete-policy": before-hook-creation
data:
config.yaml: |
main:
dialect: {{ .Values.backendConfig.db.driver }}
datasource: {{ .Values.backendConfig.db.user }}:${DB_PASSWORD}@tcp({{ .Values.backendConfig.db.host }}:{{ .Values.backendConfig.db.port }})/{{ .Values.backendConfig.db.database }}?parseTime=true
dir: backend-services/db/migrations
table: {{ .Values.backendConfig.db.migrationsTable }}
비밀 중 하나:---
apiVersion: v1
kind: Secret
metadata:
name: {{ .Chart.Name }}-migration-secrets
annotations:
"helm.sh/hook": pre-install,pre-upgrade
"helm.sh/hook-weight": "-10"
"helm.sh/hook-delete-policy": before-hook-creation
type: Opaque
stringData:
backend-db-password: {{ .Values.backendConfig.db.password }}
git_token: {{ .Values.git.token }}
그리고 작업:apiVersion: batch/v1
kind: Job
metadata:
name: {{ .Chart.Name }}-migration-job
labels:
annotations:
"helm.sh/hook": pre-install,pre-upgrade
"helm.sh/hook-weight": "-1"
"helm.sh/hook-delete-policy": before-hook-creation
spec:
backoffLimit: 0
template:
metadata:
name: {{ .Chart.Name }}-migration-job-pod
spec:
restartPolicy: Never
containers:
- name: {{ .Chart.Name }}-db-migrations
image: projectname/sql-migrate-git:latest
command: ["/bin/sh", "-c"]
args:
- git clone --single-branch --branch {{ .Values.git.branch }} [https://{{](https://%7B%7B) .Values.git.user }}:$GIT_TOKEN@{{ .Values.git.repo }} &&
ls -l backend-services/db/migrations &&
cat /config/config.yaml &&
/bin/sql-migrate up -config=/config/config.yaml -env=main || exit 1;
/bin/sql-migrate status -config=/config/config.yaml -env=main
env:
- name: GIT_TOKEN
valueFrom:
secretKeyRef:
name: {{ .Chart.Name }}-migration-secrets
key: git_token
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: {{ .Chart.Name }}-migration-secrets
key: backend-db-password
volumeMounts:
- name: migration-config
mountPath: "/config/config.yaml"
subPath: "config.yaml"
readOnly: true
volumes:
- name: migration-config
configMap:
name: migration-config
items:
- key: "config.yaml"
path: "config.yaml"
여기에서 "helm.sh/hook-delete-policy"
을(를) annotations
에 추가하여 이전 과정에서 오류가 발생하면 작업이 실패하기 때문에 배치 과정을 시작하지 않습니다.Jenkins에서 실행:
이 갈고리들 중에서 첫 번째 비밀은 원형대로 만들어진 것
hook-weight
, 그 다음에 맵을 설정하고 마지막에 작업하는 것을 볼 수 있다.이제 배포 프로세스는 다음과 같이 보입니다.
먼저 기밀을 삭제하고 맵과 작업 자원을 설정합니다(근거
exit 1
.작업 상태 확인:
$ kk -n eks-stage-1-appname-api-ns get job
NAME COMPLETIONS DURATION AGE
appname-api-migration-job 1/1 3s 6m21s
그 로그:$ kk -n eks-stage-1-appname-api-ns logs job/appname-api-migration-job
Cloning into ‘backend-services’…
total 20
-rw-r — r — 1 root root 538 Oct 26 11:32 BS_1_init_schema.up.sql
-rw-r — r — 1 root root 180 Oct 26 11:32 BS_2_add_brand_field.up.sql
-rw-r — r — 1 root root 225 Oct 26 11:32 BS_3_alter_table.up.sql
-rw-r — r — 1 root root 194 Oct 26 11:32 BS_4_add_created_at_field.sql
-rw-r — r — 1 root root 272 Oct 26 11:32 BS_5_alter_table_nourishment_diet.up.sql
main:
dialect: mysql
datasource: backend-user:${DB_PASSWORD}@tcp(stage.backend-db3-master.example.com:3306)/dbname?parseTime=true
dir: backend-services/db/migrations
table: backend_services_migrations
Applied 0 migrations
+ — — — — — — — — — — — — — — — — — — — — — + — — — — — — — — — — — — — — — -+
| MIGRATION | APPLIED |
+ — — — — — — — — — — — — — — — — — — — — — + — — — — — — — — — — — — — — — -+
| BS_1_init_schema.up.sql | 2020–05–07 12:21:25 +0000 UTC |
| BS_2_add_brand_field.up.sql | 2020–05–12 14:31:17 +0000 UTC |
| BS_3_alter_table.up.sql | 2020–05–13 06:17:25 +0000 UTC |
| BS_4_add_created_at_field.sql | 2020–07–21 09:55:49 +0000 UTC |
| BS_5_alter_table_nourishment_diet.up.sql | 2020–07–21 09:55:49 +0000 UTC |
+ — — — — — — — — — — — — — — — — — — — — — + — — — — — — — — — — — — — — — -+
마지막 /bin/sql-migrate u
이후 마이그레이션 파일에 변경 사항이 없기 때문에 0 번의 마이그레이션을 적용했습니다.모두 완성하다.
최초 발표RTFM: Linux, DevOps, and system administration.
Reference
이 문제에 관하여(Kubernetes: Kubernetes 작업 및 Helm hook을 사용하여 SQL 마이그레이션 실행), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/setevoy/kubernetes-running-sql-migrations-with-kubernetes-job-and-helm-hook-503j텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)