What is your cluster talking to?
WatchLog keeps a record of every external destination each workload or container uses, since when, and tells you when something starts talking somewhere new. On Kubernetes and Docker, from the connections the agent already counts.
Read the Egress watch docs →What acme-prod talks to on the internet
Learned from 41 days of traffic · names from DNS answers
cdn-update-check.xyz:443Newshop / ordersfirst seen 8 min ago8.8.8.0/24:53Raw IPshop / redisfirst seen 3 days agoapi.stripe.com:443Expectedshop / paymentsfirst seen 41 days agohooks.example.org:443Failingops / notifierfirst seen 12 days ago · 18% failed
What docker-prod talks to on the internet
Learned from 41 days of traffic · names from DNS answers
cdn-update-check.xyz:443Newstorefront · apifirst seen 8 min ago8.8.8.0/24:53Raw IPredis (docker-01)first seen 3 days agoapi.stripe.com:443Expectedstorefront · paymentsfirst seen 41 days agohooks.example.org:443Failingstorefront · notifierfirst seen 12 days ago · 18% failed
From connections only
- Per workload or container, destination and port: connections, bytes sent and received, and failed connections. The same counts the service map uses; nothing new is collected.
- Names come from the DNS answers the container received, so
api.stripe.com:443instead of104.18.0.0/24:443. An address no answer explains shows as its network. - Never read: payloads, TLS SNI, HTTP hosts or paths. HTTPS isn't decrypted, and the agent stays under 64 MB and 1 % of a core per node.
- Destination names are shown as text, never as links: anyone can register a domain.
- In every edition, Community included, and in every Cloud plan.
Kubernetes and Docker, each in its own words
Kubernetes
Every workload is a source:
shop/Deployment/orders. A pod's connections count for its workload, and a CronJob is one source across its runs. The Egress page filters by namespace and workload; the workload and pod pages show "Talks to the internet".Docker
Every Compose service is a source (
storefront/api), so a re-created container keeps its history; any other container is its name on its host. The page filters by host, Compose project and container; the container and Compose service pages show "Talks to the internet".
One row per destination, four badges
Each row is a destination and port with every source that talks to it, first and last seen, bytes each way, connections and the failed share, over 1 hour to 30 days.
- New
A workload or container first used this destination in the last 24 hours. Only names and public networks are ever new.
- Raw IP
A public address dialled directly, with no DNS name behind it.
- Failing
At least 5 % of its connections failed in the range.
- Expected
Covered by something you marked expected: a name, a pattern such as *.amazonaws.com, or a network.
Three rules, quiet while it learns
On by default for every cluster and fleet, editable like every rule. "New external destination" waits 7 days while WatchLog learns what a cluster, and each new workload or container, normally talks to. After an upgrade the learning starts at the upgrade, so nothing already in use raises an alert.
- 01New external destination
A workload starts talking to a name or public network it never used, after its learning period. Resolves when marked expected, or after 24 hours without traffic.
The same for a Compose service or a container on its host; a re-created container keeps its history.
- 02Raw IP egress
A workload opens 5 or more connections in 10 minutes to the same public network and port, with no DNS name behind the address.
The same for a Compose service (its replicas added up) or a container.
- 03Large upload to a new destination
A workload sends more than 100 MiB in an hour to a destination it first used in the last 24 hours.
The same for a Compose service or a container.
The learning period is a setting: alerting.egressLearningDays in the Helm chart, WATCHLOG_EGRESS_LEARNING_DAYS for the Docker Compose server.
Mark what you expect
Your cluster will meet a new *.amazonaws.com name every week. Mark it expected once, for one workload or container or for all of them, on this port or any, and "New external destination" stays quiet for every name under it, including names not seen yet.
A raw address or a large upload still alerts: an expected name doesn't make them expected. Owners and Admins mark; every change is audited.
Names, patterns and networks →api.stripe.comexactly this name*.amazonaws.comany name under it, at any depth203.0.113.0/24a network, for raw addresses
A suggested egress policy, for Kubernetes
On a workload's page, WatchLog writes the policy that allows what the workload actually reached in the last 30 days: a CiliumNetworkPolicy with toFQDNs when Cilium is installed, or a standard NetworkPolicy for any network plugin. Copy it, review it, try it in staging. WatchLog never applies it.
Docker has no standard egress policy object, so Docker pages don't get one: they point to internal: true networks and host firewall rules instead.
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: "orders-egress"
spec:
egress:
- toFQDNs:
- matchName: "api.stripe.com"
toPorts:
- ports:
- port: "443"
protocol: TCP
…In the alert itself
What started talking, to what, since when, and the likely cause: a rollout or image change just before the first connection (on Docker, a re-created container or a Compose change). Slack and Telegram show the destination as code, never as a link.
The rules and their messages →WARNING · orders started talking to cdn-update-check.xyz:443
first connection at 08:12 UTC · nothing else in the cluster talks to it
shop/orders (Deployment) · cluster acme-prod · since 08:12 UTC (3 min)
Likely cause: Started 7 minutes after orders was changed to image shop/orders:3.8.2.
Ask your AI what changed
Claude and ChatGPT read the same record through WatchLog's MCP server, read-only: get_egress, get_new_destinations and get_expected_destinations. Destination names come back as data, never inside WatchLog's own sentences.
Did anything in shop start talking somewhere new this week?
get_new_destinations
One: orders first connected to cdn-update-check.xyz:443 today at 08:12, and nothing else in the cluster talks to it. It isn't marked expected.
The limits, said plainly
- 50 destinations per sourceThe agent keeps 50 per source, per node, per hour; beyond that they show as "Other destinations", never as new.
- Processes under 15 secondsA pod or container that connects and exits before the agent’s next read isn’t attributed to any source.
- Forgotten after 90 daysA destination unused for 90 days leaves the record and is new again if it comes back. What you marked expected stays.
- Names from DNS answers onlyDNS-over-HTTPS or DNS-over-TLS hides the name: those destinations show as their network.