Docker Mysql 官方镜像没有在 kubernetes 中创建用户
Docker Mysql official image not creating user in kubernetes
我正在尝试使用来自 DockerHub 的官方 Mysql 图像通过 StatefulSet 在 k8s 中部署一个 mysql 实例。我正在关注 DockerHub 的图像文档并提供 MYSQL_ROOT_PASSWORD
、MYSQL_USER
和 MYSQL_PASSWORD
环境变量,因此应该自动创建用户,但事实并非如此。我在容器日志中看到的错误是 root
用户在创建 MYSQL_USER
中提供的用户时无法连接。
2021-09-14 17:28:20+00:00 [Note] [Entrypoint]: Creating user foo_user
2021-09-14T17:28:20.860763Z 5 [Note] Access denied for user 'root'@'localhost' (using password: YES)
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
经过一些调查,我注意到当环境变量的值取自 k8s 机密时会出现问题,但如果我在 StatefulSet 的清单中对它们的值进行硬编码,它就可以正常工作。您可以在下面看到我当前的代码:
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
labels:
app: mysql
spec:
replicas: 1
serviceName: mysql-svc
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: "mysql:latest"
env:
- name: MYSQL_DATABASE
value: 'foo_db'
- name: MYSQL_USER
value: 'foo_user'
- name: MYSQL_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-sec
key: MYSQL_PASSWORD
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-sec
key: MYSQL_ROOT_PASSWORD
ports:
- containerPort: 3306
protocol: TCP
volumeMounts:
- name: mysql-db
mountPath: /var/lib/mysql
subPath: mysql
volumeClaimTemplates:
- metadata:
name: mysql-db
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 4Gi
和 secrets.yml
文件:
apiVersion: v1
kind: Secret
metadata:
name: mysql-sec
labels:
app: mysql
type: Opaque
data:
MYSQL_PASSWORD: ***************************
MYSQL_ROOT_PASSWORD: ***************************
我也尝试先创建密文以确保密文在 pod 启动时已经存在,但没有成功。
有什么想法吗?
我终于找到了问题的根本原因,它与机密无关...问题与为密码选择的值的“复杂性”有关。我选择了一个由在线工具自动生成的强密码,类似于 !6Y*]q~x+xG{9HQ~
,并且出于某种未知原因,此谷使 mysql docker 图像的 /entrypoint.sh
脚本失败出现上述错误 Access denied for user 'root'@'localhost' (using password: YES)
。然而,即使脚本失败,容器和 mysql 服务器已启动&运行,我能够潜入并成功执行 mysql -u root --password="$MYSQL_ROOT_PASSWORD"
,所以我很清楚错误位于此脚本及其扩展和使用此环境变量值的方式中。在用一个“不太复杂”的密码值交换密码值后,它就像一个魅力。
这可能取决于您创建 Secret
的准确程度。事实上,如果您在创建 Secret
.
时使用单引号,那么包含某些特殊字符的密码应该不是问题
我相信 official kubernetes documentation 的这个片段应该可以回答您的问题:
Note:
Special characters such as $
, \
, *
, =
, and !
will be
interpreted by your
shell and require
escaping. In most shells, the easiest way to escape the password is to
surround it with single quotes ('
). For example, if your actual
password is S!B\*d$zDsb=
, you should execute the command this way:
kubectl create secret generic dev-db-secret --from-literal=username=devuser --from-literal=password='S!B\*d$zDsb='
You do not need to escape special characters in passwords from files
(--from-file
).
请注意存储在 Secret
中的值,例如如下片段所示:
type: Opaque
data:
MYSQL_PASSWORD: ***************************
MYSQL_ROOT_PASSWORD: ***************************
是 base64
编码的字符串。因此,如果您在将它们放入 secret.yaml
:
之前正确编码它们
echo '!6Y*]q~x+xG{9HQ~' | base64
你不应该 运行 遇到任何问题。
我正在尝试使用来自 DockerHub 的官方 Mysql 图像通过 StatefulSet 在 k8s 中部署一个 mysql 实例。我正在关注 DockerHub 的图像文档并提供 MYSQL_ROOT_PASSWORD
、MYSQL_USER
和 MYSQL_PASSWORD
环境变量,因此应该自动创建用户,但事实并非如此。我在容器日志中看到的错误是 root
用户在创建 MYSQL_USER
中提供的用户时无法连接。
2021-09-14 17:28:20+00:00 [Note] [Entrypoint]: Creating user foo_user
2021-09-14T17:28:20.860763Z 5 [Note] Access denied for user 'root'@'localhost' (using password: YES)
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
经过一些调查,我注意到当环境变量的值取自 k8s 机密时会出现问题,但如果我在 StatefulSet 的清单中对它们的值进行硬编码,它就可以正常工作。您可以在下面看到我当前的代码:
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
labels:
app: mysql
spec:
replicas: 1
serviceName: mysql-svc
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: "mysql:latest"
env:
- name: MYSQL_DATABASE
value: 'foo_db'
- name: MYSQL_USER
value: 'foo_user'
- name: MYSQL_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-sec
key: MYSQL_PASSWORD
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-sec
key: MYSQL_ROOT_PASSWORD
ports:
- containerPort: 3306
protocol: TCP
volumeMounts:
- name: mysql-db
mountPath: /var/lib/mysql
subPath: mysql
volumeClaimTemplates:
- metadata:
name: mysql-db
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 4Gi
和 secrets.yml
文件:
apiVersion: v1
kind: Secret
metadata:
name: mysql-sec
labels:
app: mysql
type: Opaque
data:
MYSQL_PASSWORD: ***************************
MYSQL_ROOT_PASSWORD: ***************************
我也尝试先创建密文以确保密文在 pod 启动时已经存在,但没有成功。
有什么想法吗?
我终于找到了问题的根本原因,它与机密无关...问题与为密码选择的值的“复杂性”有关。我选择了一个由在线工具自动生成的强密码,类似于 !6Y*]q~x+xG{9HQ~
,并且出于某种未知原因,此谷使 mysql docker 图像的 /entrypoint.sh
脚本失败出现上述错误 Access denied for user 'root'@'localhost' (using password: YES)
。然而,即使脚本失败,容器和 mysql 服务器已启动&运行,我能够潜入并成功执行 mysql -u root --password="$MYSQL_ROOT_PASSWORD"
,所以我很清楚错误位于此脚本及其扩展和使用此环境变量值的方式中。在用一个“不太复杂”的密码值交换密码值后,它就像一个魅力。
这可能取决于您创建 Secret
的准确程度。事实上,如果您在创建 Secret
.
我相信 official kubernetes documentation 的这个片段应该可以回答您的问题:
Note:
Special characters such as
$
,\
,*
,=
, and!
will be interpreted by your shell and require escaping. In most shells, the easiest way to escape the password is to surround it with single quotes ('
). For example, if your actual password isS!B\*d$zDsb=
, you should execute the command this way:kubectl create secret generic dev-db-secret --from-literal=username=devuser --from-literal=password='S!B\*d$zDsb='
You do not need to escape special characters in passwords from files (
--from-file
).
请注意存储在 Secret
中的值,例如如下片段所示:
type: Opaque
data:
MYSQL_PASSWORD: ***************************
MYSQL_ROOT_PASSWORD: ***************************
是 base64
编码的字符串。因此,如果您在将它们放入 secret.yaml
:
echo '!6Y*]q~x+xG{9HQ~' | base64
你不应该 运行 遇到任何问题。