Files

76 lines
2.6 KiB
Go

package kubernetes
import (
"fmt"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"gitea.home.hrajfrisbee.cz/kacerr/egress-proxies-operator/internal/provider"
)
const proxyContainerName = "squid"
// writeConfigAndExec is the container's entrypoint: write the config the
// SQUID_CONF env var carries to disk, then exec squid against it. Avoids a
// separate ConfigMap object per proxy instance — there's still only one
// Kubernetes object (the Pod) to create, track, and clean up per proxy.
const writeConfigAndExec = `printf '%s' "$SQUID_CONF" > /etc/squid/squid.conf && exec squid -N -f /etc/squid/squid.conf`
// buildPod constructs the Pod for a proxy instance. Pure and side-effect
// free, so it's unit-tested directly without a cluster — the same pattern
// the GCP provider's buildInsertRequest uses.
func buildPod(image string, req provider.CreateRequest) *corev1.Pod {
return &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: req.Name,
Namespace: req.Namespace,
Labels: map[string]string{
provider.LabelManaged: provider.LabelManagedYes,
provider.LabelUID: req.UID,
},
},
Spec: corev1.PodSpec{
RestartPolicy: corev1.RestartPolicyAlways,
Containers: []corev1.Container{{
Name: proxyContainerName,
Image: image,
Command: []string{"/bin/sh", "-c"},
Args: []string{writeConfigAndExec},
Env: []corev1.EnvVar{{
Name: "SQUID_CONF",
Value: squidConf(req.Port),
}},
Ports: []corev1.ContainerPort{{
ContainerPort: req.Port,
Protocol: corev1.ProtocolTCP,
}},
}},
},
}
}
// squidConf generates a minimal Squid config listening on port, permissive
// enough to forward CONNECT and plain HTTP to any destination. Open by
// design: this is a proxy for a private cluster, not internet-facing, and
// installing/configuring proxy software is explicitly out of scope for
// this operator's real (GCP) provider too — cloud-init is passed through
// there, never interpreted. via/forwarded_for are turned off so the proxy
// doesn't leak the Pod's identity to the origin.
func squidConf(port int32) string {
// max_filedescriptors is load-bearing in containers: squid sizes its FD
// tables from RLIMIT_NOFILE at startup, and containerd commonly sets
// that to effectively unlimited (kind: ~10^9) — squid then allocates
// gigabytes and is OOM-killed before it ever listens. cache_mem is
// trimmed because a forwarding proxy for crawling gains nothing from
// squid's 256 MB default cache.
return fmt.Sprintf(`http_port %d
acl all src 0.0.0.0/0
http_access allow all
via off
forwarded_for off
max_filedescriptors 1024
cache_mem 16 MB
`, port)
}