之前部署docker的时候都是没对docker的HTTP/socker接口进行加密。最近在线上部署的时候就得考虑这个。使用证书对docker进行加密主要参考官方的文档:
1. https://docs.docker.com/v1.13/engine/security/https/
2. https://github.com/docker/swarm/issues/341
docker engine配置TLS
主要注意做swarm cluster的时候 需要签发证书的时候subjectAltName里把本机的IP。生成证书的从网上找到的一个脚本做了修改,直接在里面把集群的IP都填进去,这样每个机器可以证书相同:
#!/bin/bash
# This script will help you setup Docker for TLS authentication.
# Run it passing in the arguement for the FQDN of your docker server
#
# For example:
# ./create-docker-tls.sh myhost.docker.com
#
# The script will also create a profile.d (if it exists) entry
# which configures your docker client to use TLS
#
# We will also overwrite /etc/sysconfig/docker (again, if it exists) to configure the daemon.
# A backup will be created at /etc/sysconfig/docker.unixTimestamp
#
# MIT License applies to this script. I don't accept any responsibility for
# damage you may cause using it.
#
set -e
STR=2048
if [ "$#" -gt 1 ]; then
DOCKER_HOST1="$1"
DOCKER_HOST2="$2"
else
echo " => ERROR: You must specify the docker FQDN as the first arguement to this scripts! <="
exit 1
fi
if [ "$USER" == "root" ]; then
echo " => WARNING: You're running this script as root, therefore root will be configured to talk to docker"
echo " => If you want to have other users query docker too, you'll need to symlink /root/.docker to /theuser/.docker"
fi
echo " => Using : $DOCKER_HOST1 You MUST connect to docker using this host!"
echo " => Ensuring config directory exists..."
cd ./cert
echo " => Verifying ca.srl"
if [ ! -f "ca.src" ]; then
echo " => Creating ca.srl"
echo 01 > ca.srl
fi
echo " => Generating CA key"
openssl genrsa \
-out ca-key.pem $STR
echo " => Generating CA certificate"
openssl req \
-new \
-key ca-key.pem \
-x509 \
-sha256 \
-days 3650 \
-nodes \
-subj "/CN=$" \
-out ca.pem
echo " => Generating server key"
openssl genrsa \
-out server-key.pem $STR
echo " => Generating server CSR"
openssl req \
-subj "/CN=$DOCKER_HOST1" \
-new \
-sha256 \
-key server-key.pem \
-out server.csr
echo " => Signing server CSR with CA"
echo subjectAltName = "DNS:$DOCKER_HOST1,DNS:$DOCKER_HOST2,IP:127.0.0.1,IP:XXXXXX,IP:XXXXXX,IP:XXXXX,IP:XXXXX" > extfile-server.cnf
openssl x509 \
-req \
-days 3650 \
-sha256 \
-in server.csr \
-CA ca.pem \
-CAkey ca-key.pem \
-out server-cert.pem \
-extfile extfile-server.cnf
echo " => Generating client key"
openssl genrsa \
-out key.pem $STR
echo " => Generating client CSR"
openssl req \
-subj "/CN=docker.client" \
-new \
-key key.pem \
-out client.csr
echo " => Creating extended key usage"
echo extendedKeyUsage = clientAuth > extfile.cnf
echo " => Signing client CSR with CA"
openssl x509 \
-req \
-days 3650 \
-sha256 \
-in client.csr \
-CA ca.pem \
-CAkey ca-key.pem \
-out cert.pem \
-extfile extfile.cnf
if [ -d "/etc/profile.d" ]; then
echo " => Creating profile.d/docker"
sudo sh -c "echo '#!/bin/bash
export DOCKER_CERT_PATH=/home/$USER/.docker
export DOCKER_HOST=tcp://$DOCKER_HOST1:2376
export DOCKER_TLS_VERIFY=1' > /etc/profile.d/docker.sh"
sudo chmod +x /etc/profile.d/docker.sh
source /etc/profile.d/docker.sh
else
echo " => WARNING: No /etc/profile.d directoy on your system."
echo " => You will need to set the following environment variables before running the docker client:"
echo " => DOCKER_HOST=tcp://$DOCKER_HOST1:2376"
echo " => DOCKER_TLS_VERIFY=1"
fi
OPTIONS="--tlsverify --tlscacert=$HOME/.docker/ca.pem --tlscert=$HOME/.docker/server-cert.pem --tlskey=$HOME/.docker/server-key.pem -H=0.0.0.0:2376"
if [ -f "/etc/sysconfig/docker" ]; then
echo " => Configuring /etc/sysconfig/docker"
BACKUP="/etc/sysconfig/docker.$(date +"%s")"
sudo mv /etc/sysconfig/docker $BACKUP
sudo sh -c "echo '# The following line was added by ./create-certs docker TLS configuration script
OPTIONS="$OPTIONS"
# A backup of the old file is at $BACKUP.' >> /etc/sysconfig/docker"
echo " => Backup file location: $BACKUP"
else
echo " => WARNING: No /etc/sysconfig/docker file found on your system."
echo " => You will need to configure your docker daemon with the following options:"
echo " => $OPTIONS"
fi
export DOCKER_HOST=tcp://DOCKER_HOST:2376
export DOCKER_TLS_VERIFY=1
echo " => Done! You just need to restart docker for the changes to take effect"
附上docker.service
[Unit]
Description=Docker Application Container Engine
Documentation=http://docs.docker.com
After=network.target
Wants=docker-storage-setup.service
[Service]
Type=notify
EnvironmentFile=-/etc/sysconfig/docker
EnvironmentFile=-/etc/sysconfig/docker-storage
EnvironmentFile=-/etc/sysconfig/docker-network
Environment=GOTRACEBACK=crash
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock $OPTIONS \
--tlsverify --tlscacert=/etc/docker/cert/ca.pem --tlscert=/etc/docker/cert/server-cert.pem --tlskey=/etc/docker/cert/server-key.pem \
--storage-driver=overlay \
--cluster-store etcd://xxxxxx:2379/vxlan \
--cluster-advertise=bond0:2375 \
$DOCKER_STORAGE_OPTIONS \
$DOCKER_NETWORK_OPTIONS \
$ADD_REGISTRY \
$BLOCK_REGISTRY \
$INSECURE_REGISTRY
LimitNOFILE=1048576
LimitNPROC=1048576
LimitCORE=infinity
MountFlags=slave
TimeoutStartSec=1min
Restart=on-failure
[Install]
WantedBy=multi-user.target
swarm使用TLS
- 创建manage
sudo docker run --restart=always -v /etc/docker/cert/:/cert/ --name swarm-manage -d -p 8888:2375 swarm -l debug manage --tlsverify --tlscacert=/cert/ca.pem --tlscert=/cert/server-cert.pem --tlskey=/cert/server-key.pem etcd://xxxxx:2379/swarm
- 启动agent
sudo docker run --restart=always --name swarm-agent -d swarm join --addr=`hostname -i`:2375 etcd://xxxxx:2379/swarm
使用TLS连接swarm
$export DOCKER_HOST=tcp://xxxxx:8888 DOCKER_TLS_VERIFY=1
$docker version
Client:
Version: 1.13.1
API version: 1.24 (downgraded from 1.26)
Go version: go1.7.5
Git commit: 092cba3
Built: Wed Feb 8 06:38:28 2017
OS/Arch: linux/amd64
Server:
Version: swarm/1.2.6
API version: 1.22 (minimum version )
Go version: go1.7.1
Git commit: `git rev-parse --short HEAD`
Built: `date -u`
OS/Arch: linux/amd64
Experimental: false