Docker环境运行Squid

Ubuntu的母公司Canonical在dockerhub官方维护了一个基于 Ubuntu LTS 的squid镜像 ubuntu/squid Docker Image ,并提供了长期安全维护。本文作为 Kubernetes部署Squid快速起步 的前奏,在本地docker环境运行 Squid代理服务 测试。

准备工作

  • 准备物理主机上的squid缓存和日志目录,这样docker容器挂载卷可以加速IO性能,也能够保证缓存数据和日志不丢失:

在物理主机创建squid容器的卷
BASE_DIR=/Users/huataihuang/docs/studio
VAR_DIR=${BASE_DIR}/var
ETC_DIR=${BASE_DIR}/etc

mkdir -p ${VAR_DIR}/log/squid
mkdir -p ${VAR_DIR}/spool/squid
mkdir -p ${VAR_DIR}/cache/squid
mkdir -p ${ETC_DIR}/squid
fedora默认初始squid配置: /etc/squid/squid.conf
acl localnet src 0.0.0.1-0.255.255.255	# RFC 1122 "this" network (LAN)
acl localnet src 10.0.0.0/8		# RFC 1918 local private network (LAN)
acl localnet src 100.64.0.0/10		# RFC 6598 shared address space (CGN)
acl localnet src 169.254.0.0/16 	# RFC 3927 link-local (directly plugged) machines
acl localnet src 172.16.0.0/12		# RFC 1918 local private network (LAN)
acl localnet src 192.168.0.0/16		# RFC 1918 local private network (LAN)
acl localnet src fc00::/7       	# RFC 4193 local private network range
acl localnet src fe80::/10      	# RFC 4291 link-local (directly plugged) machines

acl SSL_ports port 443
acl Safe_ports port 80		# http
acl Safe_ports port 21		# ftp
acl Safe_ports port 443		# https
acl Safe_ports port 70		# gopher
acl Safe_ports port 210		# wais
acl Safe_ports port 1025-65535	# unregistered ports
acl Safe_ports port 280		# http-mgmt
acl Safe_ports port 488		# gss-http
acl Safe_ports port 591		# filemaker
acl Safe_ports port 777		# multiling http

http_access deny !Safe_ports

http_access deny CONNECT !SSL_ports

http_access allow localhost manager
http_access deny manager

http_access allow localnet
http_access allow localhost

http_access deny all

http_port 3128

cache_dir ufs /var/cache/squid 100 16 256

coredump_dir /var/spool/squid

refresh_pattern ^ftp:		1440	20%	10080
refresh_pattern ^gopher:	1440	0%	1440
refresh_pattern -i (/cgi-bin/|\?) 0	0%	0
refresh_pattern .		0	20%	4320

运行

  • 执行运行命令:

docker run运行squid容器,注意取消了 --network kind 参数(见上文),采用默认网络
# 请根据实际目录修订 BASE_DIR
BASE_DIR=/Users/huataihuang/docs/studio

squid_version=5.2-22.04_beta

docker run -dt --name squid --hostname squid \
    -e TZ=Asia/Shanghai -p 3128:3128 \
    -v ${BASE_DIR}/var/log/squid:/var/log/squid \
    -v ${BASE_DIR}/var/spool/squid:/var/spool/squid \
    -v ${BASE_DIR}/var/cache/squid:/var/cache/squid \
    -v ${BASE_DIR}/etc/squid/squid.conf:/etc/squid/squid.conf \
    ubuntu/squid:${squid_version}
ubuntu/squid镜像参数

参数

说明

-e TZ=Asia/Shanghai

时区

-p 3128:3128

输出代理服务

-v /Users/huataihuang/docs/studio/var/log/squid:/var/log/squid

存储squid日志目录

-v /Users/huataihuang/docs/studio/var/spool/squid:/var/spool/squid

存储squid缓存目录

-v /Users/huataihuang/docs/studio/etc/squid/squid.conf:/etc/squid/squid.conf

squid主配置文件

-v /path/to/config/snippet:/etc/squid/conf.d/snippet.conf

squid.conf配置包含的配置片段(未使用)

后期配置(关键点)

备注

我最初考虑将这个 squid 容器连接到 macOS工作室 构建的 kind(本地docker模拟k8s集群) 内置的 kind bridge网络,这样就可以同时为整个 dev kind 集群提供代理。但是我发现 docker build 不能指定具体网络( docker run 可以),而只能指定网络模式( bridgehost ),这导致将 squid 容器运行在 kind 代理后就不能给默认网路进行代理。

标准方法,对于 kind 网络上的 node 以及 conatiner 还是采用标准的 Kubernetes部署Squid快速起步 构建的 pod ,将Kubernetes化的 Squid代理服务 来提供 kind 网络代理加速。

我想了一下,可以在这个docker化的 squid 容器中插入多个网络接口,为 docker 所有网络提供代理服务。但是由于每个docker网络的网段不同,分配IP不同,所以配置代理的时候不使用IP地址,而是采用域名解析:

  • 发现Docker的DNS解析也比较复杂,需要研究 CoreDNS

  • 比较简单的方法是将 /etc/hosts 文件bind到容器内部,这样可以控制容器主机名解析不同网段 squid 的对应IP

当然,在 Kubernetes 集群,采用静态 /etc/hosts 维护繁琐易出错,所以采用 CoreDNS 来构建解析

参考 修复kind集群重启异常 相似方法,设置 squid 容器固定IP地址:

  • 首先获取docker容器的所有IP地址:

获取docker容器的IP地址
docker inspect -f '{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -aq)
  • 我尝试以下命令将 squid 容器的IP地址固定为当前动态分配的IP地址:

    docker stop squid
    docker network connect --ip 172.17.0.3 "bridge" "squid"
    

但是这里会报错:

Error response from daemon: user specified IP address is supported on user defined networks only

但是考虑到这个容器 squid` 绑定了 0.0.0.0:3128 ,是否可以作为通用的访问代理呢?类似在 kind集群本地Registry 通过 localhost:5001 访问本地的 registry ,是否可以在容器中通过访问 localhost:3128 访问代理服务器呢?

验证不行

检查

一切运行正常,检查 docker ps 可以看到:

CONTAINER ID   IMAGE                                COMMAND                  CREATED         STATUS         PORTS                       NAMES
cc2e1ee10eba   ubuntu/squid:5.2-22.04_beta          "entrypoint.sh -f /e…"   4 minutes ago   Up 4 minutes   0.0.0.0:3128->3128/tcp      squid
  • 检查squid日志:

    docker logs -f squid
    
  • 进入容器内部检查:

    docker exec -it squid /bin/bash
    

在容器内部可以使用 APT包管理 安装 Ubuntu Linux 相关操作系统工具,方便排查一些问题,例如 apt install iproute2 工具可以帮助检查容器IP地址和路由等

备注

我是在 macOS工作室 上运行 Docker Desktop for macOS,测试不能使用本物理主机的系统级代理设置,会导致docker出去的http/https被反向代理回去(似乎)。采用chrome结合SwitchyOmega设置chrome自身代理来进程测试(因为chrome可以不依赖系统代理设置) ,就能够验证squid是否工作正常。

下一步

参考