Commit Graph

79 Commits

Author SHA1 Message Date
Oliver Gould 9bf10cbc95
Update to kubert v0.6, kube v0.71 (#8269)
Signed-off-by: Oliver Gould <ver@buoyant.io>
2022-04-15 09:28:46 -07:00
Oliver Gould 1a0c1c3172
policy: Support empty `requiredAuthenticationRefs` (#8185)
Currently, the policy admission controller requires that the
`AuthorizationPolicy` resources include a non-empty
`requiredAuthenticationRefs` field. This means that all authorization
policies require at least a `NetworkAuthentication` to permit traffic.
For example:

```yaml
---
apiVersion: policy.linkerd.io/v1alpha1
kind: AuthorizationPolicy
metadata:
  name: ingress
spec:
  targetRef:
    group: policy.linkerd.io
    kind: Server
    name: ingress-http
  requiredAuthenticationRefs:
  - group: policy.linkerd.io
    kind: NetworkAuthentication
    name: all-nets
---
apiVersion: policy.linkerd.io/v1alpha1
kind: NetworkAuthentication
metadata:
  name: ingress-all-nets
spec:
  networks:
  - cidr: 0.0.0.0/0
  - cidr: ::/0
```

This is needlessly verbose and can more simply be expressed as:

```yaml
---
apiVersion: policy.linkerd.io/v1alpha1
kind: AuthorizationPolicy
metadata:
  name: ingress
spec:
  targetRef:
    group: policy.linkerd.io
    kind: Server
    name: ingress-http
  requiredAuthenticationRefs: []
```

That is: there are explicitly no required authentications for this
policy.

This change updates the admission controller to permit such a policy.
Note that the `requiredAuthenticationRefs` field is still required so
that it's harder for simple misconfigurations to result in allowing
traffic.

This change also removes `Default` implementation for resources where do
they not make sense because there are required fields.

Signed-off-by: Oliver Gould <ver@buoyant.io>
2022-04-01 10:16:35 -07:00
Oliver Gould c1a1430d1a
Introduce AuthorizationPolicy CRDs (#8007)
Issue #7709 proposes new Custom Resource types to support generalized
authorization policies:

- `AuthorizationPolicy`
- `MeshTLSAuthentication`
- `NetworkAuthentication`

This change introduces these CRDs to the default linkerd installation
(via the `linkerd-crds` chart) and updates the policy controller's
to handle these resource types. The policy admission controller
validates that these resource reference only suppported types.

This new functionality is tested at multiple levels:

* `linkerd-policy-controller-k8s-index` includes unit tests for the
  indexer to test how events update the index;
* `linkerd-policy-test` includes integration tests that run in-cluster
  to validate that the gRPC API updates as resources are manipulated;
* `linkerd-policy-test` includes integration tests that exercise the
  admission controller's resource validation; and
* `linkerd-policy-test` includes integration tests that ensure that
  proxies honor authorization resources.

This change does NOT update Linkerd's control plane and extensions to
use these new authorization primitives. Furthermore, the `linkerd` CLI
does not yet support inspecting these new resource types. These
enhancements will be made in followup changes.

Signed-off-by: Oliver Gould <ver@buoyant.io>
2022-03-30 12:26:45 -07:00
Oliver Gould 00954d71c6
policy: Add end-to-end ServerAuthorization tests (#8155)
In preparation for new policy CRD resources, this change adds end-to-end
tests to validate policy enforcement for `ServerAuthorization`
resources.

In adding these tests, it became clear that the OpenAPI validation for
`ServerAuthorization` resources is too strict. Various `oneof`
constraints have been removed in favor of admission controller
validation. These changes are semantically compatible and do not
necessitate an API version change.

The end-to-end tests work by creating `curl` pods that call an `nginx`
pod. In order to test network policies, the `curl` pod may be created
before the nginx pod, in which case an init container blocks execution
until a `curl-lock` configmap is deleted from the cluster. If the
configmap is not present to begin with, no blocking occurs.

Signed-off-by: Oliver Gould <ver@buoyant.io>
2022-03-28 14:03:24 -07:00
Oliver Gould 4f5a8059a5
policy: Refactor indexing module (#8082)
The policy controller's indexing module spans several files and relies
on an unnecessarily complex double-watch. It's generally confusing and
therefore difficult to change.

This change attempts to simplify the logic somewhat:

* All of the indexing code is now in the
  `linkerd_policy_controller_k8s_index::index` module. No other files
  have any dependencies on the internals of this data structure. It
  exposes one public API, `Index::pod_server_rx`, used by discovery
  clients.
* It uses the new `kubert::index` API so that we can avoid redundant
  event-handling code. We now let kubert drive event processing so that
  our indexing code is solely responsible for updating per-port server
  configurations.
* A single watch is maintained for each pod:port.
* Watches are constructed lazily. The policy controller no longer
  requires that all ports be documented on a pod. (The proxy still
  requires this, however). This sets up for more flexible port
  discovery.

Signed-off-by: Oliver Gould <ver@buoyant.io>
2022-03-22 13:17:57 -07:00
Oliver Gould e094830f70
Update kube to v0.70, kubert to v0.5 (#8111)
Signed-off-by: Oliver Gould <ver@buoyant.io>
2022-03-21 12:15:00 -07:00
Oliver Gould c445c72d61
policy: Validate ServerAuthorization resources (#8076)
`ServerAuthorization` resources are not validated by the admission
controller.

This change enables validation for `ServerAuthorization` resources,
based on changes to the admission controller proposed as a part of
linkerd/linkerd2#8007. This admission controller is generalized to
support arbitrary resource types. The `ServerAuthoriation` validation
currently only ensures that network blocks are valid CIDRs and that they
are coherent. We use the new _schemars_ feature of `ipnet` v2.4.0 to
support using IpNet data structures directly in the custom resource
type bindings.

This change also adds an integration test to validate that the admission
controller behaves as expected.

Signed-off-by: Oliver Gould <ver@buoyant.io>
2022-03-16 14:03:21 -07:00
Oliver Gould 3f84c68f1a
Reorganize the policy controller (#7993)
In preparation for introducing new policy types, this change reorganizes
the policy controller to keep more of each indexing module private.

Signed-off-by: Oliver Gould <ver@buoyant.io>
2022-03-07 12:50:41 -08:00
Oliver Gould 0a7cafea67
Test the policy controller admission webhook (#8008)
The policy controller has an validating webhook for `Server` resources,
but this functionality is not really tested.

Before adding more policy resources that need validation, let's add an
integration test that exercises resource validation. The initial test is
pretty simplistic, but this is just setup.

These test also help expose two issues:

1. The change in 8760c5f--to solely use the index for validation--is
   problematic, especially in CI where quick updates can pass validation
   when they should not. This is fixed by going back to making API calls
   when validating `Server` resources.
2. Our pod selector overlap detection is overly simplistic. This change
   updates it to at least detect when a server selects _all_ pods.
   There's probably more we can do here in followup changes.

Tests are added in a new `policy-test` crate that only includes these
tests and the utiltities they need. This crate is excluded when running
unit tests and is only executed when it has a Kubernetes cluster it can
execute against. A temporary namespace is created before each test is
run and deleted as the test completes.

The policy controller's CI workflow is updated to build the core control
plane, run a k3d cluster, and exercise tests. This workflow has minimal
dependencies on the existing script/CI tooling so that the dependencies
are explicit and we can avoid some of the complexity of the existing
test infrastructure.

Signed-off-by: Oliver Gould <ver@buoyant.io>
2022-03-07 11:53:28 -08:00
Oliver Gould d4543cd86e
policy: Use a `kubert::Runtime` (#7961)
`kubert` provides a runtime utility that helps reduce boilerplate around
process lifecycle management, construction of admin and HTTPS servers,
etc.

The admission controller server preserves the certificate reloading
functionality introduced in 96131b5 and updates the utility to read both
RSA and PKSC8 keys to close #7963.

Signed-off-by: Oliver Gould <ver@buoyant.io>
2022-03-01 16:29:32 -08:00
Alejandro Pedraza a268ff11c9
Allow `Server` CRD to have empty `PodSelector` (#7925)
Fixes #7904

Allow the `Server` CRD to have the `PodSelector` entry be an empty object, by removing the `omitempty` tag from its go type definition and the `oneof` section in the CRD. No update to the CRD version is required, as this is BC change -- The CRD overriding was tested fine.

Also added some unit tests to confirm podSelector conditions are ANDed, and some minor refactorings in the `Selector` constructors.

Co-authored-by: Oliver Gould <ver@buoyant.io>
2022-02-23 13:45:34 +00:00
dependabot[bot] c3d6efe704
build(deps): bump kube from 0.68.0 to 0.69.0 (#7887)
Bumps [kube](https://github.com/kube-rs/kube-rs) from 0.68.0 to 0.69.0.
- [Release notes](https://github.com/kube-rs/kube-rs/releases)
- [Changelog](https://github.com/kube-rs/kube-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kube-rs/kube-rs/compare/0.68.0...0.69.0)

---
updated-dependencies:
- dependency-name: kube
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-16 10:17:29 +00:00
dependabot[bot] 4bbf4590ff
build(deps): bump kube from 0.67.0 to 0.68.0 (#7757)
Bumps [kube](https://github.com/kube-rs/kube-rs) from 0.67.0 to 0.68.0.
- [Release notes](https://github.com/kube-rs/kube-rs/releases)
- [Changelog](https://github.com/kube-rs/kube-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kube-rs/kube-rs/compare/0.67.0...0.68.0)

---
updated-dependencies:
- dependency-name: kube
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-02 07:06:32 -08:00
Oliver Gould 7187fa309b
Update kube to v0.67 (#7690)
The new release of `kube` updates `k8s-openapi` and removes use of
`dashmap`.

Closes #7606

Signed-off-by: Oliver Gould <ver@buoyant.io>
2022-01-25 11:50:21 -08:00
dependabot[bot] 7f00035906
build(deps): bump kube from 0.65.0 to 0.66.0 (#7624)
Bumps [kube](https://github.com/kube-rs/kube-rs) from 0.65.0 to 0.66.0.
- [Release notes](https://github.com/kube-rs/kube-rs/releases)
- [Changelog](https://github.com/kube-rs/kube-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kube-rs/kube-rs/compare/0.65.0...0.66.0)

---
updated-dependencies:
- dependency-name: kube
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-17 09:10:09 -08:00
dependabot[bot] 1c29507846
build(deps): bump kube from 0.64.0 to 0.65.0 (#7466)
* build(deps): bump kube from 0.64.0 to 0.65.0

Bumps [kube](https://github.com/kube-rs/kube-rs) from 0.64.0 to 0.65.0.
- [Release notes](https://github.com/kube-rs/kube-rs/releases)
- [Changelog](https://github.com/kube-rs/kube-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kube-rs/kube-rs/compare/0.64.0...0.65.0)

---
updated-dependencies:
- dependency-name: kube
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Address kube-rs/kube-rs#739: Remove 'api_version' and 'kind' from Server struct in tests

* Add a deny exception for tokio-rustls

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Alejandro Pedraza <alejandro@buoyant.io>
Co-authored-by: Oliver Gould <ver@buoyant.io>
2021-12-21 11:23:58 -05:00
dependabot[bot] b0a799eee7
build(deps): bump kube from 0.63.2 to 0.64.0 (#7299)
* build(deps): bump kube from 0.63.2 to 0.64.0

Bumps [kube](https://github.com/kube-rs/kube-rs) from 0.63.2 to 0.64.0.
- [Release notes](https://github.com/kube-rs/kube-rs/releases)
- [Changelog](https://github.com/kube-rs/kube-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kube-rs/kube-rs/compare/0.63.2...0.64.0)

---
updated-dependencies:
- dependency-name: kube
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Fixup deny.toml for deduped deps

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Oliver Gould <ver@buoyant.io>
2021-11-17 09:16:13 -05:00
Oliver Gould b2392b2b27
Update to kube v0.63 (#7170)
* Update to kube v0.63
2021-10-29 08:58:34 -05:00
Oliver Gould c88c0edd15
Update minimum-supported K8s version to v1.20 (#7172)
Kubernetes v1.19 is reaching its end-of-life date on 2021-10-28. In
anticipation of this, we should explicitly update our minimum supported
version to v1.20. This allows us keep our dependencies up-to-date and
ensures that we can actually test against our minimum supported version.

Fixes #7171

Co-authored-by: Alejandro Pedraza <alejandro@buoyant.io>
2021-10-28 13:19:10 -07:00
Oliver Gould 5cbad1fdb4
Update Rust to v1.56.0 (#7136)
Adopt the [2021 edition][ed2021].

[ed2021]: https://doc.rust-lang.org/edition-guide/rust-2021/index.html
2021-10-22 09:40:53 -07:00
dependabot[bot] 1b2d9dab24
build(deps): bump kube from 0.60.0 to 0.61.0 (#7074)
* build(deps): bump kube from 0.60.0 to 0.61.0

Bumps [kube](https://github.com/kube-rs/kube-rs) from 0.60.0 to 0.61.0.
- [Release notes](https://github.com/kube-rs/kube-rs/releases)
- [Changelog](https://github.com/kube-rs/kube-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kube-rs/kube-rs/compare/0.60.0...0.61.0)

---
updated-dependencies:
- dependency-name: kube
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* bump kube-runtime

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Oliver Gould <ver@buoyant.io>
2021-10-12 10:38:08 -07:00
Alex Leong 6d3f00357a
Update policy CRD version to v1beta1 (#6943)
Fixes #6827

We upgrade the Server and ServerAuthorization CRD versions from v1alpha1 to v1beta1.  This version update does not change the schema at all and the v1alpha1 versions will continue to be served for now.  We also update the CLI and control plane to use the v1beta1 versions.

Signed-off-by: Alex Leong <alex@buoyant.io>
2021-09-23 11:34:04 -07:00
Oliver Gould 21249dc1b6
policy: Do not create a default authorization for kubelet (#6833)
We initially implemented a mechanism to automatically authorize
unauthenticated traffic from each pod's Kubelet's IP. Our initial method
of determining a pod's Kubelet IP--using the first IP from its node's
pod CIDRs--is not a generally usable solution. In particular, CNIs
complicate matters (and EKS doesn't even set the podCIDRs field).

This change removes the policy controller's node watch and removes the
`default:kubelet` authorization. When using a restrictive default
policy, users will have to define `serverauthorization` resources that
permit kubelet traffic. It's probably possible to programatically
generate these authorizations (i.e. by inspecting pod probe
configurations); but this is out of scope for the core control plane
functionality.
2021-09-07 18:53:06 -07:00
dependabot[bot] e48bb02de8
build(deps): bump kube from 0.59.0 to 0.60.0 in /policy-controller (#6798)
* build(deps): bump kube from 0.59.0 to 0.60.0 in /policy-controller

Bumps [kube](https://github.com/kube-rs/kube-rs) from 0.59.0 to 0.60.0.
- [Release notes](https://github.com/kube-rs/kube-rs/releases)
- [Changelog](https://github.com/kube-rs/kube-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kube-rs/kube-rs/compare/0.59.0...0.60.0)

---
updated-dependencies:
- dependency-name: kube
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* bump kube-runtime also to `0.60` for compatiblity

Signed-off-by: Tarun Pothulapati <tarunpothulapati@outlook.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Tarun Pothulapati <tarunpothulapati@outlook.com>
2021-09-07 11:21:20 -05:00
Alex Leong 2851254966
Add admission controller to policy controller (#6696)
We add a validating admission controller to the policy controller which validates `Server` resources.  When a `Server` admission request is received, we look at all existing `Server` resources in the cluster and ensure that no other `Server` has an identical selector and port.

Signed-off-by: Alex Leong <alex@buoyant.io>

Co-authored-by: Oliver Gould <ver@buoyant.io>
2021-08-27 11:26:23 -07:00
Oliver Gould d539d120a9
policy-controller: Maintain liveness on watch restart (#6692)
The policy controller's readiness and liveness admin endpoint is tied to
watch state: the controller only advertises liveness when all watches
have received updates; and after a watch disconnects liveness fails
until a new update is received.

However, in some environments--especially when the API server ends the
stream before the client gracefully reconnects--the watch terminess so
that liveness is not advertises even though the client resumes watching
resources. Because the watch is resumed with a `resourceVersion`, no
updates are provided despite the watch being reestablished, and liveness
checks fail until the pod is terminated (or an update is received).

To fix this, we modify readiness advertisements to fail only until the
initial state is acquired from all watches. After this, the controller
serves cached state indefinitely.

While diagnosing this, logging changes were needed, especially for the
`Watch` type. Watches now properly maintain logging contexts and state
transitions are logged in more cases. The signature and logging context
of `Index::run` has been updated as well. Additionally, node lookup
debug logs have been elaborated to help confirm that 'pending' messages
are benign.
2021-08-18 08:32:28 -07:00
Oliver Gould 79a5849f7d
Update the policy-controller release build process (#6672)
We can't use the typical multiarch docker build with the proxy:
qemu-hosted arm64/arm builds take 45+ minutes before failing due to
missing tooling--specifically `protoc`. (While there is a `protoc`
binary available for arm64, there are no binaries available for 32-bit
arm hosts).

To fix this, this change updates the release process to cross-build the
policy-controller on an amd64 host to the target architecture. We
separate the policy-controller's dockerfiles as `amd64.dockerfile`,
`arm64.dockerfile`, and `arm.dockerfile`. Then, in CI we build and push
each of these images individually (in parallel, via a build matrix).
Once all of these are complete, we use the `docker manifest` CLI tools
to unify these images into a single multi-arch manifest.

This cross-building approach requires that we move from using
`native-tls` to `rustls`, as we cannot build against the platform-
appropriate native TLS libraries. The policy-controller is now feature-
flagged to use `rustls` by default, though it may be necessary to use
`native-tls` in local development, as `rustls` cannot validate TLS
connections that target IP addresses.

The policy-controller has also been updated to pull in `tracing-log` for
compatibility with crates that do not use `tracing` natively. This was
helpful while debugging connectivity issue with the Kubernetes cluster.

The `bin/docker-build-policy-controller` helper script now *only* builds
the amd64 variant of the policy controller. It fails when asked to build
multiarch images.
2021-08-13 09:28:07 -07:00
Oliver Gould 75774b91f6
policy-controller: Update kube, k8s-openapi dependencies (#6661)
kube v0.59 depends on k8s-openapi v0.13, which includes breaking
changes.

This change updates these dependencies and modifies our code to account
for these changes.

Furthermore, we now use the k8s-openapi feature `v1_16` so that we use
an API version that is compatible with Linkerd's minimum support
kubernetes version.

Closes #6657 #6658 #6659
2021-08-13 00:50:39 -07:00
Oliver Gould b98c86700f
Import the linkerd-policy-controller (#6485)
We've implemented a new controller--in Rust!--that implements discovery
APIs for inbound server policies. This change imports this code from
linkerd/polixy@25af9b5e.

This policy controller watches nodes, pods, and the recently-introduced
`policy.linkerd.io` CRD resources. It indexes these resources and serves
a gRPC API that will be used by proxies to configure the inbound proxy
for policy enforcement.

This change introduces a new policy-controller container image and adds a
container to the `Linkerd-destination` pod along with a `linkerd-policy` service
to be used by proxies.

This change adds a `policyController` object to the Helm `values.yaml` that
supports configuring the policy controller at runtime.

Proxies are not currently configured to use the policy controller at runtime. This
will change in an upcoming proxy release.
2021-08-11 12:56:12 -07:00