New in v0.7

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 →
Platform

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 ago
  • 8.8.8.0/24:53Raw IPshop / redisfirst seen 3 days ago
  • api.stripe.com:443Expectedshop / paymentsfirst seen 41 days ago
  • hooks.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 ago
  • 8.8.8.0/24:53Raw IPredis (docker-01)first seen 3 days ago
  • api.stripe.com:443Expectedstorefront · paymentsfirst seen 41 days ago
  • hooks.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:443 instead of 104.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.

  1. 01New external destinationKubernetesA 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.DockerThe same for a Compose service or a container on its host; a re-created container keeps its history.
  2. 02Raw IP egressKubernetesA workload opens 5 or more connections in 10 minutes to the same public network and port, with no DNS name behind the address.DockerThe same for a Compose service (its replicas added up) or a container.
  3. 03Large upload to a new destinationKubernetesA workload sends more than 100 MiB in an hour to a destination it first used in the last 24 hours.DockerThe 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 depth
  • 203.0.113.0/24a network, for raw addresses
The three kinds of pattern. Anything else is refused with the reason.

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.

How the policy is built →
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: "orders-egress"
spec:
  egress:
    - toFQDNs:
        - matchName: "api.stripe.com"
      toPorts:
        - ports:
            - port: "443"
              protocol: TCP
    …
An excerpt of a suggested policy.

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.

The same in Slack, Telegram and email; the webhook carries it as data.

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.

Connect your assistant →

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.

An example on Kubernetes, written from the docs.

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.