Docker Daemon 連接方式詳解


前言


Docker 常用詳解指令 一文中粗粗提了一下, Docker 是分為客戶端和服務端兩部分的, 本文將介紹客戶端是如何連接服務端的。

連接方式


1. UNIX域套接字

默認就是這種方式, 會生成一個 /var/run/docker.sock 文件, UNIX 域套接字用於本地進程之間的通訊, 這種方式相比於網絡套接字效率更高, 但局限性就是只能被本地的客戶端訪問。

2. TCP 端口監聽

服務端開啟端口監聽:dockerd -H IP:PORT

客戶端通過指定的 IP端口 訪問服務端:docker -H IP:PORT

通過這種方式, 任何人只要知道了你暴露的 IP端口 就能隨意訪問你的 Docker 服務了, 這是一件很危險的事, 因為 docker 的權限很高, 不法分子可以從這突破取得服務端 宿主機 的最高權限。

相關:一個回車鍵黑掉一台服務器
3. 可以同時監聽多個 socket
ubuntu@VM-84-201-ubuntu:/usr/anyesu/docker$ sudo dockerd -H unix:///var/run/docker.sock -H tcp://127.0.0.1:2376 -H tcp://127.0.0.1:2377
...
INFO[0004] API listen on 127.0.0.1:2377
INFO[0004] API listen on /var/run/docker.sock
INFO[0004] API listen on 127.0.0.1:2376

啟用 TLS 安全連接


上面介紹了普通的 HTTP 方式遠程連接很不安全, 解決的辦法很簡單, 就是啟用 TLS 證書實現客戶端和服務端的雙向認證, 以此來保證安全性。

創建 TLS 證書 ( 根證書、服務端證書、客戶端證書 )
cd /usr/anyesu/docker
# 內容比較多, 就寫成一個shell腳本, 將需要綁定的服務端ip或域名做參數傳入即可
vi tlscert.sh

腳本內容如下:

#!/bin/bash
# @author: anyesu

