Docker架构
Docker基于CS(client-server)架构,Docker client简单来说就是执行docker ps, docker image list等命令的客户端,Docker daemon即运行在后台的dockerd进程,负责处理请求、运行、管理容器等工作,下图来自Docker官网,简单展示了Docker的架构。
既然是CS架构,Docker客户端就要连接Docker服务,二者可以作为同一主机上的两个进程,也可以是不同主机上的两个进程进行通信,都是使用REST API。另外,Docker Compose也是另一个单独的Docker client。
Docker Daemon
Docker daemon(dockerd)监听API请求并管理各种Docker对象,镜像、容器、网络和卷(volumes)。Docker daemon也可以与其他的daemon交互,管理docker服务。
Docker Client
Docker client(docker)是我们操作docker的接口,执行的docker命令被发送到Docker Daemon,处理后返回结果呈现在前端。Docker client可以同时与多个Docker Daemon交互。
Docker Desktop
Docker提供的图形化桌面应用,有Windows、Linux、Mac版本,涵盖了Docker Daemon、Docker client、Docker Compose、Docker Content Trust, Kubernetes,和Credential Helper,其中Windows是基于WSL的。
Docker registries
存储Docker镜像的地方,Pypi,Maven仓库类似。
Docker Daemon配置
配置Docker Daemon有两种方式
- 使用JSON文件,默认位置是/etc/docker/daemon.json
- dockerd启动参数
这种方式又有两个位置可以配置
/usr/lib/systemd/system/docker.service
- 非rootless模式下,
/etc/systemd/system/docker.service.d
/下所有的conf配置文件
推荐使用第二种方式,如果没有找到docker.sevice文件,可能你不是使用包安装管理器安装的docker,可以参考这个github仓库安装服务。
可以同时使用两种方式,dockerd会将启动参数和JSON文件中的配置合并,前提是两个位置的配置不能冲突,不能出现相同的配置选项(key)。
配置Docker远程连接
Docker配置远程连接
默认情况下,dockerd在unix套接字上监听本地docker client连接。配置远程连接有加密(基于TLS)和不加密两种方式,都可以通过systemd或者daemon.json完成,两种配置不能有冲突,否则会导致dockerd启动失败。
# ps -ef |grep dockerd
root 23438 1 0 00:41 ? 00:00:03 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
root 24354 24336 0 08:15 pts/0 00:00:00 grep --color=auto dockerd
Docker的客户端和服务端通信有三种方式
1、 -H unix://
指的是Docker使用本地的unix套接字 /var/run/docker.sock
进行通信
2、-H tcp://0.0.0.0:2376
使守护程序可以通过端口2376
上的任何网络接口使用。需要在安全组中打开此端口(并且,如果可能的话,请将该端口限制为IP地址白名单),以便远程客户端可以访问守护程序,为了安全起见,一般不建议开启。
3、-H fd://
这是在systemd
内部运行Docker
是使用的远程通信方式,由systemd
创建套接字并激活Docker
守护进程。
非安全方式
无需任何认证,任何客户端均可以与dockerd通信,不安全,不推荐。
编辑 docker 配置文件/lib/systemd/system/docker.service
, 找到运行主命令的那行,其内容大致为"ExecStart=/usr/bin/dockerd -H fd:// … "
的那一行,给dockerd命令加参数-H tcp://0.0.0.0:2376
,意思是在 2376
端口开放 API 访问。
ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2376 --containerd=/run/containerd/containerd.sock
重新加载
systemctl daemon-reload # 重新加载守护进程配置
systemctl restart docker.service # 重启 docker 服务
如果无法访问的话,可以尝试一下开放防火墙2376端口
TLS(HTTPS)安全方式
1、使用HTTPS会生成各种认证文件,新建文件夹用于生成这些文件。
mkdir /root/tls
cd /root/tls
# 环境变量,后面使用
# 这里指的ip或者是域名,都是指的将来用于对外的地址
HOST=服务器IP
2、生成CA证书
openssl genrsa -aes256 -out ca-key.pem 4096
# 执行输入两次密码
openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem
# 然后依次输入:访问密码、国家、省、市、组织名称、单位名称、随便一个名字、邮箱等。
# niceyoo cn beijing beijing niceyoo niceyoo niceyoo xxx@163.com
以下是示例输出
Generating RSA private key, 4096 bit long modulus
…++
…++
e is 65537 (0x10001)
Enter pass phrase for ca-key.pem:
Verifying - Enter pass phrase for ca-key.pem:
openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem
Enter pass phrase for ca-key.pem:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter ‘.’, the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:Queensland
Locality Name (eg, city) []:Brisbane
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Docker Inc
Organizational Unit Name (eg, section) []:Sales
Common Name (e.g. server FQDN or YOUR name) []:$HOST
Email Address []:Sven@home.org.au
$HOST即上面设置的服务器IP
3、生成服务器公钥
openssl genrsa -out server-key.pem 4096
# Generating RSA private key, 4096 bit long modulus
#.....................................................................++
#.................................................................................................++
#e is 65537 (0x10001)
openssl req -subj "/CN=$HOST" -sha256 -new -key server-key.pem -out server.csr
4、公钥签名 (白名单)
2种方式,2选1,这里我用第二种
# 1 、指定ip
echo subjectAltName = DNS:$HOST,IP:$HOST,IP:127.0.0.1 >> extfile.cnf
# 2、配置0.0.0.0,允许所有的ip可以链接(但只允许永久证书的才可以连接成功)
echo subjectAltName = DNS:$HOST,IP:0.0.0.0 >> extfile.cnf
echo extendedKeyUsage = serverAuth >> extfile.cnf
5、生成签名证书
openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -extfile extfile.cnf
# Signature ok
# subject=/CN=your.host.com
# Getting CA Private Key
# Enter pass phrase for ca-key.pem:
# 输入之前的密码
6、为客户端生成证书
openssl genrsa -out key.pem 4096
# Generating RSA private key, 4096 bit long modulus
# .........................................................++
................++
# e is 65537 (0x10001)
openssl req -subj '/CN=client' -new -key key.pem -out client.csr
echo extendedKeyUsage = clientAuth >> extfile.cnf
echo extendedKeyUsage = clientAuth > extfile-client.cnf
openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem -extfile extfile-client.cnf
# Signature ok
# subject=/CN=client
# Getting CA Private Key
# Enter pass phrase for ca-key.pem:
# 再次输入之前设置的密码
7、删除无用文件,修改权限
# 删除不需要的文件,两个整数签名请求
rm -v client.csr server.csr extfile.cnf extfile-client.cnf
# 为了保护您的密钥免于意外损坏,请删除其写入权限。要使它们仅供您阅读,请按以下方式更改文件模式:
chmod -v 0400 ca-key.pem key.pem server-key.pem
# 证书可以使对外可读的,删除写入权限以防止意外损坏:
chmod -v 0444 ca.pem server-cert.pem cert.pem
最后有以下几个文件
-r-------- 1 root root 3326 Aug 19 08:27 ca-key.pem
-r--r--r-- 1 root root 2130 Aug 19 08:27 ca.pem
-rw-r--r-- 1 root root 41 Aug 19 08:44 ca.srl
-r--r--r-- 1 root root 1883 Aug 19 08:44 cert.pem
-r-------- 1 root root 3243 Aug 19 08:43 key.pem
-r--r--r-- 1 root root 1948 Aug 19 08:30 server-cert.pem
-r-------- 1 root root 3243 Aug 19 08:28 server-key.pem
8、配置Docker Daemon启动
首先复制认证文件到/etc/docker下
cp -v {ca,cert,key}.pem /etc/docker
daemon.json方式,推荐 *
- 1、
vim /etc/docker/daemon.json
,添加以下内容
{
"hosts": ["unix:///var/run/docker.sock", "tcp://0.0.0.0:2376"],
"tls": true,
"tlscacert": "/etc/docker/ca.pem",
"tlscert": "/etc/docker/server-cert.pem",
"tlskey": "/etc/docker/server-key.pem",
"tlsverify": true
}
- 2、覆盖systemd中host配置,否则会启动失败,
vim /etc/systemd/system/docker.service.d/exec-start-conflit.conf
这里注意如果没有
exec-start-conflit.conf
文件,注解使用vi 创建对应的文件即可
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd --containerd=/run/containerd/containerd.sock
systemd方式
vim /etc/systemd/system/docker.service.d/exec-start-conflit.conf
[Service]
ExecStart=
ExecStart= --tlsverify --tls --tlscacert=/etc/docker/ca.pem --tlscert=/etc/docker/server-cert.pem --tlskey=/etc/docker/server-key.pem -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2376 --containerd=/run/containerd/containerd.sock
两种方式配置完后,都需要重启docker
systemctl daemon-reload
systemctl restart docker
# 检查2376端口是否打开
netstat -nltp | grep 2376
# 本地是否正常执行
docker ps
客户端连接Docker Daemon
拷贝ca.pem、cert.pem、key.pem
到客户端主机指定文件夹。
docker --tlsverify \
--tlscacert=ca.pem \
--tlscert=cert.pem \
--tlskey=key.pem \
-H=$HOST:2376 version
idea连接