以非root用户管理Docker

Docker守护程序绑定到Unix套接字而不是TCP端口。默认情况下,Unix套接字由用户拥有root,其他用户只能使用来访问它sudo。Docker守护程序始终以root用户身份运行。

如果您不想在docker命令前添加sudo,请创建一个Unix组docker,并将其添加用户。Docker守护程序启动时,它会创建一个可由该docker组成员访问的Unix套接字。

警告 该docker组授予与root 用户等效的权限。关这如何影响系统安全性的详细信息,请参阅 Docker 守护进程攻击面注意: 要在没有 root 权限的情况下运行 Docker,请参阅 以非 root 用户身份运行 Docker 守护程序(无根模式)

要创建docker组并添加您的用户,请执行以下操作:
1。创建docker组。

  1. $ sudo groupadd docker

2.将您的用户添加到该docker组。·

$ sudo usermod -aG docker $USER

3.注销并重新登录,以便重新评估您的组成员身份。

  • 如果在虚拟机上进行测试,则可能需要重新启动虚拟机以使更改生效。
  • 在台式机Linux环境(例如X Windows)上,完全注销会话,然后重新登录。
  • 在Linux上,您还可以运行以下命令来激活对组的更改:
    $ newgrp docker
    
    4.验证您是否可以运行docker不带命令的命令sudo
    $ docker run hello-world
    
    此命令下载测试映像并在容器中运行它。容器运行时,它会打印参考消息并退出。

如果最初sudo在将用户添加到docker组之前运行Docker CLI命令,则可能会看到以下错误,这表明~/.docker/由于sudo命令的原因,您的目录是使用不正确的权限创建的。

WARNING: Error loading config file: /home/user/.docker/config.json -
stat /home/user/.docker/config.json: permission denied

要解决此问题,请删除~/.docker/目录(会自动重新创建目录,但是所有自定义设置都会丢失),或者使用以下命令更改其所有权和权限:

$ sudo chown "$USER":"$USER" /home/"$USER"/.docker -R
$ sudo chmod g+rwx "$HOME/.docker" -R

配置Docker开机启动

当前大多数Linux发行版(RHEL,CentOS,Fedora,Debian,Ubuntu 16.04及更高版本)用于systemd管理系统引导时启动的服务。在Debian和Ubuntu上,默认情况下,将Docker服务配置为在引导时启动。要在启动时自动启动其他发行版的Docker和Containerd,请使用以下命令:

$ sudo systemctl enable docker.service
$ sudo systemctl enable containerd.service

若要禁用此行为,请disable改用。

$ sudo systemctl disable docker.service
$ sudo systemctl disable containerd.service

配置默认的日志驱动程序

Docker提供了通过一系列日志记录驱动程序从主机上运行的所有容器收集和查看日志数据的功能。默认的日志记录驱动程序json-file将日志数据写入主机文件系统上的JSON格式的文件中。随着时间的流逝,这些日志文件的大小会扩大,从而可能会耗尽磁盘资源。
为了缓解此类问题,可以将json-file日志记录驱动程序配置为启用日志轮换,使用 备用日志记录驱动程序, 例如 默认情况下执行日志循环的“本地”日志记录驱动程序,或者使用将日志记录发送到远程日志记录聚合器的日志记录驱动程序。

配置Docker守护程序在何处监听连接

默认情况下,Docker守护程序在UNIX套接字上侦听连接以接受来自本地客户端的请求。通过将Docker配置为侦听IP地址和端口以及UNIX套接字,可以允许Docker接受来自远程主机的请求。

保护您的连接 在配置 Docker 以接受来自远程主机的连接之前,了解将 Docker 开放到网络的安全含义至关重要。如果不采取措施保护连接,远程非 root 用户就有可能在主机上获得 root 访问权限。有关如何使用 TLS 证书来保护此连接的更多信息,请查看有关 如何保护 Docker 守护进程套接字的文章

可以docker.service 使用systemd使用Linux发行版的systemd单元文件(例如RedHat,CentOS,Ubuntu和SLES的最新版本)来配置Docker接受远程连接,或者使用daemon.json不使用systemd的Linux发行版推荐的文件来配置Docker 。

systemd 与 daemon.json

将 Docker 配置为同时使用systemd单元文件和daemon.json 文件来侦听连接会导致冲突,从而阻止 Docker 启动。

