由于 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.

的唯一实例上失控

所以我认为发生的事情是:

  1. 实例 A 存在并启动并且 运行
  2. 实例 B 部署开始并希望访问与 A
  3. 相同的卷
  4. 仅在创建 B 时,A 以 30 秒的宽限期终止
  5. 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