Skip to content

Squid Proxy(Kubernetes 部署)

在 Kubernetes 叢集中部署 Squid 正向代理,透過 Azure Internal LoadBalancer 提供內網 HTTP/HTTPS 代理服務。

概述

Squid 是一款歷史悠久的正向代理(Forward Proxy)伺服器,常用於內網環境中為後端服務提供對外 HTTP/HTTPS 存取能力。在 Kubernetes 環境中部署 Squid,可以讓叢集內的 Pod 或內網機器透過統一的代理出口存取外部資源,同時保留存取控制與快取功能。

本文記錄的部署方案採用 ubuntu/squid:edge 映像,搭配 Azure Internal LoadBalancer 將 Squid 服務暴露至內網固定 IP,並透過 ConfigMap 管理設定檔、PVC 保存快取資料。

核心內容

架構與網路拓撲

Squid 部署在 ingress-basic namespace 中,透過 Azure Internal LoadBalancer 綁定至固定內網 IP 10.30.196.60,監聽埠號 3128。Service 同時暴露 31283129 兩個埠,但 targetPort 均指向容器的 3128——這是為了讓不同的客戶端或 Prometheus Exporter 部署模式 能透過不同埠號連入同一個 Squid 實例。

ACL 存取控制

Squid 的安全性主要透過 ACL(Access Control List)機制實現。設定中定義了以下幾層控制:

網段白名單(localnet): 涵蓋所有 RFC 1918 私有網段(10.0.0.0/8172.16.0.0/12192.168.0.0/16)、RFC 6598 共享位址空間、以及 IPv6 本地網段。凡是來自這些網段的請求皆被允許。

Exporter 專用存取: 特別為 10.30.196.0/24 網段開放 Squid Cache Manager 存取權限,以便 Prometheus Exporter 部署模式 能採集指標。其餘來源對 Cache Manager 的存取一律拒絕。

埠號限制: 僅允許連線至 Safe Ports(80、443、21 等常見埠號以及 1025-65535 高埠範圍),且 CONNECT 方法僅限 SSL 埠(443)。

快取策略

Squid 使用 refresh_pattern 指令控制快取行為,針對 FTP、Gopher 等協定有不同的快取時間設定。快取資料儲存在透過 PVC 掛載的 /var/spool/squid 目錄,使用 managed-csi StorageClass 提供 500MB 的持久化儲存。

Kubernetes 資源配置

部署涉及三個主要資源:

PersistentVolumeClaim: 使用 managed-csi StorageClass 請求 500MB 儲存空間,掛載至容器的 /var/spool/squid 作為快取目錄。

ConfigMap: 將完整的 squid.conf 以 ConfigMap 形式存入叢集,透過 subPath 掛載至 /etc/squid/squid.conf,實現設定檔與映像的解耦。

Deployment: 單副本部署,配置 CPU 200m / Memory 1024Mi 的資源請求(目前未設定 limits,生產環境建議補上)。

關鍵要點

  • Squid 透過 Azure Internal LoadBalancer 綁定固定 IP,讓內網客戶端能以穩定的代理位址存取
  • ACL 機制提供多層存取控制:網段白名單、埠號限制、Cache Manager 存取限制
  • 設定檔透過 ConfigMap + subPath 掛載,便於版本管理與動態更新
  • 快取目錄使用 PVC 持久化,避免 Pod 重啟後快取遺失
  • 目前僅設定 resources.requests,建議生產環境補上 resources.limits

實際應用

在企業內網環境中,許多後端服務需要透過代理才能存取外部資源(例如下載套件、呼叫外部 API)。部署 Squid 作為統一出口,可以集中管理存取策略、提供快取加速、並便於稽核網路流量。搭配 Prometheus Exporter 部署模式 可進一步監控代理的使用狀況。

部署設定參考

以下為實際部署時使用的完整設定,供日後查詢與複製使用。

環境參數

項目
映像檔ubuntu/squid:edge
Namespaceingress-basic
監聽埠3128
Service 類型LoadBalancer(Azure 內部)
Load Balancer IP10.30.196.60
PVC 大小500M(StorageClass: managed-csi

完整 squid.conf

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 exporter_net src 10.30.196.0/24
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
acl CONNECT method CONNECT
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localhost manager
http_access allow exporter_net manager
http_access deny manager
http_access allow localhost
http_access allow localnet
http_access deny all
http_port 3128
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 \/(Packages|Sources)(|\.bz2|\.gz|\.xz)$ 0 0% 0 refresh-ims
refresh_pattern \/Release(|\.gpg)$ 0 0% 0 refresh-ims
refresh_pattern \/InRelease$ 0 0% 0 refresh-ims
refresh_pattern \/(Translation-.*)(|\.bz2|\.gz|\.xz)$ 0 0% 0 refresh-ims
refresh_pattern .               0       20%     4320
logfile_rotate 0

Kubernetes YAML(PVC + Service + Deployment)

yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: squid-volume-claim
  namespace: ingress-basic
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: managed-csi
  resources:
    requests:
      storage: 500M

---

apiVersion: v1
kind: Service
metadata:
  name: squid-service
  namespace: ingress-basic
  annotations:
    service.beta.kubernetes.io/azure-load-balancer-internal: "true"
    service.beta.kubernetes.io/azure-load-balancer-ipv4: 10.30.196.60
  labels:
    app: squid
spec:
  type: LoadBalancer
  ports:
  - port: 3128
    targetPort: 3128
    name: squid-http
  - port: 3129
    targetPort: 3128
    name: squid-http2
  selector:
    app: squid

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: squid-deployment
  namespace: ingress-basic
spec:
  replicas: 1
  selector:
    matchLabels:
      app: squid
  template:
    metadata:
      labels:
        app: squid
    spec:
      containers:
      - name: squid
        image: ubuntu/squid:edge
        ports:
        - containerPort: 3128
          name: squid
          protocol: TCP
        volumeMounts:
        - name: squid-config-volume
          mountPath: /etc/squid/squid.conf
          subPath: squid.conf
        - name: squid-data
          mountPath: /var/spool/squid
        resources:
          requests:
            cpu: 200m
            memory: 1024Mi
      volumes:
        - name: squid-config-volume
          configMap:
            name: squid-config
            items:
            - key: squid
              path: squid.conf
        - name: squid-data
          persistentVolumeClaim:
            claimName: squid-volume-claim

Volume 掛載摘要

Volume 名稱來源容器掛載路徑用途
squid-config-volumeConfigMap squid-config(key: squid/etc/squid/squid.confSquid 設定檔
squid-dataPVC squid-volume-claim/var/spool/squid快取資料目錄

相關概念

來源