Kubernetes: Kubernetes 작업 및 Helm hook을 사용하여 SQL 마이그레이션 실행
21015 단어 devopskubernetessqltutorial
![](https://s1.md5.ltd/image/42d3baf9818b7e0bb1383c6913a9c9c7.png)
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에서 실행:
![](https://s1.md5.ltd/image/ca330b1bd4407bd2d9abcd7dca036762.png)
![](https://s1.md5.ltd/image/9d296e7dd74bb5283efea782c8b8ae8c.png)
이 갈고리들 중에서 첫 번째 비밀은 원형대로 만들어진 것
hook-weight
, 그 다음에 맵을 설정하고 마지막에 작업하는 것을 볼 수 있다.이제 배포 프로세스는 다음과 같이 보입니다.
![](https://s1.md5.ltd/image/51e85412ef64050615aba0e3e9e2daf8.png)
먼저 기밀을 삭제하고 맵과 작업 자원을 설정합니다(근거
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.)