Skip to content

Commit

Permalink
Add API spec for FQDN selector
Browse files Browse the repository at this point in the history
  • Loading branch information
rahulkjoshi committed Feb 22, 2024
1 parent dc00b36 commit 134f95b
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 2 deletions.
2 changes: 1 addition & 1 deletion mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@ nav:
- Template: npeps/npep-95.md
- Provisional:
- npeps/npep-122.md
- npeps/npep-133.md
- Implementable:
- npeps/npep-137-conformance-profiles.md
- npeps/npep-126-egress-traffic-control.md
- npeps/npep-133-fqdn-egress-selector.md
# - Experimental:
# - Standard:
# - Declined:
Expand Down
130 changes: 129 additions & 1 deletion npeps/npep-133.md → npeps/npep-133-fqdn-egress-selector.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ Names](https://www.wikipedia.org/wiki/Fully_qualified_domain_name) (FQDNs).
filtering capabilities, like matching HTTP traffic or URL paths.
* This selector should not control what DNS records are resolvable from a
particular workload.
* This selector provides no capability to detect traffic destined for
different domains backed by the same IP (e.g. CDN or load balancers).
* This enhancement does not provide a mechanism for selecting in-cluster
endpoints using FQDNs. To select Pods, Nodes, or the API Server,
AdminNetworkPolicy has other more specific selectors.
Expand Down Expand Up @@ -106,7 +108,133 @@ line.

## API

TODO: https://github.com/kubernetes-sigs/network-policy-api/issues/133
This NPEP proposes adding a new type of `AdminNetworkPolicyEgressPeer` called
`FQDNPeerSelector` which allows specifying domain names.

```golang
type AdminNetworkPolicyEgressPeer struct {
<snipped>
// FQDNs provides a way to specify domain names as peers.
//
// FQDN is only supported for ALLOW rules. To restrict egress, use this
// selector with a lower priority deny rule (either an explicit DENY
// AdminNetworkPolicy rule or the implicit deny semantics of
// NetworkPolicy). This selector enumerates the allowed domains and the
// lower priority deny drops any non-matching traffic.
//
// Support: Extended
//
// +optional
FQDN *FQDNPeerSelector `json:"fqdn,omitempty"`
}

type FQDNPeerSelector struct {
// Name specifies the exact Fully-Qualified Domain Name to select (the
// trailing '.' is optional)
//
// Support: Extended
//
// +optional
// +kubebuilder:validation:Pattern=`^([a-zA-Z0-9]([-a-zA-Z0-9_]*[a-zA-Z0-9])*\.?)*$`
Name string `json:"names,omitempty"`

// Pattern allows matching FQDNs using wildcard specifiers.
//
// "*" matches 0 or more DNS valid characters (except for "."), and may
// occur anywhere in the pattern.
// Examples:
// - `*.kubernetes.io` matches subdomains of kubernetes.io at that level.
// "www.kubernetes.io" and "blog.kubernetes.io" match, however
// "kubernetes.io", "latest.blog.kubernetes.io", and "wikipedia.org" do
// not.
// - `sub*.kubernetes.io` matches subdomains of kubernetes.io where the
// subdomain component begins with "sub".
// "sub.kubernetes.io" and "subdomain.kubernetes.io" match, however
// "www.kubernetes.io", "blog.kubernetes.io", and "kubernetes.io do
// not.
// - `*.*.kubernetes.io` matches subdomains of kubernetes.io at that
// level.
// "sub.subdomain.kubernetes.io" matches, however "kubernetes.io" and
// "blog.kubernetes.io" do not.
// - `*a*.kubernetes.io` matches subdomains of kubernetes.io that contain
// an "a" at that level.
// "api.kubernetes.io" and "domain.kubernetes.io" match, however
// "blog.kubernetes.io" and "kubernetes.io" do not
//
// Support: Extended
//
// +optional
// +kubebuilder:validation:Pattern=`^([a-zA-Z0-9*]([-a-zA-Z0-9_*]*[a-zA-Z0-9*])*\.?)*$`
Pattern string `json:"pattern,omitempty"`
}
```

### Examples

#### Pods in `monitoring` namespace can talk to `my-service.com` and `*.cloud-provider.io`

```yaml
apiVersion: policy.networking.k8s.io/v1alpha1
kind: AdminNetworkPolicy
metadata:
name: allow-my-service-egress
spec:
priority: 55
subject:
namespaces:
matchLabels:
kubernetes.io/metadata.name: "monitoring"
egress:
- name: "allow-to-my-service"
action: "Allow"
to:
- fqdn:
name: "my-service.com"
- fqdn:
pattern: "*.cloud-provider.io"
ports:
- portNumber:
protocol: TCP
port: 443
```
### Expected Behavior
1. A FQDN egress policy does not grant the workload permission to communicate
with any in-cluster DNS services (like `kube-dns`). A separate rule needs to
be configured to allow traffic to any DNS servers.
1. FQDN policies should not affect the ability of workloads to resolve domains,
only their ability to communicate with the IP backing them.
* For example, if a policy allows traffic to `kubernetes.io`, any selected
Pods can still resolve `wikipedia.org` or
`my-services.default.svc.cluster.local`, but can not send traffic to them
unless allowed by a different rule.
1. Each implementation will provide guidance on which DNS name-server is
considered authoritative for resolving domain names. This could be the
`kube-dns` Service or potentially some other DNS provider specified in the
implementation's configuration.
1. DNS record querying and lifetimes:
* Pods are expected to make a DNS query for a domain before sending traffic
to it. If the Pod fails to send a DNS request and instead just sends
traffic to the IP (either because of caching or a static config), traffic
is not guaranteed to flow.
* Pods should respect the TTL of DNS records they receive. Trying to
establish new connection using DNS records that are expired is not
guaranteed to work.
* When the TTL for a DNS record expires, the implementor should stop allowing
new connections to that IP. Existing connection will still be allowed
(that's consistent with NetworkPolicy behavior on long-running
connectionsExisting connection will still be allowed (that's consistent
with NetworkPolicy behavior on long-running connections).
1. Targeting in-cluster endpoints with FQDN selector is not guaranteed to work:
* Selecting Pods using their [generated DNS
record](https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pods)
(for example `pod-ip-address.my-namespace.pod.cluster.local`) is not
guaranteed to work.
* Selecting Clusters services using their [generated DNS
record](https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#services)
(for example `my-svc.my-namespace.svc.cluster.local`) is not guaranteed to
work.

## Alternatives

Expand Down

0 comments on commit 134f95b

Please sign in to comment.