从 6 小时开始,我试图找出 ansible 希望在 ubuntu 16 上与我的 mariadb 一起工作。
当我手动登录服务器时
MySQL -u someuser -p
一切正常
当我尝试使用 ansible 脚本访问服务器时:
- name: Create mysql database
mysql_user: name=someuser state=present password=somepw
它的抱怨:
致命: [IP]: 失败! => {"已更改": 假, "失败": 真, "msg": "无法连接到数据库,请检查login_user和 login_password是正确的,或者/home/someuser/.my.cnf 有 凭据。异常消息:(2002,\"无法连接到本地 MySQL 服务器通过套接字'/tmp/mysql.sock' (2)\")"}
然后我尝试将 .my.cnf 放入远程服务器上的目录中,就像它试图告诉我的那样。 我还添加了login_user和login_password。无济于事。
该文件如下所示:
/home/someuser/.my.cnf
[client]
user=someuser
password=somepw
"好吧"我想。也许凭据在 ansible 脚本和 conf 文件中加倍。我试图离开 conf 文件或跳过 ansible 脚本中的凭据。没有帮助
我还重新启动了mysql服务器。无济于事。奇怪的是,从服务器本身来看,一切都可以使用mysql shell。 我真的很难找到解决方案。这不应该像魅力一样工作吗?
好的,想通了。在我的情况下,Ubuntu 16 将套接字文件放入
/var/run/mysqld/mysqld.sock
Ansible 没有预料到的地方。 所以对我来说,把它login_unix_socket放进剧本(ansible 脚本)是有效的
- name: Create mysql database
mysql_db:
login_unix_socket: /var/run/mysqld/mysqld.sock
name: projectname
state: present
并放置如上所述的 .my.cnf。
需要远程主机上的 MySQLdb Python 包。对于 Ubuntu,这就像 apt-get install python-mysqldb 一样简单。(见上文)对于 CentOS/Fedora,这就像 yum 安装 MySQL-python 一样简单。(见百胜。
传递凭据时,login_password和login_user都是必需的。如果不存在,模块将尝试从 ~/.my.cnf 读取凭据,最后回退到使用 MySQL 默认登录名"root">
而不带密码
之后,请使用以下代码与数据库连接:
mysql_user:
name: root
password: deepak
login_unix_socket: /var/run/mysqld/mysqld.sock
请从my.cnf
验证您的套接字文件并进行更新。
如果从remote_host运行行动手册,则可能会收到错误
"msg": "unable to connect to database, check login_user and login_password are correct or /home/********/.my.cnf has the credentials. Exception message: (1045, "Access denied for user '********@'localhost' (using password: NO)")"
要解决此问题,您必须允许远程主机连接到 mysql。
让我们先深入了解mysql_db
模块:
要注意的主要参数是login_host
、login_user
和login_password
。
最简单的方法(在本例中为创建数据库)是:
- name: Create database
mysql_db:
name: "{{ the_name_of_db_to_create }}"
login_host: "{{ the_instance_where_db_needs_creating }}"
login_user: "{{ the_master_username_for_instance }}"
login_password: "{{ the_master_password_for_instance }}"
state: present
在这种情况下,我们不需要$HOME/.my.conf
因为login_user
和login_password
优先。
PS:请务必仅在state: present
不存在时才使用它来创建 db。
那我们什么时候需要login_unix_socket
呢?
答案就在文档本身中。
The path to a Unix domain socket for **local** connections.
是的,仅当您的数据库实例驻留在执行 ansible 的同一服务器中时。
如果您尝试添加此属性并尝试连接到远程实例,它将失败并显示 OP 提到的相同错误消息,因为此参数似乎覆盖了login_host
以localhost
。
那我们什么时候需要$HOME/.my.conf
呢?
当您保存 ansible 剧本的 git 存储库过于敏感并且出于任何原因无法在那里留下用户名和密码等详细信息时。您仍然可以隐藏在 env var 后面或在执行过程中使用 var 文件等。但您可以决定手动将$HOME/.my.conf
添加到服务器中,也可以作为一次性 ansible 操作添加。文件的格式为:
[client]
user=the_master_username_for_instance
password=the_master_password_for_instance
不用说,添加此文件时,不需要参数login_user
和login_password
。
当我既不提及参数也不提及 conf 文件时会发生什么?
然后,Ansible 将尝试使用用户名root
而不是密码。
现在,让我们看看如何使用mysql_user
模块创建新用户
请注意,该模块不仅用于创建新用户。但这是迄今为止最受追捧的功能。
最简单的方法是:
- name: Create user
mysql_user:
name: "{{ the_name_of_user_to_create }}"
login_host: "{{ the_instance_where_db_needs_creating }}"
login_user: "{{ the_master_username_for_instance }}"
login_password: "{{ the_master_password_for_instance }}"
state: present
所有参数都遵循与上述mysql_db模块相同的规则。
现在,这将创建user@'localhost'
.如果要创建user@'some_other_host'
怎么办?
在这里:
- name: Create user
mysql_user:
name: "{{ the_name_of_user_to_create }}"
password: "{{ the_password_for__the_new_user }}"
login_host: "{{ the_instance_where_db_is }}"
login_user: "{{ the_master_username_for_instance }}"
login_password: "{{ the_master_password_for_instance }}"
state: present
host: "{{ the_client_host }}"
请注意,您可以使用%
the_client_host
以允许从任何位置进行访问。
就我而言,我使用的是 CentOS,而在 CentOS 中,袜子路径与我想象的完全不同,
找到了路径
ps -ef | grep mariadb
最后问题得到了如下修复,
- name: Create database
mysql_db:
name: "{{ db_name }}"
state: present
login_unix_socket: /var/lib/mysql/mysql.sock
我知道这是一个相当古老的问题。我最近遇到了同样的情况,并认为这可能对追求同样情况的人有所帮助。
找不到/root/.my.cnf。异常消息
我什么时候收到此错误的。
- name: "Mysql Configuration - Resetting RootPassword"
mysql_user:
login_user: root
login_password: ''
name: root
host: localhost <<===================== Cause of Error.
password: "{{mysql_root_password}}"
- name: "Mysql Configuration - Creating Wordpress Database"
mysql_db:
login_user: root
login_password: "{{mysql_root_password}}"
db: "{{wp_database}}"
state: present
fatal: [centos-client.ansible.lab]: FAILED! => {"changed": false, "msg": "无法找到/root/.my.cnf。异常消息:(1045, \"拒绝用户'root'@'本地主机'的访问(使用密码:YES)\")"}
**这就是我修复它的方式**
- name: "Mysql Configuration - Resetting RootPassword"
mysql_user:
login_user: root
login_password: ''
name: root
host_all: yes <<===================== Fix
password: "{{mysql_root_password}}"
- name: "Mysql Configuration - Creating Wordpress Database"
mysql_db:
login_user: root
login_password: "{{mysql_root_password}}"
db: "{{wp_database}}"
state: present
请注意,在某些发行版(如 ubuntu)中,您可能需要使用 login_unix_socket 来指定 mysql 套接字的确切位置。
值得注意的是,ansible只从文件中获取登录名和密码.my.cnf
。因此,如果您有这样的.my.cnf
:
[client]
host=10.0.0.4
user=root
port=3310
password=strongpassword
[mysql]
database=irk
它使您可以轻松地从控制台连接到mysql,只需键入mysql
即可。
但是对于 ansible,您必须在剧本文件中指定主机和端口:
- mysql_user:
...
login_host: 10.0.0.4
login_port: 3310
Per @Jurudocs 和 @fuji-komalan 使用login_unix_socket
模块参数并可能添加host_all: yes
。
这是我的最终配置:
- name: Change root password for MariaDB
mysql_user:
name: root
password: <password>
login_unix_socket: /var/lib/mysql/mysql.sock
host_all: yes
- 路径
/var/lib/mysql/mysql.sock
而不是/var/run/mysqld/mysqld.sock
- 使用参数
host_all
并将其设置为yes
谷歌表示,
在 CentOS/RHEL/Rocky Linux 上,默认的套接字文件是
/var/lib/mysql/mysql.sock
。
这在 AL2023 上对我有用。