• docker配置远程访问



    Docker Daemon 默认情况下是只允许本地访问的,不允许远程访问。本文将首先介绍 Docker Daemon 的连接方式,然后说明如何配置远程访问。即实现通过本地 docker 客户端访问远程主机的 docker 服务端,以此来监控远程主机上的 Docker 容器。

    如何配置:

    有两种方式:

    第一种(推荐)

    是使用 systemctl edit docker 来调用文本编辑器修改指定的单元或单元实例,ubuntu 默认调用的是 nano 编辑器,不是很好用,如果不熟悉 nano 编辑器的操作可以使用 vim 编辑器。

    主要也就是新建或修改 /etc/systemd/system/docker.service.d/override.conf,其内容如下:

    ##Add this to the file for the docker daemon to use different ExecStart parameters (more things can be added here)
    [Service]
    ExecStart=
    ExecStart=/usr/bin/dockerd
    

    解释一下:

    默认情况下使用 systemd 时,docker.service 的设置为:ExecStart=/usr/bin/dockerd -H fd://,这将覆盖写到 daemon.json 中的任何 hosts 。通过在 override.conf 文件中将 ExecStart 仅仅定义为:ExecStart=/usr/bin/dockerd,这将会使用在 daemon.json 中设置的 hosts 。这个文件中的第一行ExecStart= 必须要有,因为它将用于清除默认的 ExecStart 参数。如果是修改 docker.service 的文件而不是创建 override.conf,那么下次 systemd 重启时,docker.service 文件也会被重新创建。

    然后在 /etc/docker/daemon.json (没有就新建一个,下文统一简称 daemon.json)中写入以下内容

    {
      "hosts":[
        "unix:///var/run/docker.sock",
        "tcp://0.0.0.0:2375"
      ]
    }
    

    该文件必须符合 json 规范写法,否则 Docker 将不能启动

    重新加载 daemon 并重启 docker 服务:

    $ sudo systemctl daemon-reload
    $ sudo systemctl restart docker.service
    

    检查端口监听:

    $ sudo netstat -ntlp |grep dockerd
    tcp6       0      0 :::2375                 :::*                    LISTEN      2439/dockerd
    

    在远程主机上面通过 tcp socket 来访问本机的 Docker Daemon 服务:

    $ docker -H  192.168.205.10:2375 images
    
    $ docker -H  192.168.205.10:2375 ps
    

    其中 192.168.1.130 是开放了远程访问的主机的 IP。

    第二种

    这种就很简单暴力,直接修改/lib/systemd/system/docker.service文件,注释掉默认的 ExecStart 并添加新的 ExecStart 配置:

    # ExecStart=/usr/bin/dockerd -H fd://
    ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock
    

    然后重启 docker.service:

    $ sudo systemctl daemon-reload
    $ sudo systemctl restart docker.service
    

    这样 dockerd 就开始监听 tcp 端口 2375 了

    第三种

    Docker 客户端与 dockerd 之间就是通过 REST 的方式通信的。前面我们已经让 dockerd 监听 tcp 端口了,所以我们可以使用 curl 来代替 docker 客户端。这里我们简单的演示如何请求 dockerd 从 docker hub 上下载 hello-world 镜像:

    $ curl '127.0.0.1:2375/images/create?fromImage=hello-world&tag=latest' -X POST
    
    {"status":"Pulling from library/hello-world","id":"latest"}
    {"status":"Digest: sha256:8c5aeeb6a5f3ba4883347d3747a7249f491766ca1caa47e5da5dfcf6b9b717c0"}
    {"status":"Status: Image is up to date for hello-world:latest"}
    

    如果去看看 Engine API,你会发现其它的请求也都是用类似方式发送的,更多API可以参考官方文档,目前最新的版本是v1.40:https://docs.docker.com/engine/api/v1.40/

    CoreOS 官方文档提供的方法

    官方文档:https://coreos.com/os/docs/latest/customizing-docker.html

    新建 /etc/systemd/system/docker-tcp.socket 文件

    [Unit]
    Description=Docker Socket for the API
    
    [Socket]
    # ListenStream=127.0.0.1:2375
    ListenStream=2375
    BindIPv6Only=both
    Service=docker.service
    
    [Install]
    WantedBy=sockets.target

    重新启动服务

    $ sudo systemctl daemon-reload
    $ sudo systemctl enable docker-tcp.socket
    $ sudo systemctl stop docker
    $ sudo systemctl start docker-tcp.socket
    $ sudo systemctl start docker

    初始化完成后需要将DOCKER_HOST的地址设置为tcp://127.0.0.1:4243 

    export DOCKER_HOST=tcp://127.0.0.1:4243
     

    配置安全连接

    官方文档:https://docs.docker.com/engine/security/https/

    上面我们配置的远程连接是不安全的,只能用于测试环境中。在生产环境中需要配置 TLS 安全连接,只有拥有密钥的客户端,才能连接到远程的服务端。

    服务端配置

    只能使用 Linux 下的 openssl 生成密钥,macOS 下的不可以。在 CoreOS 下执行以下操作

    手动执行命令生成证书(不推荐)

    这一步较复杂,你可以跳过这一方法,使用容器生成证书。此方法来自 Docker 官方文档 https://docs.docker.com/engine/security/https/。

    文件总览

    ├── ca-key.pem       # 妥善保管,连接时用不到
    ├── ca.pem           # clent & server
    ├── ca.srl           # 用不到
    ├── cert.pem         # client
    ├── client.csr       # 请求文件
    ├── extfile.cnf      # 配置文件
    ├── key.pem          # client
    ├── server-cert.pem  # server
    ├── server.csr       # 请求文件
    └── server-key.pem   # server
    # 生成 CA 私钥
    
    $ openssl genrsa -aes256 -out ca-key.pem 4096
    
    # 需要输入两次密码(自定义)
    
    # 生成 CA 公钥
    
    $ openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem
    
    # 输入上一步中设置的密码,然后需要填写一些信息
    
    # 下面是服务器证书生成
    
    # 生成服务器私钥
    
    $ openssl genrsa -out server-key.pem 4096
    
    # 用私钥生成证书请求文件
    
    $ openssl req -subj "/CN=localhost" -sha256 -new -key server-key.pem -out server.csr
    
    $ echo subjectAltName = DNS:localhost,DNS:www.khs1994.com,DNS:tencent,IP:192.168.199.100,IP:192.168.57.110,IP:127.0.0.1 >> extfile.cnf
    
    # 允许服务端哪些 IP 或 host 能被客户端连接,下文会进行测试。
    
    # DNS 我也不是很理解,这里配置 localhost ,公共 DNS 解析的域名,/etc/hosts 文件中的列表进行测试。
    
    $ echo extendedKeyUsage = serverAuth >> extfile.cnf
    
    # 用 CA 来签署证书
    
    $ openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem 
      -CAcreateserial -out server-cert.pem -extfile extfile.cnf
    
    # 再次输入第一步设置的密码
    
    # 下面是客户端证书文件生成
    
    # 生成客户端私钥
    
    $ openssl genrsa -out key.pem 4096
    
    # 用私钥生成证书请求文件  
    
    $ openssl req -subj '/CN=client' -new -key key.pem -out client.csr
    
    $ echo extendedKeyUsage = clientAuth >> extfile.cnf
    
    # 用 CA 来签署证书
    
    $ openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem 
      -CAcreateserial -out cert.pem -extfile extfile.cnf
    
    # 再次输入第一步设置的密码
    
    # 删除文件,更改文件权限
    
    $ rm -v client.csr server.csr
    
    $ chmod -v 0400 ca-key.pem key.pem server-key.pem
    
    $ chmod -v 0444 ca.pem server-cert.pem cert.pem

    把 ca.pem server-cert.pem server-key.pem 三个文件移动到 /etc/docker/ 文件夹中。

    使用容器生成证书(推荐)

    GitHub:https://github.com/khs1994-docker/dockerd-tls

    方法来自 CoreOS 官方文档:https://coreos.com/os/docs/latest/generate-self-signed-certificates.html

    既然使用容器那就可以在任何系统运行,只要把生成的证书文件对应的放到 Docker 客户端和服务端即可。

    $ git clone --depth=1 https://github.com/khs1994-docker/dockerd-tls.git
    $ cd dockerd-tls

    在 ./cfssl/*.json 中配置好 CN hosts

    $ docker-compose up cfssl

    命令执行完毕之后在 ./cfssl/cert 文件夹中可以看到证书文件,修改文件权限。

    $ chmod -v 0400 ca-key.pem key.pem server-key.pem
    
    $ chmod -v 0444 ca.pem server-cert.pem cert.pem

    把 ca.pem server-cert.pem server-key.pem 三个文件移动到服务端 /etc/docker/ 文件夹中。

    CoreOS 请使用第二种方法,其他 Linux 系统根据上文选择的方法,这里选择对应的方法

    通常的配置方法

    修改 daemon.json 文件。

    注意:非安全连接使用的是 2375 端口,安全连接使用的是 2376 端口。当然这是推荐的端口配置,你可以配置任何端口!

    {
      "tlsverify": true,
      "tlscert": "/etc/docker/server-cert.pem",
      "tlskey": "/etc/docker/server-key.pem",
      "tlscacert": "/etc/docker/ca.pem",
      "hosts":[
        "unix:///var/run/docker.sock",
        "tcp://0.0.0.0:2376"
      ]
    }

    重新启动 Docker

    $ sudo systemctl restart docker

    CoreOS 官方文档的方法

    首先需要修改 /etc/systemd/system/docker-tcp.socket 文件内容

    ListenStream=2375
    
    # 修改为
    
    ListenStream=2376

    修改 CoreOS 上的 daemon.json 文件。

    {
      "tlsverify": true,
      "tlscert": "/etc/docker/server-cert.pem",
      "tlskey": "/etc/docker/server-key.pem",
      "tlscacert": "/etc/docker/ca.pem"
    }

    重新启动服务。

    $ sudo systemctl daemon-reload
    $ sudo systemctl stop docker
    $ sudo systemctl restart docker-tcp.socket
    $ sudo systemctl restart docker

    上文已经提到了启动顺序,这里提示一下,不再赘述。

    客户端远程安全连接

    将 ca.pem cert.pem key.pem 三个文件通过 scp 下载到 macOS

    在 macOS 执行以下命令,密钥路径请根据实际情况填写。

    $ docker --tlsverify 
      --tlscacert=/Users/khs1994/test/ca.pem 
      --tlscert=/Users/khs1994/test/cert.pem 
      --tlskey=/Users/khs1994/test/key.pem 
      -H=192.168.57.110:2376 
      info

    把密钥放入 ~/.docker 文件夹中

    每次操作需要跟那么多参数,太麻烦了。我们可以把 ca.pem cert.pem key.pem 三个文件放入客户端 ~/.docker 中,然后配置环境变量就可以简化命令了。

    $ export DOCKER_HOST=tcp://192.168.57.110:2376 DOCKER_TLS_VERIFY=1
    
    $ docker info

    你也可以选择其他路径,请通过环境变量 DOCKER_CERT_PATH 指定。

    报错详情

    不使用安全连接

    $ docker -H 192.168.57.110:2376 info
    Get http://192.168.57.110:2376/v1.34/containers/json?all=1: malformed HTTP response "x15x03x01x00x02x02".
    * Are you trying to connect to a TLS-enabled daemon without TLS?

    在非允许列表 IP 中登录

    假如远程服务器还有一个 IP 10.141.20.83 ,现在我们尝试使用这个 IP 作为服务端地址,看看客户端能否连接到。

    $ docker -H 10.141.20.83:2376 info
    error during connect: Get https://10.141.20.83:2376/v1.34/info: x509: certificate is valid for 192.168.57.110, 192.168.199.100, 127.0.0.1, not 10.141.20.83

    在非允许列表 Host 中登录

    $ docker -H localhost:2376 info
    error during connect: Get https://localhost:2375/v1.34/info: x509: certificate is valid for coreos1, not localhost

    fish shell

    $ set -Ux DOCKER_HOST tcp://192.168.57.110:2376
    $ set -Ux DOCKER_TLS_VERIFY 1
    
    # 以上命令写入环境变量是永久存在的,通过以下命令删除环境变量
    
    $ set -Ue DOCKER_HOST ; set -Ue DOCKER_TLS_VERIFY

    服务端验证模式

    • tlsverifytlscacerttlscerttlskey set: Authenticate clients
    • tlstlscerttlskey: Do not authenticate clients

    客户端验证模式

    • tls: Authenticate server based on public/default CA pool
    • tlsverifytlscacert: Authenticate server based on given CA
    • tlstlscerttlskey: Authenticate with client certificate, do not authenticate server based on given CA
    • tlsverifytlscacerttlscerttlskey: Authenticate with client certificate and authenticate server based on given CA

    测试远程构建 Docker 镜像

    在 macOS 新建 demo 文件夹并进入。

    我们首先建一个文本文件 test.txt

    hello!

    然后新建一个简单的 Dockerfile 文件

    FROM busybox
    
    COPY ./test.txt /
    
    CMD cat /test.txt

    按照前面的方法设置好环境变量,这里不再赘述。

    $ docker -H 192.168.57.110:2375 --tlsverify build -t khs1994/busybox .

    在远程服务端查看

    SSH 登录到 CoreOS(这里为了便于理解,SSH 到远程服务器操作)。

    $ docker image ls
    REPOSITORY                             TAG                 IMAGE ID            CREATED             SIZE
    khs1994/busybox                        latest              368d23df8500        10 seconds ago      1.13MB

    我们已经查看到了镜像。

    $ docker run -it --rm khs1994/busybox
    hello!

    运行成功。

    客户端恢复原状

    你如果想在 macOS 操作本地的服务端,请将上面配置的环境变量删除,这里不再赘述。

     
     
  • 相关阅读:
    Triangle LOVE
    数据传送指令具体解释
    关于C++String字符串的使用
    TCP/IP基础(一)
    java打开目录(含推断操作系统工具类和解压缩工具类)
    hdu-1848 Fibonacci again and again
    opencv2对读书笔记——图像二值化——thresholded函数
    安卓中四种点击事件
    @MappedSuperclass注解的使用说明
    Androidclient採用Http 协议Post方式请求与服务端进行数据交互
  • 原文地址:https://www.cnblogs.com/cheyunhua/p/16641785.html
Copyright © 2020-2023  润新知