Ansible Playbook执行报错:sudo需密码,求排查解决
问题:执行Kubernetes部署Ansible Playbook时出现sudo密码要求错误
我用Ansible Playbook部署Kubernetes集群时,遇到如下报错:
FAILED! => {"changed": false, "module_stderr": "sudo: a password is required\n"}
我已持有目标主机的私钥,但不清楚配置哪里缺失,需要排查解决。
涉及的Playbook内容
- name: Basic Setup hosts: all ## run on all hosts gather_facts: false become: true ## 切换为sudo/超级用户权限 vars: ansible_python_interpreter: /usr/bin/python3 tasks: - name: 等待200秒直到22端口开放并包含"OpenSSH" ansible.builtin.wait_for: port: 22 host: "{{ (ansible_ssh_host|default(ansible_host))|default(inventory_hostname) }}" search_regex: OpenSSH delay: 10 timeout: 200 vars: ansible_connection: local - name: 设置主机名 ansible.builtin.hostname: name: "{{ node_hostname }}" - name: 复制/etc/hosts模板 ansible.builtin.copy: backup: true src: ./files/hosts dest: /tmp/hosts - name: 插入/更新/etc/hosts配置 ansible.builtin.blockinfile: block: "{{ lookup('file', './files/hosts') }}" path: /etc/hosts backup: yes - name: 禁用所有节点的swap ansible.builtin.shell: swapoff -a - name: 配置内核模块依赖 ansible.builtin.shell: cmd: | cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf overlay br_netfilter EOF - name: 加载overlay模块 community.general.modprobe: name: overlay state: present - name: 加载br_netfilter模块 community.general.modprobe: name: br_netfilter state: present - name: 配置sysctl参数 ansible.builtin.shell: cmd: | cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-ip6tables = 1 net.ipv4.ip_forward = 1 EOF - name: 无需重启应用sysctl参数 ansible.builtin.shell: sysctl --system - name: 创建containerd配置文件 ansible.builtin.shell: mkdir -p /etc/containerd && touch /etc/containerd/config.toml - name: 安装containerd依赖包 ansible.builtin.apt: pkg: - apt-transport-https - ca-certificates - curl - gnupg - lsb-release - name: 添加Docker GPG密钥 apt_key: url: https://download.docker.com/linux/ubuntu/gpg state: present - name: 添加Docker软件源 apt_repository: repo: deb https://download.docker.com/linux/ubuntu jammy stable state: present - name: 更新apt缓存并安装docker-ce apt: name: docker-ce state: latest update_cache: true - name: 安装containerd.io ansible.builtin.apt: pkg: - containerd.io - name: 启用并启动containerd服务 ansible.builtin.systemd: name: containerd daemon_reload: yes state: started enabled: yes - name: 配置containerd使用systemd作为cgroup驱动 ansible.builtin.copy: backup: true src: ./files/containerd-config.toml dest: /etc/containerd/config.toml - name: 重启containerd服务加载新配置 ansible.builtin.systemd: state: restarted daemon_reload: yes name: containerd ## Kubernetes kubeadm相关配置 - name: 下载Google Cloud公钥 ansible.builtin.apt_key: url: https://packages.cloud.google.com/apt/doc/apt-key.gpg state: present - name: 添加Kubernetes软件源 ansible.builtin.apt_repository: repo: deb https://apt.kubernetes.io/ kubernetes-xenial main state: present filename: kubernetes - name: 安装kubelet、kubeadm、kubectl ansible.builtin.apt: pkg: - kubelet - kubeadm - kubectl - name: 锁定kubelet、kubeadm、kubectl版本 ansible.builtin.shell: apt-mark hold kubelet kubectl kubeadm - name: 配置控制平面节点 hosts: master become: true tasks: - name: 初始化kubeadm ansible.builtin.shell: sudo kubeadm init --pod-network-cidr=10.244.0.0/16 --control-plane-endpoint "{{ansible_host}}:6443" - name: 创建~/.kube目录 ansible.builtin.file: path: ~/.kube state: directory mode: "0755" - name: 复制kubeconfig文件到用户目录 shell: sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config - name: 设置kubeconfig文件权限 shell: sudo chown $(id -u):$(id -g) $HOME/.kube/config - name: 安装flannel网络插件 ansible.builtin.shell: kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/v0.20.2/Documentation/kube-flannel.yml - name: 复制kubeconfig文件到本地 ansible.builtin.fetch: src: $HOME/.kube/config dest: /tmp/kubeconfig/ flat: yes - name: 生成Worker节点加入集群的令牌命令 ansible.builtin.shell: sudo kubeadm token create --print-join-command register: join_node_token - name: 保存加入命令为变量 ansible.builtin.set_fact: join_node: "{{ join_node_token.stdout_lines[0] }}" - name: 配置Worker节点 hosts: workers become: true tasks: - name: 将Worker节点加入集群 shell: "sudo {{ hostvars['control_plane'].join_node }}"
排查与解决方法
1. 配置目标主机sudo免密权限
Playbook已启用become: true,但目标主机的登录用户可能未配置sudo免密。登录目标主机,编辑/etc/sudoers文件(建议用visudo命令避免语法错误),添加以下内容(假设登录用户为ubuntu):
ubuntu ALL=(ALL) NOPASSWD:ALL
2. 移除Playbook中冗余的sudo命令
由于become: true已让所有模块以sudo权限执行,shell任务中额外添加的sudo会重复触发验证。建议移除冗余sudo,并尽量用Ansible内置模块替代shell命令:
比如将原shell写入文件的命令改为copy模块:
- name: 配置内核模块依赖 ansible.builtin.copy: content: | overlay br_netfilter dest: /etc/modules-load.d/k8s.conf mode: '0644'
3. 确认Ansible连接时指定私钥路径
在inventory文件或ansible.cfg中明确私钥路径:
- inventory文件示例:
[all] master ansible_host=xxx.xxx.xxx.xxx ansible_user=ubuntu ansible_ssh_private_key_file=/path/to/your/private_key.pem workers ansible_host=yyy.yyy.yyy.yyy ansible_user=ubuntu ansible_ssh_private_key_file=/path/to/your/private_key.pem
- 或在
ansible.cfg全局配置:
[defaults] private_key_file = /path/to/your/private_key.pem
4. 手动验证连接与sudo权限
先通过SSH手动测试目标主机:
ssh -i /path/to/private_key.pem ubuntu@target_host_ip sudo whoami
如果sudo whoami无需输入密码,说明免密配置生效;若仍需密码,优先解决此问题后再执行Playbook。
内容的提问来源于stack exchange,提问作者Marjo
相关产品推荐
相关产品推荐

