Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Branch for 2.15 docs #1740

Merged
merged 9 commits into from
Feb 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion linkerd.io/content/2.14/checks/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<script type="text/javascript">
window.onload = function() {
var hash = window.location.hash;
window.location.href = window.location.origin + "/2.14/tasks/troubleshooting/" + hash;
window.location.href = window.location.origin + "/2.15/tasks/troubleshooting/" + hash;
}
</script>
<title>Linkerd Check Redirection</title>
Expand Down
2 changes: 1 addition & 1 deletion linkerd.io/content/2.14/overview/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title = "Overview"
aliases = [
"/docs",
"/documentation",
"/2.14/",
"/2.15/",
"../docs/",
"/doc/network-performance/",
"/in-depth/network-performance/",
Expand Down
6 changes: 6 additions & 0 deletions linkerd.io/content/2.15/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
title: "Overview"
---
<!-- markdownlint-disable -->
<meta http-equiv="Refresh" content="0; url=overview/">
<!-- markdownlint-enable -->
18 changes: 18 additions & 0 deletions linkerd.io/content/2.15/checks/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="refresh" content="0; url=../tasks/troubleshooting/">
<script type="text/javascript">
window.onload = function() {
var hash = window.location.hash;
window.location.href = window.location.origin + "/2.14/tasks/troubleshooting/" + hash;
}
</script>
<title>Linkerd Check Redirection</title>
</head>
<body>
If you are not redirected automatically, follow this
<a href='../tasks/troubleshooting/'>link</a>.
</body>
</html>
14 changes: 14 additions & 0 deletions linkerd.io/content/2.15/features/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
+++
title = "Features"
weight = 3
[sitemap]
priority = 1.0
+++

Linkerd offers many features, outlined below. For our walkthroughs and guides,
please see the [Linkerd task docs]({{% ref "../tasks" %}}). For a reference,
see the [Linkerd reference docs]({{% ref "../reference" %}}).

## Linkerd's features

{{% sectiontoc "features" %}}
68 changes: 68 additions & 0 deletions linkerd.io/content/2.15/features/access-logging.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
+++
title = "HTTP Access Logging"
description = "Linkerd proxies can be configured to emit HTTP access logs."
aliases = [
"../access-logging/",
"../proxy-access-logging/",
"../http-access-logging/",
"../access-log",
]
+++

Linkerd proxies can be configured to generate an HTTP access log that records
all HTTP requests that transit the proxy.

The `config.linkerd.io/access-log` annotation is used to enable proxy HTTP
access logging. Adding this annotation to a namespace or workload configures the
proxy injector to set an environment variable in the proxy container that
configures access logging.

HTTP access logging is disabled by default because it has a performance impact,
compared to proxies without access logging enabled. Enabling access logging may
increase tail latency and CPU consumption under load. The severity of
this performance cost may vary depending on the traffic being proxied, and may
be acceptable in some environments.

{{< note >}}
The proxy's HTTP access log is distinct from proxy debug logging, which is
configured separately. See the documentation on [modifying the proxy log
level](../../tasks/modifying-proxy-log-level/) for details on configuring the
proxy's debug logging.
{{< /note >}}

## Access Log Formats

The value of the `config.linkerd.io/access-log` annotation determines the format
of HTTP access log entries, and can be either "apache" or "json".

Setting the `config.linkerd.io/access-log: "apache"` annotation configures the
proxy to emit HTTP access logs in the [Apache Common Log
Format](https://en.wikipedia.org/wiki/Common_Log_Format). For example:

```text
10.42.0.63:51160 traffic.booksapp.serviceaccount.identity.linkerd.cluster.local - [2022-08-23T20:28:20.071809491Z] "GET http://webapp:7000/ HTTP/2.0" 200
10.42.0.63:51160 traffic.booksapp.serviceaccount.identity.linkerd.cluster.local - [2022-08-23T20:28:20.187706137Z] "POST http://webapp:7000/authors HTTP/2.0" 303
10.42.0.63:51160 traffic.booksapp.serviceaccount.identity.linkerd.cluster.local - [2022-08-23T20:28:20.301798187Z] "GET http://webapp:7000/authors/104 HTTP/2.0" 200
10.42.0.63:51160 traffic.booksapp.serviceaccount.identity.linkerd.cluster.local - [2022-08-23T20:28:20.409177224Z] "POST http://webapp:7000/books HTTP/2.0" 303
10.42.0.1:43682 - - [2022-08-23T20:28:23.049685223Z] "GET /ping HTTP/1.1" 200
```

Setting the `config.linkerd.io/access-log: json` annotation configures the proxy
to emit access logs in a JSON format. For example:

```json
{"client.addr":"10.42.0.70:32996","client.id":"traffic.booksapp.serviceaccount.identity.linkerd.cluster.local","host":"webapp:7000","method":"GET","processing_ns":"39826","request_bytes":"","response_bytes":"19627","status":200,"timestamp":"2022-08-23T20:33:42.321746212Z","total_ns":"14441135","trace_id":"","uri":"http://webapp:7000/","user_agent":"Go-http-client/1.1","version":"HTTP/2.0"}
{"client.addr":"10.42.0.70:32996","client.id":"traffic.booksapp.serviceaccount.identity.linkerd.cluster.local","host":"webapp:7000","method":"POST","processing_ns":"30036","request_bytes":"33","response_bytes":"0","status":303,"timestamp":"2022-08-23T20:33:42.436964052Z","total_ns":"14122403","trace_id":"","uri":"http://webapp:7000/authors","user_agent":"Go-http-client/1.1","version":"HTTP/2.0"}
{"client.addr":"10.42.0.70:32996","client.id":"traffic.booksapp.serviceaccount.identity.linkerd.cluster.local","host":"webapp:7000","method":"GET","processing_ns":"38664","request_bytes":"","response_bytes":"2350","status":200,"timestamp":"2022-08-23T20:33:42.551768300Z","total_ns":"6998222","trace_id":"","uri":"http://webapp:7000/authors/105","user_agent":"Go-http-client/1.1","version":"HTTP/2.0"}
{"client.addr":"10.42.0.70:32996","client.id":"traffic.booksapp.serviceaccount.identity.linkerd.cluster.local","host":"webapp:7000","method":"POST","processing_ns":"42492","request_bytes":"46","response_bytes":"0","status":303,"timestamp":"2022-08-23T20:33:42.659401621Z","total_ns":"9274163","trace_id":"","uri":"http://webapp:7000/books","user_agent":"Go-http-client/1.1","version":"HTTP/2.0"}
{"client.addr":"10.42.0.1:56300","client.id":"-","host":"10.42.0.69:7000","method":"GET","processing_ns":"35848","request_bytes":"","response_bytes":"4","status":200,"timestamp":"2022-08-23T20:33:49.254262428Z","total_ns":"1416066","trace_id":"","uri":"/ping","user_agent":"kube-probe/1.24","version":"HTTP/1.1"}
```

## Consuming Access Logs

The HTTP access log is written to the proxy container's `stderr` stream, while
the proxy's standard debug logging is written to the proxy container's `stdout`
stream. Currently, the `kubectl logs` command will always output both the
container's `stdout` and `stderr` streams. However, [KEP
3289](https://github.com/kubernetes/enhancements/pull/3289) will add support for
separating a container's `stdout` or `stderr` in the `kubectl logs` command.
155 changes: 155 additions & 0 deletions linkerd.io/content/2.15/features/automatic-mtls.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
---
title: Automatic mTLS
description: Linkerd automatically enables mutual Transport Layer Security (TLS) for all communication between meshed applications.
weight: 4
aliases:
- ../automatic-tls
enableFAQSchema: true
faqs:
- question: What traffic can Linkerd automatically mTLS?
answer: Linkerd transparently applies mTLS to all TCP communication between
meshed pods. However, there are still ways in which you may still have
non-mTLS traffic in your system, including traffic to or from non-meshed
pods (e.g. Kubernetes healthchecks), and traffic on ports that were
marked as skip ports, which bypass the proxy entirely.

- question: How does Linkerd's mTLS implementation work?
answer: The Linkerd control plane contains a certificate authority (CA)
called "identity". This CA issues TLS certificates to each Linkerd data
plane proxy. Each certificate is bound to the Kubernetes ServiceAccount
of the containing pod. These TLS certificates expire after 24 hours and
are automatically rotated. The proxies use these certificates to encrypt
and authenticate TCP traffic to other proxies.

- question: What is mTLS?
answer: mTLS, or mutual TLS, is simply "regular TLS" with the extra
stipulation that the client is also authenticated. TLS guarantees
authenticity, but by default this only happens in one direction--the
client authenticates the server but the server doesn’t authenticate the
client. mTLS makes the authenticity symmetric.
---

By default, Linkerd automatically enables mutually-authenticated Transport
Layer Security (mTLS) for all TCP traffic between meshed pods. This means that
Linkerd adds authenticated, encrypted communication to your application with
no extra work on your part. (And because the Linkerd control plane also runs
on the data plane, this means that communication between Linkerd's control
plane components are also automatically secured via mTLS.)

See [Caveats and future work](#caveats-and-future-work) below for some details.

## What is mTLS?

mTLS, or mutual TLS, is simply "regular TLS" with the extra stipulation that
the client is also authenticated. TLS guarantees authenticity, but by default
this only happens in one direction--the client authenticates the server but the
server doesn’t authenticate the client. mTLS makes the authenticity symmetric.

mTLS is a large topic. For a broad overview of what mTLS is and how it works in
Kuberentes clusters, we suggest reading through [A Kubernetes engineer's guide
to mTLS](https://buoyant.io/mtls-guide/).

## Which traffic can Linkerd automatically mTLS?

Linkerd transparently applies mTLS to all TCP communication between meshed
pods. However, there are still ways in which you may still have non-mTLS
traffic in your system, including:

* Traffic to or from non-meshed pods (e.g. Kubernetes healthchecks)
* Traffic on ports that were marked as [skip ports](../protocol-detection/),
which bypass the proxy entirely.

You can [verify which traffic is mTLS'd](../../tasks/validating-your-traffic/)
in a variety of ways. External systems such as [Buoyant
Cloud](https://buoyant.io/cloud) can also automatically generate reports of TLS
traffic patterns on your cluster.

## Operational concerns

Linkerd's mTLS requires some preparation for production use, especially for
long-lived clusters or clusters that expect to have cross-cluster traffic.

The trust anchor generated by the default `linkerd install` CLI command expires
after 365 days. After that, it must be [manually
rotated](../../tasks/manually-rotating-control-plane-tls-credentials/)—a
non-trivial task. Alternatively, you can [provide the trust anchor
yourself](../../tasks/generate-certificates/) and control the expiration date,
e.g. setting it to 10 years rather than one year.

Kubernetes clusters that make use of Linkerd's [multi-cluster
communication](../multicluster/) must share a trust anchor. Thus, the default
`linkerd install` setup will not work for this situation and you must provide
an explicit trust anchor.

Similarly, the default cluster issuer certificate and key expire after a year.
These must be [rotated before they
expire](../../tasks/manually-rotating-control-plane-tls-credentials/).
Alternatively, you can [set up automatic rotation with
`cert-manager`](../../tasks/automatically-rotating-control-plane-tls-credentials/).

External systems such as [Buoyant Cloud](https://buoyant.io/cloud) can be used
to monitor cluster credentials and to send reminders if they are close to
expiration.

## How does Linkerd's mTLS implementation work?

The [Linkerd control plane](../../reference/architecture/) contains a certificate
authority (CA) called `identity`. This CA issues TLS certificates to each
Linkerd data plane proxy. Each certificate is bound to the [Kubernetes
ServiceAccount](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/)
identity of the containing pod. These TLS certificates expire after 24 hours
and are automatically rotated. The proxies use these certificates to encrypt
and authenticate TCP traffic to other proxies.

On the control plane side, Linkerd maintains a set of credentials in the
cluster: a trust anchor, and an issuer certificate and private key. These
credentials can be generated by Linkerd during install time, or optionally
provided by an external source, e.g. [Vault](https://vaultproject.io) or
[cert-manager](https://github.com/jetstack/cert-manager). The issuer
certificate and private key are stored in a [Kubernetes
Secret](https://kubernetes.io/docs/concepts/configuration/secret/); this Secret
is placed in the `linkerd` namespace and can only be read by the service
account used by the [Linkerd control plane](../../reference/architecture/)'s
`identity` component.

On the data plane side, each proxy is passed the trust anchor in an environment
variable. At startup, the proxy generates a private key, stored in a [tmpfs
emptyDir](https://kubernetes.io/docs/concepts/storage/volumes/#emptydir) which
stays in memory and never leaves the pod. The proxy connects to the control
plane's `identity` component, validating the connection to `identity` with the
trust anchor, and issues a [certificate signing request
(CSR)](https://en.wikipedia.org/wiki/Certificate_signing_request). The CSR
contains an initial certificate with identity set to the pod's [Kubernetes
ServiceAccount](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/),
and the actual service account token, so that `identity` can validate that the
CSR is valid. After validation, the signed trust bundle is returned to the
proxy, which can use it as both a client and server certificate. These
certificates are scoped to 24 hours and dynamically refreshed using the same
mechanism.

Finally, when a proxy receives an outbound connection from the application
container within its pod, it looks up that destination with the Linkerd control
plane. If it's in the Kubernetes cluster, the control plane provides the proxy
with the destination's endpoint addresses, along with metadata including an
identity name. When the proxy connects to the destination, it initiates a TLS
handshake and verifies that that the destination proxy's certificate is signed
by the trust anchor and contains the expected identity.

## TLS protocol parameters

Linkerd currently uses the following TLS protocol parameters for mTLS
connections, although they may change in future versions:

* TLS version 1.3
* Cipher suite `TLS_CHACHA20_POLY1305_SHA256` as specified in [RFC
8446](https://www.rfc-editor.org/rfc/rfc8446#section-9.1).

## Caveats and future work

* Linkerd does not *require* mTLS unless [authorization policies](../server-policy/)
are configured.

* Ideally, the ServiceAccount token that Linkerd uses would not be shared with
other potential uses of that token. In future Kubernetes releases, Kubernetes
will support audience/time-bound ServiceAccount tokens, and Linkerd will use
those instead.
Loading
Loading