localhost
폴더를 다른 위치로 복사하기 위해 Ansible 스크립트를 실행하고 있습니다 . 하지만,
- name: Copy Network
become: yes
become_user: root
copy:
src: /d/
dest: "/dest/d/"
mode: 0644
tags: [network]
나에게주고있다 [Errno 13] Permission denied: b'd/f1'
. become_user
명령이 루트로 실행될 것으로 예상했지만 작동하지 않았습니다. 이 파일의 권한은 입니다 0600(root:root)
.
Ansible을 사용하여 복사하기 위해 이 파일에 액세스할 수 있는 방법을 알려 주시겠습니까?
메모:
sudo ansible-playbook p.yml
sudo
완벽하게 작동하지만 필요하지 않고 ansible에 트릭이 있는 경우 ansible 명령과 함께 사용하고 싶지 않습니다 .command: cp -r /d/ /dest/d/
sudo
ansible 명령( )에 추가하지 않고 작동합니다ansible-playbook p.yml
. 그러나 멱등성 및 모듈에 작업에 필요한 옵션이 있기command
때문에 도움을 줄 수 있다면 사용하고 싶지 않습니다 .copy
mode
답변1
업데이트: 로컬 호스트 마스터에서 권한을 루트로 승격할 수 있는 경우 해결책은 설정하는 것입니다 remote_src: true
(credit @ivandov).
- copy:
src: /d/
dest: /dest/d/
mode: '0644'
remote_src: true
become: true
become_user: root
아래 세부정보에서는 localhost에서 루트로 에스컬레이션할 수 없는 경우에 대해 설명합니다. localhost의 파일이 주어지면
shell> ll /tmp/test/d/f1
-rw-r----- 1 root root 0 Aug 25 23:23 /tmp/test/d/f1
모듈복사예상대로 작동
- copy:
src: /tmp/test/d/
dest: /tmp/test/dest/
become: true
become_user: root
먼저, 파일 읽기를 시도했지만 실패합니다.
치명적: [localhost]: 실패했습니다! => msg: '''/tmp/test/d/f1'' 파일을 읽는 동안 오류가 발생했습니다. [Errno 13] 권한이 거부되었습니다: b''/tmp/test/d/f1''. [Errno 13] 권한이 거부되었습니다: b''/tmp/test/d/f1'''
기본적으로 모듈복사다음에서 파일을 복사합니다.소스(원격 서버에 복사할 파일의 로컬 경로)목적지(파일을 복사해야 하는 원격 절대 경로). 이 경우 become: true
Ansible은 원격 호스트에 대한 권한을 에스컬레이션하지만 로컬 호스트 마스터에서는 에스컬레이션하지 않음을 의미합니다. 작업이 localhost에서 실행되고 있다는 사실에도 불구하고, 즉 마스터와 원격 호스트가 모두 localhost라는 사실에도 불구하고 remote_src: true
설정이 없으면 become: true
파일을 읽는 것이 아닌 쓰기에만 적용됩니다. localhost 설정에서 루트로 에스컬레이션할 수 없는 경우remote_src: true
- copy:
src: /tmp/test/d/
dest: /tmp/test/dest/
remote_src: true
become: true
become_user: root
실패할 것이다
치명적: [localhost]: 실패했습니다! => 변경됨=false ansible_facts: discover_interpreter_python: /usr/bin/python3 module_stderr: |- sudo: 비밀번호가 필요함 module_stdout: '' msg: |- 모듈 오류 정확한 오류는 stdout/stderr을 참조하세요. rc: 1
큐:"해결책이 있나요?"
A: 루트로 에스컬레이션하지 않으면 해결 방법이 없습니다. 파일의 소유권과 권한을 위반하게 됩니다. 예를 들어 컨트롤러에 파일이 있는 경우
shell> ll f1
-rw-rw---- 1 root root 0 Sep 13 18:17 f1
아래 플레이북은 권한이 없는 사용자에 의해 시작되었습니다.
shell> cat playbook.yml
- hosts: test_01
become: true
tasks:
- copy:
src: f1
dest: /tmp
충돌할 것이다
TASK [copy] ****
fatal: [test_01]: FAILED! =>
msg: 'an error occurred while trying to read the file ''/scratch/f1'':
[Errno 13] Permission denied: b''/scratch/f1'''
localhost 마스터에서 루트로 에스컬레이션할 수 없는 경우 해결 방법은 플레이북을 실행하는 사용자가 파일을 읽을 수 있도록 만드는 것입니다.
답변2
Vladimir의 답변을 바탕으로 실제로 간단한 해결 방법이 있습니다!
아래의 설명(그리고 굵은 글씨로 추가한 강조 부분)이 핵심이었습니다.
모듈 복사에서 be: yes는 파일 쓰기에만 적용됩니다.그것을 읽는 것이 아니라.
remote_src: true
파일을 로컬로 복사하는 경우에도 을 사용하세요 . 이로 인해 은(는 ) 원격 시스템으로 처리되고 권한 에스컬레이션이 올바르게 적용되므로 로컬 시스템에서 파일/디렉터리를 become
읽을 때 권한이 올바르게 에스컬레이션 됩니다.src
src
- name: Copy Network
become: yes
become_user: root
copy:
src: /d/
dest: "/dest/d/"
remote_src: true # this allows become to work as expected
mode: 0644
tags: [network]
답변3
tl;dr - Ansible은 become: root
플레이북을 실행하는 Ansible 호스트가 아닌 대상 머신에 적용됩니다. 해결 방법이 가능합니다.
나는 답을 썼다여기단일 파일에 대해 이 문제를 해결 하려면: 플레이북을 실행하는 Ansible 호스트는 root
; become: root
이는 대상 시스템에만 적용됩니다. 원래 질문에는 둘 다 있지만 이 동작은 여전히 적용된다고 생각합니다. 권한이 없는 '소스'와 권한이 있는 대상 localhost
으로 생각하십시오 .root
root
솔루션은 필요한 파일을 메모리에 사용합니다 delegate_to: localhost
. slurp
즉, 로컬에서 마법을 작동한 다음 저장된 파일을 대상 컴퓨터에 쓸 수 있습니다 delegate_to:
.become: root
원래 질문에서는 디렉터리에 대해 이 작업을 수행하는 방법에 대해 묻습니다. slurp
디렉터리 지정에 대해서도 논의되었습니다.여기이는 파일별 솔루션과 결합될 때 적절한 시작점을 제공해야 합니다 slurp
. 해당 답변에 대한 @guzmonne의 의견을 참고하세요. 파일별 해결 방법을 사용하기 전에 파일 목록을 구성합니다 slurp
(훌륭하지는 않지만 파일/디렉터리 권한을 변경하는 것보다 나을 수 있음).