由于 Kubernetes 上的访问被拒绝,每隔 SQL 服务器部署失败
Every other SQL Server deployment fails due to access denied on Kubernetes
我正在使用以下清单将 SQL Server 2019 部署到 Kubernetes:
apiVersion : apps/v1
kind: Deployment
metadata:
name: sql
spec:
selector:
matchLabels:
app: 'sql'
template:
metadata:
labels:
app: sql
spec:
hostname: sql-dev
securityContext:
fsGroup: 10001
initContainers:
- name: volume-permissions
image: busybox
command: ["sh", "-c", "chown -R 10001:0 /var/opt/mssql"]
volumeMounts:
- mountPath: "/var/opt/mssql"
name: mssqldb
containers:
- name: sql
image: localhost:32000/sql:dev-latest
env:
- name: MSSQL_SA_PASSWORD
valueFrom:
secretKeyRef:
name: mssql
key: SA_PASSWORD
- name: ACCEPT_EULA
value: "Y"
ports:
- containerPort: 1433
resources:
limits:
memory: 2Gi
cpu: 1
volumeMounts:
- name: mssqldb
mountPath: /var/opt/mssql
volumes:
- name: mssqldb
persistentVolumeClaim:
claimName: sqldev-pvc
---
apiVersion: v1
kind: Service
metadata:
name: sql-svc
spec:
type: LoadBalancer
ports:
- protocol: TCP
port: 1433
targetPort: 1433
nodePort: 31113
selector:
app: sql
这是 pv/pvc 清单:
apiVersion: v1
kind: PersistentVolume
metadata:
name: sqldev-pv
spec:
capacity:
storage: 1Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
storageClassName: sql
hostPath:
path: /usr/sql
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: sqldev-pvc
spec:
accessModes:
- ReadWriteOnce
storageClassName: sql
resources:
requests:
storage: 1Gi
如果集群上还没有部署,则部署本身可以工作并且服务器可用。
下一次部署失败并显示以下消息:
2021-01-20 12:02:34.98 Server Error: 17113, Severity: 16, State:
2021-01-20 12:02:34.98 Server Error 5(Access is denied.) occurred while opening file '/var/opt/mssql/data/master.mdf' to obtain
configuration information at startup. An invalid startup option might
have caused the error. Verify your startup options, and correct or
remove them if necessary.
进行另一次部署或简单地用 kubectl rollout restart deployment/sql
重新启动它都很好,而下一次部署又失败了。
该模式是一致的好-坏-好-坏-...
请解释为什么会这样,我该如何解决。
更新: 显然,一个 mssql 实例专门锁定了数据库文件——这完全有道理。您不希望 brain
的 2 个实例在 childhood memories
.
的唯一实例上失控
所以我认为发生的事情是:
- 实例
A
存在并启动并且 运行
- 实例
B
部署开始并希望访问与 A
相同的卷
- 仅在创建
B
时,A
以 30 秒的宽限期终止
B
正在尝试访问 mdf,但它仍然被 A
独家锁定。
在 pod 内初始化 mssql 之前,我有一个涉及 sleep 30
bash 脚本的粗略解决方案,但现在我想研究一下,是否有更优雅的解决方案。
我解决这个问题的第一个方法是延迟 mssql 的启动时间,直到前一个 pod 使用 bash 循环终止:
echo "Waiting 35 seconds grace period."
for i in {0..35}
do
sleep 1
echo "$i seconds waited"
done
虽然这在技术上解决了问题,但它不是很优雅。如果 pod 的宽限期改为大于 35 秒,这也需要更改。
将部署策略从其隐式默认值 RollingUpdate
更改为 Recreate
,成功了。结果是,在新的 pod 启动之前,先前的 pod 被终止。
apiVersion : apps/v1
kind: Deployment
metadata:
name: sql
spec:
selector:
matchLabels:
app: 'sql'
strategy:
type: Recreate
文档:https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#recreate-deployment
我正在使用以下清单将 SQL Server 2019 部署到 Kubernetes:
apiVersion : apps/v1
kind: Deployment
metadata:
name: sql
spec:
selector:
matchLabels:
app: 'sql'
template:
metadata:
labels:
app: sql
spec:
hostname: sql-dev
securityContext:
fsGroup: 10001
initContainers:
- name: volume-permissions
image: busybox
command: ["sh", "-c", "chown -R 10001:0 /var/opt/mssql"]
volumeMounts:
- mountPath: "/var/opt/mssql"
name: mssqldb
containers:
- name: sql
image: localhost:32000/sql:dev-latest
env:
- name: MSSQL_SA_PASSWORD
valueFrom:
secretKeyRef:
name: mssql
key: SA_PASSWORD
- name: ACCEPT_EULA
value: "Y"
ports:
- containerPort: 1433
resources:
limits:
memory: 2Gi
cpu: 1
volumeMounts:
- name: mssqldb
mountPath: /var/opt/mssql
volumes:
- name: mssqldb
persistentVolumeClaim:
claimName: sqldev-pvc
---
apiVersion: v1
kind: Service
metadata:
name: sql-svc
spec:
type: LoadBalancer
ports:
- protocol: TCP
port: 1433
targetPort: 1433
nodePort: 31113
selector:
app: sql
这是 pv/pvc 清单:
apiVersion: v1
kind: PersistentVolume
metadata:
name: sqldev-pv
spec:
capacity:
storage: 1Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
storageClassName: sql
hostPath:
path: /usr/sql
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: sqldev-pvc
spec:
accessModes:
- ReadWriteOnce
storageClassName: sql
resources:
requests:
storage: 1Gi
如果集群上还没有部署,则部署本身可以工作并且服务器可用。 下一次部署失败并显示以下消息:
2021-01-20 12:02:34.98 Server Error: 17113, Severity: 16, State: 2021-01-20 12:02:34.98 Server Error 5(Access is denied.) occurred while opening file '/var/opt/mssql/data/master.mdf' to obtain configuration information at startup. An invalid startup option might have caused the error. Verify your startup options, and correct or remove them if necessary.
进行另一次部署或简单地用 kubectl rollout restart deployment/sql
重新启动它都很好,而下一次部署又失败了。
该模式是一致的好-坏-好-坏-...
请解释为什么会这样,我该如何解决。
更新: 显然,一个 mssql 实例专门锁定了数据库文件——这完全有道理。您不希望 brain
的 2 个实例在 childhood memories
.
所以我认为发生的事情是:
- 实例
A
存在并启动并且 运行 - 实例
B
部署开始并希望访问与A
相同的卷
- 仅在创建
B
时,A
以 30 秒的宽限期终止 B
正在尝试访问 mdf,但它仍然被A
独家锁定。
在 pod 内初始化 mssql 之前,我有一个涉及 sleep 30
bash 脚本的粗略解决方案,但现在我想研究一下,是否有更优雅的解决方案。
我解决这个问题的第一个方法是延迟 mssql 的启动时间,直到前一个 pod 使用 bash 循环终止:
echo "Waiting 35 seconds grace period."
for i in {0..35}
do
sleep 1
echo "$i seconds waited"
done
虽然这在技术上解决了问题,但它不是很优雅。如果 pod 的宽限期改为大于 35 秒,这也需要更改。
将部署策略从其隐式默认值 RollingUpdate
更改为 Recreate
,成功了。结果是,在新的 pod 启动之前,先前的 pod 被终止。
apiVersion : apps/v1
kind: Deployment
metadata:
name: sql
spec:
selector:
matchLabels:
app: 'sql'
strategy:
type: Recreate
文档:https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#recreate-deployment