Làm thế nào để sử dụng sudo bên trong một container docker?


259

Thông thường, các container docker được chạy bằng root người dùng . Tôi muốn sử dụng một người dùng khác, không có vấn đề gì khi sử dụng chỉ thị USER của docker. Nhưng người dùng này sẽ có thể sử dụng sudo bên trong container. Lệnh này bị thiếu.

Đây là một Dockerfile đơn giản cho mục đích này:

FROM ubuntu:12.04

RUN useradd docker && echo "docker:docker" | chpasswd
RUN mkdir -p /home/docker && chown -R docker:docker /home/docker

USER docker
CMD /bin/bash

Chạy container này, tôi đăng nhập bằng 'docker' của người dùng. Khi tôi cố gắng sử dụng sudo, lệnh không được tìm thấy. Vì vậy, tôi đã cố gắng cài đặt gói sudo bên trong Dockerfile của mình bằng cách sử dụng

RUN apt-get install sudo

Điều này dẫn đến việc không thể định vị gói sudo


Chỉ cần cung cấp cho nhóm sudo cho người dùng. Askubfox.com/questions/7477/ trộm
Regan

Câu trả lời:


242

Chỉ có nó. Như regan đã chỉ ra, tôi đã phải thêm người dùng vào nhóm sudoers. Nhưng lý do chính là tôi đã quên cập nhật bộ đệm lưu trữ, vì vậy apt-get không thể tìm thấy gói sudo. Nó đang làm việc bây giờ. Đây là mã hoàn thành:

FROM ubuntu:12.04

RUN apt-get update && \
      apt-get -y install sudo

RUN useradd -m docker && echo "docker:docker" | chpasswd && adduser docker sudo

USER docker
CMD /bin/bash

8
không hoạt động trong centos. các adduserlệnh spits ra việc sử dụng trợ giúp chouseradd
Emad

Đối với CentOS, bạn có thể thêm người dùng và nhóm, sau đó tạo tệp shard bên dưới /etc/sudoers.d/và đặt quyền cho 440tệp đó. Sau đó, người dùng sẽ có quyền truy cập sudo theo CentOS, 6 trở lên. 5 bạn sẽ phải thêm #includedir /etc/sudoers.dchỉ thị vào/etc/sudoers
FilBot3

Không làm việc cho tôi. Tôi có những lỗi đó: E: Không thể mở tệp khóa / var / lib / apt / list / lock - open (13: Quyền bị từ chối) E: Không thể khóa thư mục / var / lib / apt / list /
Marosinho

1
Điều này dường như không hoạt động cho hình ảnh
docker

100

Khi không có sudo hay apt-get trong container, bạn cũng có thể nhảy vào chạy container với tư cách người dùng root bằng lệnh

docker exec -u root -t -i container_id /bin/bash

Đây là một giải pháp tốt hơn nhiều cho những gì OP có thể muốn đạt được, mặc dù câu trả lời được chấp nhận đưa ra giải pháp được yêu cầu. Ít nhất, đó là câu trả lời tôi đang tìm kiếm!
spikyjt

79

Các câu trả lời khác không làm việc cho tôi. Tôi tiếp tục tìm kiếm và tìm thấy một bài viết trên blog bao gồm cách một nhóm đang chạy không root bên trong một container docker.

Đây là phiên bản TL; DR:

RUN apt-get update \
 && apt-get install -y sudo

RUN adduser --disabled-password --gecos '' docker
RUN adduser docker sudo
RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers

USER docker

# this is where I was running into problems with the other approaches
RUN sudo apt-get update 

Tôi đã sử dụng FROM node:9.3cho việc này, nhưng tôi nghi ngờ rằng các cơ sở container tương tự khác cũng sẽ hoạt động.