if [ $# != 1 ] ; then
echo "USAGE: $0 [HOST_IP]"
exit 1;
fi

============================================#

# 下面為證書密鑰及相關信息配置,注意修改 #
#============================================#
PASSWORD="8#QBD2$!EmED&QxK"
COUNTRY=CN
PROVINCE=yourprovince
CITY=yourcity
ORGANIZATION=yourorganization
GROUP=yourgroup
NAME=yourname
HOST=$1
SUBJ="/C=$COUNTRY/ST=$PROVINCE/L=$CITY/O=$ORGANIZATION/OU=$GROUP/CN=$HOST"

echo "your host is: $1"

1.生成根證書RSA私鑰,PASSWORD作為私鑰文件的密碼

openssl genrsa -passout pass:$PASSWORD -aes256 -out ca-key.pem 4096

2.用根證書RSA私鑰生成自簽名的根證書

openssl req -passin pass:$PASSWORD -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem -subj $SUBJ

============================================#

# 用根證書簽發server端證書 #
#============================================#

3.生成服務端私鑰

openssl genrsa -out server-key.pem 4096

4.生成服務端證書請求文件

openssl req -new -sha256 -key server-key.pem -out server.csr -subj "/CN=$HOST"

5.使tls連接能通過ip地址方式,綁定IP

echo subjectAltName = IP:127.0.0.1,IP:$HOST > extfile.cnf

6.使用根證書簽發服務端證書

openssl x509 -passin pass:$PASSWORD -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -extfile extfile.cnf

============================================#

# 用根證書簽發client端證書 #
#============================================#

7.生成客戶端私鑰

openssl genrsa -out key.pem 4096

8.生成客戶端證書請求文件

openssl req -subj '/CN=client' -new -key key.pem -out client.csr

9.客戶端證書配置文件

echo extendedKeyUsage = clientAuth > extfile.cnf

10.使用根證書簽發客戶端證書

openssl x509 -passin pass:$PASSWORD -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem -extfile extfile.cnf

============================================#

# 清理 #
#============================================#
# 刪除中間文件
rm -f client.csr server.csr ca.srl extfile.cnf

轉移目錄

mkdir client server
cp {ca,cert,key}.pem client
cp {ca,server-cert,server-key}.pem server
rm {cert,key,server-cert,server-key}.pem

設置私鑰權限為只讀

chmod -f 0400 ca-key.pem server/server-key.pem client/key.pem

執行服務端配置

# 給腳本添加運行權限
chmod +x tlscert.sh
HOST_IP=127.0.0.1
./tlscert.sh $HOST_IP
# 客戶端需要的證書保存在client目錄下, 服務端需要的證書保存在server目錄下
sudo cp server/* /etc/docker
# 修改配置
sudo vi /etc/default/docker
# 改為 DOCKER_OPTS="--selinux-enabled --tlsverify --tlscacert=/etc/docker/ca.pem --tlscert=/etc/docker/server-cert.pem --tlskey=/etc/docker/server-key.pem -H=unix:///var/run/docker.sock -H=0.0.0.0:2375"
 # 重啟docker
sudo service docker restart

關於 Ubuntu 16.04.2 LTS 下DOCKER_OPTS 不生效的問題解決

接着按之前的方式連接服務端就出錯了,說明 TLS 已經生效了。

ubuntu@VM-84-201-ubuntu:/usr/anyesu/docker$ docker -H tcp://127.0.0.1:2375 version
Get http://127.0.0.1:2375/v1.29/version: malformed HTTP response "\x15\x03\x01\x00\x02\x02".
* Are you trying to connect to a TLS-enabled daemon without TLS?

正確的訪問方式:

# 客戶端加tls參數訪問
docker --tlsverify --tlscacert=client/ca.pem --tlscert=client/cert.pem --tlskey=client/key.pem -H tcp://127.0.0.1:2375 version
 # Docker API方式訪問
curl https://127.0.0.1:2375/images/json --cert client/cert.pem --key client/key.pem --cacert client/ca.pem
 # 簡化客戶端調用參數配置
sudo cp client/* ~/.docker
# 追加環境變量
echo -e "export DOCKER_HOST=tcp://$HOST_IP:2375 DOCKER_TLS_VERIFY=1" >> ~/.bashrc

sudo docker version

切記, 要保護好客戶端證書, 這是連接服務端的憑證。另外根證書私鑰也要保存好, 泄漏之后就能簽發客戶端證書了。

認證模式


1. 服務端認證模式
選項 說明
tlsverify, tlscacert, tlscert, tlskey 向客戶端發送服務端證書, 校驗客戶端證書是否由指定的 CA ( 自簽名根證書 ) 簽發
tls, tlscert, tlskey 向客戶端發送服務端證書, 不校驗客戶端證書是否由指定的 CA ( 自簽名根證書 ) 簽發
2. 客戶端認證模式
選項 說明
tls 校驗服務端證書是否由 公共的 CA 機構簽發
tlsverify, tlscacert 校驗服務端證書是否由指定的 CA ( 自簽名根證書 ) 簽發
tls, tlscert, tlskey 使用客戶端證書進行身份驗證, 但不校驗服務端證書是否由指定的 CA ( 自簽名根證書 ) 簽發
tlsverify, tlscacert, tlscert, tlskey 使用客戶端證書進行身份驗證且校驗服務端證書是否由指定的 CA ( 自簽名根證書 ) 簽發

關於遠程構建命令


在之前的文章中介紹了 使用 Docker Compose 構建容器 , 學了今天的內容之后可以連接遠程 Docker Daemon 進行構建, 不過需要注意的一點是, 構建需要的配置文件、依賴文件等都需要在客戶端准備好, 然后會把這些內容傳輸到服務端執行構建或運行容器。

另外, win10 下的 WSL 也可以安裝 Docker ( 不過可能是因為早期版本子系統的緣故, Docker 服務端跑不起來, 只能運行 Docker 客戶端, 前段時間的 創意者更新 中可能有所改進, 不過還未嘗試 ), 通過 Docker 客戶端連接遠程 Docker 服務 假裝 體驗下 Docker 也是不錯的。

參考文章


系列文章


Docker 學習總結

Docker 常用指令詳解

使用 Dockerfile 構建鏡像

使用 Docker Compose 構建容器

Docker 下的網絡模式


轉載請注明出處:http://www.jianshu.com/p/7ba1a93e6de4

      </div>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM