Ansible使用become_user创建CKAN用户及虚拟环境报错求助
问题分析与修复方案
首先说你遇到的核心问题:为什么become_user: ckan执行virtualenv会报错,但命令行su -s /bin/bash - ckan却能正常工作?
原因很简单:你给CKAN用户设置的登录shell是/sbin/nologin,这个shell的作用就是禁止用户登录执行命令。当你用su -s /bin/bash时,手动指定了用bash来运行后续操作,绕过了用户的默认shell;但Ansible的become_user默认会使用目标用户的登录shell来执行任务,/sbin/nologin根本没法执行virtualenv这类命令,自然就报错了。
除此之外,你的任务还有几个明显的问题,导致即使shell的问题解决了,后续步骤也跑不通:
- 每个Ansible任务都是独立的进程,单独执行
. default/bin/activate只会在当前任务的进程里生效,下一个任务的pip命令根本不会用这个虚拟环境; - 执行
virtualenv时没指定工作目录,它会在Ansible的当前工作目录(通常是远程主机的/root)创建,而不是你想要的/usr/lib/ckan; command模块不能执行shell内置命令(比如./source),得用shell模块才行。
修正后的完整任务
- name: Create CKAN system user user: name: ckan comment: "CKAN Service User" # 这里可以暂时把shell改成bash,方便后续操作;如果想保持nologin,看下面的说明 shell: /bin/bash create_home: yes home: /usr/lib/ckan state: present - name: Fix permissions for CKAN home directory file: path: /usr/lib/ckan mode: u=rwX,g=rX,o=rX recurse: yes owner: ckan group: ckan - name: Setup Python virtualenv and install base dependencies shell: | virtualenv --no-site-packages default source default/bin/activate && pip install setuptools==36.1 args: chdir: /usr/lib/ckan become: yes become_user: ckan # 如果不想修改CKAN用户的默认shell为bash,就添加这行,临时指定用bash执行 # become_flags: "-s /bin/bash"
关键修复点解释
解决shell限制问题:
- 方案一:直接把CKAN用户的shell改成
/bin/bash,适合后续需要频繁用这个用户执行命令的场景; - 方案二:保持用户默认的
/sbin/nologin,但在become时添加become_flags: "-s /bin/bash",让Ansible临时用bash来执行这个任务,这样既保证用户不能登录,又能正常执行命令。
- 方案一:直接把CKAN用户的shell改成
合并虚拟环境操作:
- 把创建虚拟环境和安装setuptools放在同一个
shell任务里,用&&串联命令,确保所有操作都在同一个进程中完成,这样source激活的虚拟环境能直接被后续的pip命令使用,避免进程上下文丢失的问题。
- 把创建虚拟环境和安装setuptools放在同一个
指定工作目录:
- 通过
chdir参数明确指定命令在/usr/lib/ckan下执行,保证虚拟环境创建在CKAN用户的家目录里,而不是其他地方。
- 通过
内容的提问来源于stack exchange,提问作者Florian Mozart
相关产品推荐
相关产品推荐

