├── LICENSE ├── README.md ├── extensions.md ├── jaeger-issuer.yaml ├── linkerd-cert-issuer.yaml └── viz-issuer.yaml /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Kelly Birr 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Kelly's Linkerd 2 Guide 2 | A simple guide with step-by-step commands for setting up [Linkerd](https://linkerd.io) for real use in long lived and/or production Kubernetes clusters. 3 | 4 | While I love [Helm](https://helm.sh/) as much as the next guy, this guide is done entirely without it. It's important to know that Buoyant does recommend the use of Helm for production installation as it's more repeatable. 5 | 6 | This is not intended to be an in-depth discussion, or advanced topics guide for Linkerd or Kubernetes. I've got just enough setup guide to get it up and running. Please read [Buoyant’s Linkerd Production Runbook](https://buoyant.io/linkerd-runbook/) for yourself to learn a lot more detail. 7 | 8 | *Contributions welcome: If you have suggestions on how this can be improved, I welcome any and all feedback. I also have a million things on my plate, so please don't be offended if I don't reply immediately.* 9 | 10 | ### Relevancy 11 | This guide is based on Linkerd 2.12.3. Newer or older versions of Linkerd may have differences. Please always double-check this against the [Linkerd Docs](https://linkerd.io/docs/) before starting. 12 | 13 | ### Disclaimer 14 | I am nowhere near the foremost expert on Linkerd. I've just been using it for quite a while and have hit a few pit-falls from configurations that were not exactly production-ready. The [Linkerd Slack](http://slack.linkerd.io/?_gl=1*1gvbgbs*_ga*ODEyOTQyMDgwLjE2MzQyNTc0NjI.*_ga_TV358ZPK6D*MTY0NDQyMTUwNS43LjAuMTY0NDQyMTUwNS4w#_ga=2.153716476.550972073.1644365071-812942080.1634257462) has much smarter people than me. I highly recommend you join and ask questions there. 15 | 16 | 17 | ## Setup Instructions 18 | I'm executing all of these commands from the root folder in this repository, on Ubuntu 18.04 ([WSL](https://docs.microsoft.com/en-us/windows/wsl/)). This guide should work as-is on any other OS or distro. 19 | 20 | I'm doing this on [AKS](https://azure.microsoft.com/en-us/services/kubernetes-service/), but there is nothing Azure specific. This should work on any cloud or even bare-metal Kubernetes cluster. 21 | 22 | ### Prerequisites 23 | * You need the Linkerd CLI already installed on your workstation. See Buoyant's [Getting Started](https://linkerd.io/2.11/getting-started/#step-1-install-the-cli) guide for installation instructions. 24 | * You need to have [cert-manager](https://cert-manager.io/), and its CRDs, already installed and working on your cluster. I may add that as a sub-guide here later but for now I'll just direct you to their [Installation Instructions](https://cert-manager.io/docs/installation/). 25 | 26 | ### 1) Generate a new, long-lived root certificate 27 | I'm doing this with [smallstep cli](https://smallstep.com/). If you don't already have it installed, here are their [Install Instructions](https://smallstep.com/docs/step-cli/installation). It is also possible to do this with [OpenSSL](https://www.openssl.org/), but I'm not going to covert that here. 28 | 29 | Let's generate a 20-year root certificate, so when it needs to be rotated it won't be our problem. 30 | 31 | ```bash 32 | step certificate create root.linkerd.cluster.local ca.crt ca.key \ 33 | --profile root-ca --no-password --insecure --not-after 175200h 34 | ``` 35 | 36 | ### 2) Create the `linkerd` namespace. 37 | You'll need this to exist for the next few commands to work. 38 | 39 | ```bash 40 | kubectl create namespace linkerd 41 | ``` 42 | 43 | ### 3) Load your new certificate as a secret. 44 | This will be used by Linkerd as the trust anchor for the control plane, mTLS and by cert-manager to issue and rotate shorter lived certificates. 45 | 46 | ```bash 47 | kubectl create secret tls linkerd-trust-anchor --cert=ca.crt --key=ca.key --namespace=linkerd 48 | ``` 49 | 50 | ### 4) Load the included YAML, for cert-manager to create managed certificates 51 | The "[linkerd-cert-issuer.yaml](linkerd-cert-issuer.yaml)" includes the issuers for the trust-ancher and webhooks as well as manager certificate definitions for `linkerd-identity-issuer`, `linkerd-policy-validator`, `linkerd-proxy-injector` and `linkerd-sp-validator`. 52 | 53 | I've chosen a certificate lifetime of 180-days with a renew-before of 60-days. Linkerd's guide actually recommend a much shorter lifetime. In the real-world I've had older versions of cert-manger "miss" certificate renewals for a few days to weeks. This gives it more cushion against expiration. 54 | 55 | This longer lifetime also has the benefit of `$ linkerd check` telling you all-is-good if your certificates are rotating properly. Any lifetime of less than 60 days will cause the built-in check to constantly warn you that your certificates are close to expiration. 56 | 57 | ```bash 58 | kubectl apply -f linkerd-cert-issuer.yaml 59 | ``` 60 | 61 | ### 5) Verify your certificates are created 62 | This step can be skipped, if you like to live on the edge. If cert-manager is working as expected, this command will show a listing of all the certificates mentioned above. 63 | 64 | ```bash 65 | kubectl get secret -n linkerd 66 | ``` 67 | 68 | The output should look something like this: 69 | 70 | ``` 71 | NAME TYPE DATA AGE 72 | default-token-f8v2m kubernetes.io/service-account-token 3 10m 73 | linkerd-identity-issuer kubernetes.io/tls 3 2m 74 | linkerd-policy-validator-k8s-tls kubernetes.io/tls 3 2m 75 | linkerd-proxy-injector-k8s-tls kubernetes.io/tls 3 2m 76 | linkerd-sp-validator-k8s-tls kubernetes.io/tls 3 2m 77 | linkerd-trust-anchor kubernetes.io/tls 2 2m 78 | ``` 79 | 80 | ### 6) Ensure you have correctly labeled the `kube-system` namespace 81 | 82 | This is really important for HA installation of Linkerd, which we're going to be doing. 83 | 84 | I'll let Buoyant explain the necessity of this in their page on [High Availability](https://linkerd.io/2.11/features/ha/#exclude-the-kube-system-namespace). 85 | 86 | ```bash 87 | kubectl label namespace kube-system config.linkerd.io/admission-webhooks=disabled 88 | ``` 89 | 90 | ### 7) Install Linkerd 91 | 92 | We're using the Linkerd CLI installation method. The arguments passed configure [High Availability](https://linkerd.io/2.11/features/ha/#exclude-the-kube-system-namespace) mode as well as informing Linkerd that the issuer and web-hook certificates will be managed by cert-manager. 93 | 94 | *Update for 2.12.x: Added step for `--crds` to create linkerd CRDs as first-step of install* 95 | 96 | ```bash 97 | linkerd install --crds | kubectl apply -f - 98 | ``` 99 | 100 | *Update for 2.11.2: Added `--set proxyInit.runAsRoot=false` to run init containers as non-root (best practice)* 101 | 102 | ```bash 103 | linkerd install --ha \ 104 | --identity-external-issuer \ 105 | --identity-trust-anchors-file ca.crt \ 106 | --set policyValidator.externalSecret=true \ 107 | --set-file policyValidator.caBundle=ca.crt \ 108 | --set proxyInjector.externalSecret=true \ 109 | --set-file proxyInjector.caBundle=ca.crt \ 110 | --set profileValidator.externalSecret=true \ 111 | --set-file profileValidator.caBundle=ca.crt \ 112 | --set proxyInit.runAsRoot=false \ 113 | | kubectl apply -f - 114 | ``` 115 | 116 | *NOTE: You are going to get a warning that the `linkerd` namespace already exists outside of `kubectl apply`. This is expected and can be safely ignored.* 117 | 118 | ### 8) Verify your Linkerd installation 119 | As before, this step can be skipped, if you like to live on the edge. We're going use the built-in check feature of Linkerd CLI. 120 | 121 | *Give the previous command 1-2 minutes, to install and start the Linkerd workloads, before trying to verify.* 122 | 123 | ```bash 124 | linkerd check 125 | ``` 126 | 127 | If Linkerd is working as expected, or if there are problems, this tool will tell you. 128 | 129 | ### Next Steps 130 | 131 | This is all that is required to get a production ready Linkerd install up an running. The existing online [Linkerd Docs](https://linkerd.io/docs/) cover all the details of configuring your other cluster workloads, including ingress, to actually work with your newly installed service-mesh. I don't feel the need to repeat any of that here. 132 | 133 | ### Linkerd Viz and Jaeger 134 | 135 | If you're interested in using the Viz and Jaeger extensions with this configuration, check out "[extensions.md](extensions.md)" in this repository. 136 | 137 | 138 | -------------------------------------------------------------------------------- /extensions.md: -------------------------------------------------------------------------------- 1 | # Linkerd 2 Exensions 2 | This guide covers a complimentary install of the Viz and/or Jaeger extensions in long lived and/or production Kubernetes clusters. Everything in this guide assumes you've already installed Linkerd using the process in the [README](README.md) and still have the CA certificate you generated. 3 | 4 | ## VIZ 5 | 6 | ### 1) Create the `linkerd-viz` namespace. 7 | You'll need this to exist for the next few commands to work. 8 | 9 | ```bash 10 | kubectl create namespace linkerd-viz 11 | ``` 12 | 13 | ### 2) Load your CA certificate as a secret. 14 | This will be used by Linkerd and cert-manager to issue and rotate shorter lived web-hook certificates. 15 | 16 | ```bash 17 | kubectl create secret tls webhook-issuer-tls --cert=ca.crt --key=ca.key --namespace=linkerd-viz 18 | ``` 19 | 20 | ### 3) Load the included YAML, for cert-manager to create managed certificates 21 | The "[viz-issuer.yaml](viz-issuer.yaml)" includes the issuer for web-hooks as well as managed certificate definitions for `tap`, and `linkerd-tap-injector`. 22 | 23 | ```bash 24 | kubectl apply -f viz-issuer.yaml 25 | ``` 26 | 27 | ### 4) Verify your certificates are created 28 | This step can be skipped, if you like to live on the edge. If cert-manager is working as expected, this command will show a listing of the certificates mentioned above. 29 | 30 | ```bash 31 | kubectl get secret -n linkerd-viz 32 | ``` 33 | 34 | The output should look something like this: 35 | 36 | ``` 37 | NAME TYPE DATA AGE 38 | default-token-ngc9f kubernetes.io/service-account-token 3 3m 39 | tap-injector-k8s-tls kubernetes.io/tls 3 1m 40 | tap-k8s-tls kubernetes.io/tls 3 1m 41 | webhook-issuer-tls kubernetes.io/tls 2 1m 42 | ``` 43 | 44 | ### 5) Install Linkerd Viz Extension 45 | 46 | We're using the Linkerd CLI installation method. 47 | 48 | ```bash 49 | linkerd viz install \ 50 | --set tap.externalSecret=true \ 51 | --set-file tap.caBundle=ca.crt \ 52 | --set tapInjector.externalSecret=true \ 53 | --set-file tapInjector.caBundle=ca.crt \ 54 | | kubectl apply -f - 55 | ``` 56 | 57 | *NOTE: You are going to get a warning that the `linkerd-viz` namespace already exists outside of `kubectl apply`. This is expected and can be safely ignored.* 58 | 59 | ### 8) Verify your installation 60 | As before, this step can be skipped, if you like to live on the edge. We're going use the built-in check feature of Linkerd CLI. 61 | 62 | *Give the previous command 1-2 minutes, to install and start the Linkerd-Viz workloads, before trying to verify.* 63 | 64 | ```bash 65 | linkerd check 66 | ``` 67 | 68 | If Viz is working as expected, or if there are problems, this tool will tell you. 69 | 70 | 71 | ## JAEGER 72 | The process is virtually identical to installing Viz (above). 73 | 74 | ### 1) Create the `linkerd-jaeger` namespace. 75 | 76 | ```bash 77 | kubectl create namespace linkerd-jaeger 78 | ``` 79 | 80 | ### 2) Load your CA certificate as a secret. 81 | 82 | ```bash 83 | kubectl create secret tls webhook-issuer-tls --cert=ca.crt --key=ca.key --namespace=linkerd-jaeger 84 | ``` 85 | 86 | ### 3) Load the included YAML, for cert-manager to create managed certificates 87 | The "[jaeger-issuer.yaml](jaeger-issuer.yaml)" includes the issuer for web-hooks and managed certificate definition for `jaeger-injector`. 88 | 89 | ```bash 90 | kubectl apply -f jaeger-issuer.yaml 91 | ``` 92 | 93 | ### 4) Verify your certificates are created 94 | 95 | ```bash 96 | kubectl get secret -n linkerd-jaeger 97 | ``` 98 | 99 | ### 5) Install Linkerd Jaeger Extension 100 | 101 | ```bash 102 | linkerd jaeger install \ 103 | --set webhook.externalSecret=true \ 104 | --set-file webhook.caBundle=ca.crt \ 105 | | kubectl apply -f - 106 | ``` 107 | 108 | *NOTE: You are going to get a warning that the `linkerd-jaeger` namespace already exists outside of `kubectl apply`. This is expected and can be safely ignored.* 109 | 110 | ### 6) Verify your installation 111 | 112 | *Give the previous command 1-2 minutes, to install and start the Linkerd-Jaeger workloads, before trying to verify.* 113 | 114 | ```bash 115 | linkerd check 116 | ``` 117 | 118 | -------------------------------------------------------------------------------- /jaeger-issuer.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cert-manager.io/v1 2 | kind: Issuer 3 | metadata: 4 | name: webhook-issuer 5 | namespace: linkerd-jaeger 6 | spec: 7 | ca: 8 | secretName: webhook-issuer-tls 9 | --- 10 | apiVersion: cert-manager.io/v1 11 | kind: Certificate 12 | metadata: 13 | name: jaeger-injector 14 | namespace: linkerd-jaeger 15 | spec: 16 | secretName: jaeger-injector-k8s-tls 17 | duration: 4320h 18 | renewBefore: 1440h 19 | issuerRef: 20 | name: webhook-issuer 21 | kind: Issuer 22 | commonName: jaeger-injector.linkerd.svc 23 | dnsNames: 24 | - jaeger-injector.linkerd.svc 25 | isCA: false 26 | privateKey: 27 | algorithm: ECDSA 28 | usages: 29 | - server auth 30 | --- 31 | -------------------------------------------------------------------------------- /linkerd-cert-issuer.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cert-manager.io/v1 2 | kind: Issuer 3 | metadata: 4 | name: linkerd-trust-anchor 5 | namespace: linkerd 6 | spec: 7 | ca: 8 | secretName: linkerd-trust-anchor 9 | --- 10 | apiVersion: cert-manager.io/v1 11 | kind: Issuer 12 | metadata: 13 | name: webhook-issuer 14 | namespace: linkerd 15 | spec: 16 | ca: 17 | secretName: linkerd-trust-anchor 18 | --- 19 | apiVersion: cert-manager.io/v1 20 | kind: Certificate 21 | metadata: 22 | name: linkerd-identity-issuer 23 | namespace: linkerd 24 | spec: 25 | secretName: linkerd-identity-issuer 26 | duration: 4320h 27 | renewBefore: 1440h 28 | issuerRef: 29 | name: linkerd-trust-anchor 30 | kind: Issuer 31 | commonName: identity.linkerd.cluster.local 32 | dnsNames: 33 | - identity.linkerd.cluster.local 34 | isCA: true 35 | privateKey: 36 | algorithm: ECDSA 37 | usages: 38 | - cert sign 39 | - crl sign 40 | - server auth 41 | - client auth 42 | --- 43 | apiVersion: cert-manager.io/v1 44 | kind: Certificate 45 | metadata: 46 | name: linkerd-policy-validator 47 | namespace: linkerd 48 | spec: 49 | secretName: linkerd-policy-validator-k8s-tls 50 | duration: 4320h 51 | renewBefore: 1440h 52 | issuerRef: 53 | name: webhook-issuer 54 | kind: Issuer 55 | commonName: linkerd-policy-validator.linkerd.svc 56 | dnsNames: 57 | - linkerd-policy-validator.linkerd.svc 58 | isCA: false 59 | privateKey: 60 | algorithm: ECDSA 61 | encoding: PKCS8 62 | usages: 63 | - server auth 64 | --- 65 | apiVersion: cert-manager.io/v1 66 | kind: Certificate 67 | metadata: 68 | name: linkerd-proxy-injector 69 | namespace: linkerd 70 | spec: 71 | secretName: linkerd-proxy-injector-k8s-tls 72 | duration: 4320h 73 | renewBefore: 1440h 74 | issuerRef: 75 | name: webhook-issuer 76 | kind: Issuer 77 | commonName: linkerd-proxy-injector.linkerd.svc 78 | dnsNames: 79 | - linkerd-proxy-injector.linkerd.svc 80 | isCA: false 81 | privateKey: 82 | algorithm: ECDSA 83 | usages: 84 | - server auth 85 | --- 86 | apiVersion: cert-manager.io/v1 87 | kind: Certificate 88 | metadata: 89 | name: linkerd-sp-validator 90 | namespace: linkerd 91 | spec: 92 | secretName: linkerd-sp-validator-k8s-tls 93 | duration: 4320h 94 | renewBefore: 1440h 95 | issuerRef: 96 | name: webhook-issuer 97 | kind: Issuer 98 | commonName: linkerd-sp-validator.linkerd.svc 99 | dnsNames: 100 | - linkerd-sp-validator.linkerd.svc 101 | isCA: false 102 | privateKey: 103 | algorithm: ECDSA 104 | usages: 105 | - server auth 106 | --- -------------------------------------------------------------------------------- /viz-issuer.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cert-manager.io/v1 2 | kind: Issuer 3 | metadata: 4 | name: webhook-issuer 5 | namespace: linkerd-viz 6 | spec: 7 | ca: 8 | secretName: webhook-issuer-tls 9 | --- 10 | apiVersion: cert-manager.io/v1 11 | kind: Certificate 12 | metadata: 13 | name: tap 14 | namespace: linkerd-viz 15 | spec: 16 | secretName: tap-k8s-tls 17 | duration: 4320h 18 | renewBefore: 1440h 19 | issuerRef: 20 | name: webhook-issuer 21 | kind: Issuer 22 | commonName: tap.linkerd-viz.svc 23 | dnsNames: 24 | - tap.linkerd-viz.svc 25 | isCA: false 26 | privateKey: 27 | algorithm: ECDSA 28 | usages: 29 | - server auth 30 | --- 31 | apiVersion: cert-manager.io/v1 32 | kind: Certificate 33 | metadata: 34 | name: linkerd-tap-injector 35 | namespace: linkerd-viz 36 | spec: 37 | secretName: tap-injector-k8s-tls 38 | duration: 4320h 39 | renewBefore: 1440h 40 | issuerRef: 41 | name: webhook-issuer 42 | kind: Issuer 43 | commonName: tap-injector.linkerd-viz.svc 44 | dnsNames: 45 | - tap-injector.linkerd-viz.svc 46 | isCA: false 47 | privateKey: 48 | algorithm: ECDSA 49 | usages: 50 | - server auth 51 | --- --------------------------------------------------------------------------------