Tôi đang sử dụng ubuntu:bionic-20180724.1. Tôi đã sử dụng phương pháp này nhưng sau những điều trên, nó không cho phép tôi cài đặt gói khác. Tôi đã thêm một dòng vào bên trên Dockerfileđể cài đặt gói với : RUN apt-get install -y tree. Tuy nhiên, nó đã cho tôi thông báo lỗi này:Step xxxx/xxxx : RUN apt-get install -y tree ---> Running in j5e6gsvwfafa Reading package lists... E: Could not open lock file /var/lib/apt/lists/lock - open (13: Permission denied) E: Unable to lock directory /var/lib/apt/lists/
edesz

1
@WR Tôi nghĩ bạn cần thay đổi dòng đó để đọc RUN sudo apt-get install -y tree. Sau khi đặt USERthành một thứ khác root, bạn sẽ cần sử dụng sudocho bất kỳ lệnh nào yêu cầu rootđặc quyền.
M. Scott Ford

À, cảm ơn! Bỏ lỡ điều đó. Tôi không nghĩ sudođã được cho phép trong Dockerfile.
edesz

Hoàn hảo, chỉ là những gì tôi cần.
Arin Ekandem

25

Đối với bất kỳ ai gặp vấn đề này với một container đang chạy và họ không nhất thiết muốn xây dựng lại, lệnh sau sẽ kết nối với một container đang chạy với quyền root:

docker exec -ti -u root container_name bash

Bạn cũng có thể kết nối bằng ID của nó, thay vì tên của nó, bằng cách tìm nó bằng:

docker ps -l

Để lưu các thay đổi của bạn để chúng vẫn ở đó khi bạn khởi chạy tiếp theo bộ chứa (hoặc cụm soạn thảo docker):

docker commit container_id image_name

Để bắt đầu một container không chạy và kết nối với quyền root:

docker run -ti -u root --entrypoint=/bin/bash image_id_or_name -s

Để sao chép từ một container đang chạy:

docker cp <containerId>:/file/path/within/container /host/path/target

Để xuất bản sao của hình ảnh:

docker save container | gzip > /dir/file.tar.gz

Bạn có thể khôi phục cài đặt Docker khác bằng cách sử dụng:

gzcat /dir/file.tar.gz | docker load

Nó nhanh hơn nhiều nhưng cần nhiều không gian hơn để không nén, sử dụng:

docker save container | dir/file.tar

Và:

cat dir/file.tar | docker load

17

nếu bạn muốn kết nối với container và cài đặt một cái gì đó
bằng cách sử dụng apt-get
trước như câu trả lời ở trên từ anh trai của chúng tôi "Tomáš Záluský"

docker exec -u root -t -i container_id /bin/bash

sau đó cố gắng

CHẠY apt-get update hoặc apt-get 'bất cứ điều gì bạn muốn'

nó làm việc với tôi hy vọng nó hữu ích cho tất cả


5

Nếu SUDO hoặc apt-get không thể truy cập được trong Container, Bạn có thể sử dụng tùy chọn bên dưới trong khi chạy container.

docker exec -u root -it f83b5c5bf413 ash

" F83b5c5bf413" là ID container của tôi và đây là ví dụ hoạt động từ thiết bị đầu cuối của tôi:

nhập mô tả hình ảnh ở đây


3

Đây là cách tôi thiết lập người dùng không root với hình ảnh cơ bản của ubuntu:18.04:

RUN \
    groupadd -g 999 foo && useradd -u 999 -g foo -G sudo -m -s /bin/bash foo && \
    sed -i /etc/sudoers -re 's/^%sudo.*/%sudo ALL=(ALL:ALL) NOPASSWD: ALL/g' && \
    sed -i /etc/sudoers -re 's/^root.*/root ALL=(ALL:ALL) NOPASSWD: ALL/g' && \
    sed -i /etc/sudoers -re 's/^#includedir.*/## **Removed the include directive** ##"/g' && \
    echo "foo ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers && \
    echo "Customized the sudoers file for passwordless access to the foo user!" && \
    echo "foo user:";  su - foo -c id

