Điều chỉnh hạt nhân với Docker đặc quyền


10

Tôi đang xây dựng một thùng chứa để điều chỉnh cài đặt kernel cho bộ cân bằng tải. Tôi muốn triển khai những thay đổi đó đến máy chủ lưu trữ trong một hình ảnh bằng cách sử dụng một thùng chứa đặc quyền duy nhất. Ví dụ:

docker run --rm --privileged ubuntu:latest sysctl -w net.core.somaxconn=65535

Trong thử nghiệm các thay đổi có hiệu lực nhưng chỉ đối với container đó. Tôi có ấn tượng rằng với một bộ chứa đặc quyền hoàn toàn thay đổi thành / Proc sẽ thực sự thay đổi hệ điều hành cơ bản.

$docker run --rm --privileged ubuntu:latest \
    sysctl -w net.core.somaxconn=65535
net.core.somaxconn = 65535

$ docker run --rm --privileged ubuntu:latest \
    /bin/bash -c "sysctl -a | grep somaxconn"
net.core.somaxconn = 128

Đây có phải là cách các container đặc quyền được cho là để làm việc?

Tôi chỉ đang làm điều gì đó ngớ ngẩn?

Cách tốt nhất để thực hiện các thay đổi lâu dài là gì?

Thông tin phiên bản:

Client version: 1.4.1
Client API version: 1.16
Go version (client): go1.3.3
Git commit (client): 5bc2ff8
OS/Arch (client): linux/amd64
Server version: 1.4.1
Server API version: 1.16
Go version (server): go1.3.3
Git commit (server): 5bc2ff8

Lệnh ví dụ với mount / Proc:

$ docker run -v /proc:/proc ubuntu:latest \
    /bin/bash -c "sysctl -a | grep local_port"
net.ipv4.ip_local_port_range = 32768    61000

$ docker run -v /proc:/proc --privileged ubuntu:latest \
    /bin/bash -c "sysctl -p /updates/sysctl.conf"
net.ipv4.ip_local_port_range = 2000 65000

$ docker run -v /proc:/proc ubuntu:latest \
    /bin/bash -c "sysctl -a | grep local_port"
net.ipv4.ip_local_port_range = 32768    61000

$ docker run -v /proc:/proc --privileged ubuntu:latest \
    /bin/bash -c "sysctl -a | grep local_port"
net.ipv4.ip_local_port_range = 32768    61000

Tôi có cần phải làm một cái gì đó ngớ ngẩn như mount / Proc như một khối lượng không?
allingeek

Đã thử gắn / Proc: / Proc không có may mắn. Các cuộc gọi tiếp theo đến sysctl -a trả về các giá trị ban đầu.
allingeek

Có vẻ như bây giờ nó hoạt động trên Docker 18,09
Jairo Andres Velasco Romero

Câu trả lời:


8

Cài đặt cụ thể này nằm dưới ảnh hưởng của không gian tên mạng mà docker chạy.

Vì quy tắc chung /procsẽ thay đổi các cài đặt có liên quan trên toàn hệ thống, về mặt kỹ thuật, tuy nhiên, bạn đang thay đổi các cài đặt trong /proc/netđó trả về kết quả trên cơ sở không gian tên trên mỗi mạng.

Lưu ý rằng đó /proc/netthực sự là một liên kết tượng trưng /proc/self/netvì nó thực sự phản ánh các cài đặt của không gian tên mà bạn đang thực hiện công việc.


Vì vậy, nếu tôi thực hiện thay đổi này trong một thùng chứa có / Proc được gắn và máy chủ --net, tôi có thể thay đổi máy chủ. Nhưng nếu tôi hiểu câu trả lời của bạn, các thùng chứa tiếp theo sẽ duy trì các giá trị cũ (được khởi động từ các cài đặt liên tục của máy chủ) trong không gian tên của chính nó. Tôi cần chạy container đó với một cái gì đó giống như CAP_NET_ADMIN để thực hiện các thay đổi tương tự trong thời gian chạy trong vùng chứa của bộ cân bằng tải. Âm thanh phải không?
allingeek

Có, chạy với CAP_NET_ADMIN không nên đặt ra vấn đề trong đó bạn đã khởi tạo một không gian tên cho nó.
Matthew Ife

Matthew_Ife Không phải là vấn đề trong trường hợp này mà container dự kiến ​​sẽ được đặc quyền. Dường như với tôi rằng CAP_NET_ADMIN có thể cho phép thoát khỏi sự giam cầm của docker (ít nhất là container có thể cấu hình lại giao diện của nó để mạo danh một container khác)
Ángel

@Angel Điều đó phụ thuộc vào liên kết nào được thiết lập bên trong docker. Nói chung, người ta nên đặt thực thi lưu lượng trong không gian tên cha. Không thể chuyển đổi không gian tên thành một nơi khác vì bạn cần CAP_SYS_ADMIN cho điều đó.
Matthew Ife

SO sử dụng --net = host sẽ hoạt động?
Jairo Andres Velasco Romero

7

Docker 1.12+ có hỗ trợ riêng để điều chỉnh các giá trị sysctl bên trong các thùng chứa. Đây là một đoạn trích từ tài liệu :

Cấu hình các tham số kernel được đặt tên (sysctls) khi chạy

--Sysctl đặt các tham số kernel được đặt tên (sysctls) trong vùng chứa. Ví dụ: để bật chuyển tiếp IP trong không gian tên mạng container, hãy chạy lệnh này:

docker run --sysctl net.ipv4.ip_forward=1 someimage

Sử dụng ví dụ của bạn, cách nâng cao chính xác net.core.somaxconnsẽ là:

docker run ... --sysctl net.core.somaxconn=65535 ...

3

Container đặc quyền vẫn đang sử dụng không gian tên quy trình riêng của nó cho /proc. Những gì bạn có thể làm là gắn kết thực /procbên trong container:

docker run --rm --privileged -v /proc:/host-proc ubuntu:latest \
  'echo 65535 > /host-proc/sys/net/core/somaxconn'

Chỉ cần thử điều này và nó không hoạt động.
allingeek

Từ nhỏ tôi biết về docker; nó được coi là một cá thể khép kín, giống như một nhà tù trên FreeBSD, vì vậy nó có thể dễ dàng di chuyển, triển khai lại, v.v ... Bạn không nên trộn lẫn docklet với HĐH máy chủ.
DutchUncle 3/2/2015

2
Có một số trường hợp hợp lệ để sử dụng các thùng chứa - đặc quyền và đây có vẻ là trường hợp hoàn hảo. Tất cả các container sử dụng cùng một kernel bên dưới. Container tiêu chuẩn gắn / Proc như chỉ đọc.
allingeek

@allingeek CAP_NET_ADMIN thực sự có thể là bit bị thiếu.
Ángel

1
Đã thử với NET_ADMIN và nó vẫn không hoạt động - docker chạy --cap-add NET_ADMIN --net = host -v / Proc: / Proc_host ub Ubuntu: 14.04 bash -c 'echo 1> / Proc_host / sys / net / ipv4 / ip_forward '&& sysctl net.ipv4.ip_forward net.ipv4.ip_forward = 0
tomdee

2

Điều này hoạt động với tôi với Docker 1.5.0:

docker run --privileged --net=host --rm ubuntu:latest /bin/sh -c \
   'echo 65535 > /proc/sys/net/core/somaxconn'   
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.