使用systemd单元文件配置远程访问

  1. 使用该命令在文本编辑器中sudo systemctl edit docker.service打开覆盖文件docker.service
  2. 添加或修改以下几行,替换您自己的值。

    [Service]
    ExecStart=
    ExecStart=/usr/bin/dockerd -H fd:// -H tcp://127.0.0.1:2375
    
  3. 保存文件。

  4. 重新加载systemctl配置。

    $ sudo systemctl daemon-reload
    
  5. 重启 Docker。

    $ sudo systemctl restart docker.service
    
  6. 通过查看netstat以确认dockerd正在侦听配置的端口的输出来检查更改是否得到遵守。

    $ sudo netstat -lntp | grep dockerd
    

    image.png

    使用配置远程访问daemon.json

  7. 设置连接到UNIX套接字的hosts数组/etc/docker/daemon.json和IP地址,如下:

    {
    "hosts": ["unix:///var/run/docker.sock", "tcp://127.0.0.1:2375"]
    }
    
  8. 重启 Docker。

    $ sudo systemctl restart docker.service
    
  9. 通过查看netstat以确认dockerd正在侦听配置的端口的输出来检查更改是否得到遵守。

    $ sudo netstat -lntp | grep dockerd
    

    image.png

    故障排除

    内核兼容性

    如果您的内核版本低于 3.10 或缺少某些模块,Docker 将无法正常运行。要检查内核兼容性,您可以下载并运行check-config.sh 脚本。

    $ curl https://raw.githubusercontent.com/docker/docker/master/contrib/check-config.sh > check-config.sh
    $ bash ./check-config.sh
    

    该脚本仅适用于 Linux,不适用于 macOS。

    无法连接到Docker daemon

    如果您看到如下错误,则您的 Docker 客户端可能被配置为连接到不同主机上的 Docker 守护程序,而该主机可能无法访问。

    Cannot connect to the Docker daemon. Is 'docker daemon' running on this host?
    

    要查看您的客户端配置为连接到哪个主机,请检查DOCKER_HOST您环境中变量的值。

    $ env | grep DOCKER_HOST
    

    如果此命令返回一个值,则 Docker 客户端将设置为连接到在该主机上运行的 Docker 守护程序。如果未设置,则 Docker 客户端将设置为连接到在本地主机上运行的 Docker 守护程序。如果设置错误,请使用以下命令取消设置:

    $ unset DOCKER_HOST
    

    您可能需要在文件中编辑环境,例如~/.bashrc~/.profile以防止DOCKER_HOST错误设置变量。
    如果DOCKER_HOST按预期设置,请验证 Docker 守护程序是否正在远程主机上运行,并且防火墙或网络中断未阻止您进行连接。

    IP转发问题

    如果使用手动配置你的网络systemd-networksystemd 219或更高版本,Docker容器可能无法访问您的网络。从systemd版本 220开始,给定网络 ( net.ipv4.conf.<interface>.forwarding)的转发设置 默认为off。此设置可防止 IP 转发。它还与 Dockernet.ipv4.conf.all.forwarding在容器内启用设置的行为相冲突。
    要在 RHEL、CentOS 或 Fedora 上解决此问题,请<interface>.network/usr/lib/systemd/network/Docker 主机(例如:编辑文件/usr/lib/systemd/network/80-container-host0.network并在该[Network]部分中添加以下内容。

    [Network]
    ...
    IPForward=kernel
    # OR
    IPForward=true
    

    此配置允许按预期从容器转发 IP。

    在resolve.conf和容器中找到的DNS解析器无法使用

    使用GUI的Linux系统通常有一个网络管理器正在运行,而网络管理器使用的是dnsmasq在环回地址上运行的实例,如127.0.0.1127.0.1.1缓存dns请求,并将此项添加到/etc/resolv.conf。这个dnsmasq服务加速DNS查询,并提供DHCP服务.此配置在具有自己的网络命名空间的Docker容器中无法工作,因为Docker容器解析回送地址,如127.0.0.1本身,它不太可能在自己的回送地址上运行DNS服务器。
    如果Docker检测到没有在/etc/resolv.conf是一个功能齐全的DNS服务器,会发生以下警告,Docker将使用Google提供的公共DNS服务器8.8.8.88.8.4.4用于DNS解析。

    WARNING: Local (127.0.0.1) DNS resolver found in resolv.conf and containers
    can't use it. Using default external servers : [8.8.8.8 8.8.4.4]
    

    如果您看到此警告,请首先检查是否使用dnsmasq:

    $ ps aux |grep dnsmasq
    

    如果您的容器需要解析网络内部的主机,则公共名称服务器是不够的。你有两个选择:

  • 您可以指定一个 DNS 服务器供 Docker 使用,或者
  • 您可以dnsmasq在 NetworkManager 中禁用。如果您这样做,NetworkManager 会将您真正的 DNS 名称服务器添加到/etc/resolv.conf,但您将失去dnsmasq.

    为 Docker 指定 DNS 服务器

  1. 创建或编辑Docker守护进程配置文件,默认为/etc/docker/daemon.json文件,它控制Docker守护进程配置。

    $ sudo nano /etc/docker/daemon.json
    
  2. 添加dns具有一个或多个 IP 地址作为值的键。如果文件已有内容,您只需添加或编辑该dns行。

    {
    "dns": ["8.8.8.8", "8.8.4.4"]
    }
    

    如果您的内部 DNS 服务器无法解析公共 IP 地址,请至少包含一个可以解析的 DNS 服务器,以便您可以连接到 Docker Hub 并且您的容器可以解析 Internet 域名。
    保存并关闭文件。

  3. 重新启动 Docker 守护进程。

    $ sudo service docker restart
    
  4. 通过尝试拉取镜像来验证 Docker 是否可以解析外部 IP 地址:

    $ docker pull hello-world
    
  5. 如有必要,请验证 Docker 容器是否可以通过 ping 来解析内部主机名。

    $ docker run --rm -it alpine ping -c4 <my_internal_host>
    

    image.png

    禁用 dnsmasq

    Ubuntu

    如果您不想更改 Docker 守护程序的配置以使用特定 IP 地址,请按照这些说明dnsmasq在 NetworkManager 中禁用。

  6. 编辑/etc/NetworkManager/NetworkManager.conf文件。

  7. 通过dns=dnsmasq在行#的开头添加一个字符来注释掉该行。

    # dns=dnsmasq
    
  8. 保存并关闭文件。

  9. 重新启动 NetworkManager 和 Docker。作为替代方案,您可以重新启动系统。

    $ sudo systemctl restart network-manager
    $ sudo systemctl restart docker
    

    RHEL、CentOS 或 Fedora

    dnsmasq在 RHEL、CentOS 或 Fedora 上禁用:

  10. 禁用dnsmasq服务:

    $ sudo systemctl stop dnsmasq
    $ sudo systemctl disable dnsmasq
    
  11. 使用Red Hat 文档手动配置 DNS 服务器 。

    允许通过防火墙访问远程api

    如果在运行Docker的同一台主机上运行防火墙,并且希望从另一台主机访问Docker远程API,并且启用远程访问,则需要配置防火墙以允许Docker端口上的传入连接,该端口默认为2376如果启用了TLS加密传输或2375 以其他方式启用。
    两种常见的防火墙守护进程是 UFW(Uncomplicated Firewall)(常用于 Ubuntu 系统)和firewalld(常用于基于 RPM 的系统)。请参阅您的操作系统和防火墙的文档,但以下信息可能会帮助您入门。这些选项相当宽松,您可能希望使用不同的配置来更多地锁定您的系统。

  • UFWDEFAULT_FORWARD_POLICY="ACCEPT"在您的配置中设置。
  • firewalld:将类似于以下内容的规则添加到您的策略中(一种用于传入请求,一种用于传出请求)。确保接口名称和链名称正确。
    <direct>
    [ <rule ipv="ipv6" table="filter" chain="FORWARD_direct" priority="0"> -i zt0 -j ACCEPT </rule> ]
    [ <rule ipv="ipv6" table="filter" chain="FORWARD_direct" priority="0"> -o zt0 -j ACCEPT </rule> ]
    </direct>
    

    kernel(内核)不支持cgroup交换限制功能

    在 Ubuntu 或 Debian 主机上,使用映像时,您可能会看到类似于以下内容的消息。
    WARNING: Your kernel does not support swap limit capabilities. Limitation discarded.
    
    在基于 RPM 的系统上不会发生此警告,默认情况下启用这些功能。
    如果您不需要这些功能,则可以忽略警告。您可以按照这些说明在 Ubuntu 或 Debian 上启用这些功能。即使 Docker 没有运行,内存和交换计算也会产生大约 1% 的总可用内存开销和 10% 的整体性能下降。
  1. 以具有sudo权限的用户身份登录 Ubuntu 或 Debian 主机。
  2. 编辑/etc/default/grub文件。添加或编辑该GRUB_CMDLINE_LINUX行以添加以下两个键值对:

    GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1"
    

    保存并关闭文件。

  3. 更新 GRUB。

    $ sudo update-grub
    

    如果您的 GRUB 配置文件的语法不正确,则会发生错误。在这种情况下,重复步骤 2 和 3。
    更改在系统重新启动时生效。