Điều gì xảy ra với đoạn mã trên:

  • Người dùng và nhóm foođược tạo.
  • Người dùng foođược thêm vào cả nhóm foosudonhóm.
  • Các uidgidđược thiết lập với giá trị của 999.
  • Thư mục nhà được đặt thành /home/foo.
  • Vỏ được đặt thành /bin/bash.
  • Các sedlệnh thực hiện cập nhật nội tuyến vào /etc/sudoerstập tin để cho phép foorootsử dụng mật mã truy cập vào các sudonhóm.
  • Các sedlệnh vô hiệu hóa các #includedirchỉ thị mà sẽ cho phép bất kỳ tập tin trong thư mục con để ghi đè lên các bản cập nhật nội tuyến.

2

Nếu bạn có một thùng chứa đang chạy như root chạy tập lệnh (mà bạn không thể thay đổi) cần truy cập vào sudolệnh, bạn chỉ cần tạo một sudotập lệnh mới trong lệnh $PATHgọi lệnh đã truyền.

ví dụ: trong Dockerfile của bạn:

RUN if type sudo 2>/dev/null; then \ 
     echo "The sudo command already exists... Skipping."; \
    else \
     echo -e "#!/bin/sh\n\${@}" > /usr/sbin/sudo; \
     chmod +x /usr/sbin/sudo; \
    fi

1
Tùy thuộc vào hình ảnh docker bạn đang sử dụng (trong trường hợp của tôi là Ubuntu: 18.04), bạn có thể cần phải xóa -ekhỏi echo. Nếu không, nó sẽ có mặt trong chính tập tin, khiến nó trở nên vô dụng.
stiller_leser

Ý tưởng gọn gàng, nhưng điều này sẽ không hoạt động nếu lệnh ban đầu đang sử dụng các tùy chọn sudo, chẳng hạn như sudo -E ls. Nó sẽ cố gắng thực hiện -E ls.
wvducky

2

Điều này có thể không hoạt động đối với tất cả các hình ảnh, nhưng một số hình ảnh đã có người dùng root, chẳng hạn như trong hình ảnh jupyterhub / singleuser. Với hình ảnh đó đơn giản là:

USER root
RUN sudo apt-get update

1

Sử dụng bí danh.

alias sudo=''

Đơn giản nhưng hiệu quả. Đừng quên gắn nó vào ~ / .bash_aliases để nó hoạt động sau khi bạn mở một vỏ mới.

nano ~/.bash_aliases
alias sudo=''
#(Ctrl+X)

Vì người dùng là root mặc định trong Docker, 'bỏ ​​qua' lệnh sudo là cách dễ nhất.


0

Không giống như câu trả lời được chấp nhận , tôi sử dụng usermodthay thế.

Giả sử đã đăng nhập với quyền root trong docker và "fruit" là tên người dùng không root mới mà tôi muốn thêm, chỉ cần chạy các lệnh này:

apt update && apt install sudo
adduser fruit
usermod -aG sudo fruit

Nhớ lưu ảnh sau khi cập nhật. Sử dụng docker psđể nhận docker hiện tại <CONTAINER ID> và <IMAGE>, sau đó chạy docker commit -m "added sudo user" <CONTAINER ID> <IMAGE>để lưu hình ảnh docker.

Sau đó kiểm tra với:

su fruit
sudo whoami

Hoặc kiểm tra bằng cách đăng nhập trực tiếp (đảm bảo lưu hình ảnh trước) với tư cách là người dùng không root khi khởi chạy docker:

docker run -it --user fruit <IMAGE>
sudo whoami

Bạn có thể sử dụng sudo -kđể đặt lại dấu thời gian nhắc mật khẩu:

sudo whoami # No password prompt
sudo -k # Invalidates the user's cached credentials
sudo whoami # This will prompt for password
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.