Skip to content

Commit

Permalink
Merge pull request #48 from ricsanfre/feature/linkerd
Browse files Browse the repository at this point in the history
Feature/linkerd
  • Loading branch information
ricsanfre committed Apr 5, 2022
2 parents a459b60 + e6238f8 commit c350a5e
Show file tree
Hide file tree
Showing 86 changed files with 42,021 additions and 4,139 deletions.
3 changes: 3 additions & 0 deletions docs/_data/docs.yml
Expand Up @@ -29,6 +29,9 @@
- title: Cluster Backup
docs:
- backup
- title: Service Mesh
docs:
- service-mesh
- title: Reference Docs
docs:
- k8s-networking
Expand Down
24 changes: 14 additions & 10 deletions docs/_docs/ansible-instructions.md
Expand Up @@ -2,7 +2,7 @@
title: Quick Start Instructions
permalink: /docs/ansible/
description: Quick Start guide to deploy our Raspberry Pi Kuberentes Cluster using cloud-init and ansible playbooks.
last_modified_at: "25-02-2022"
last_modified_at: "05-04-2022"
---

This are the instructions to quickly deploy Kuberentes Pi-cluster using cloud-init and Ansible Playbooks
Expand Down Expand Up @@ -217,7 +217,7 @@ ansible-playbook k3s_install.yml

### K3S basic services deployment

To deploy and configure basic services (metallb, traefik, certmanager, longhorn, EFK, Prometheus, Velero) run the playbook:
To deploy and configure basic services (metallb, traefik, certmanager, linkerd, longhorn, EFK, Prometheus, Velero) run the playbook:

```shell
ansible-playbook k3s_deploy.yml
Expand All @@ -229,15 +229,19 @@ Different ansible tags can be used to select the componentes to deploy:
ansible-playbook k3s_deploy.yml --tags <ansible_tag>
```

| Ansible Tag | Component to configure/deploy |
The following table shows the different components and their dependencies.

| Ansible Tag | Component to configure/deploy | Dependencies
|---|---|
| `metallb` | Metal LB |
| `traefik` | Traefik |
| `certmanager` | Cert-manager |
| `longhorn` | Longhorn |
| `logging` | EFK Stack |
| `monitoring` | Prometheus Stack |
| `backup` | Velero |
| `metallb` | Metal LB | - |
| `certmanager` | Cert-manager | - |
| `linkerd` | Linkerd | Cert-manager |
| `traefik` | Traefik | Linkerd |
| `longhorn` | Longhorn | Linkerd |
| `monitoring` | Prometheus Stack | Longhorn, Linkerd |
| `linkerd-viz` | Linkerd Viz | Prometheus Stack, Linkerd |
| `logging` | EFK Stack | Longhorn, Linkerd |
| `backup` | Velero | Linkerd |
{: .table }

### K3s Cluster reset
Expand Down
184 changes: 145 additions & 39 deletions docs/_docs/certmanager.md
Expand Up @@ -2,19 +2,112 @@
title: SSL Certificates (Cert-Manager)
permalink: /docs/certmanager/
description: How to deploy a centralized SSL certification management solution based on Cert-manager in our Raspberry Pi Kuberentes cluster.
last_modified_at: "25-02-2022"
last_modified_at: "08-03-2022"
---

In the Kubernetes cluster, [Cert-Manager](https://cert-manager.io/docs/) can be used to automate the certificate management tasks (issue certificate request, renewals, etc.). Cert-manager adds certificates and certificate issuers as resource types in Kubernetes clusters, and simplifies the process of obtaining, renewing and using those certificates.

It can issue certificates from a variety of supported sources, including support for auto-signed certificates or use [Let's Encrypt](https://letsencrypt.org/) service to obtain validated SSL certificates. It will ensure certificates are valid and up to date, and attempt to renew certificates at a configured time before expiry.
It can issue certificates from a variety of supported sources, including support for auto-signed certificates or use [Let's Encrypt](https://letsencrypt.org/) service to obtain validated SSL certificates. It will ensure certificates are valid and up to date, and attempt to renew certificates at a configured time before expiry. It also keep up to date the associated Kuberentes Secrets storing key pairs used by Ingress resources when securing the incoming communications.

{{site.data.alerts.note}}
CertManager integration with Let's Encryp has not been configured since my DNS provider does not suppport yet the API for automating DNS challenges. See open issue [#16](https://github.com/ricsanfre/pi-cluster/issues/16).
![picluster-certmanager](/assets/img/cert-manager.png)

## Cert-Manager certificates issuers

In cert-manager different kind of certificate issuer can be configured to generate signed SSL certificates

### Self-signed Issuer

The SelfSigned issuer doesn’t represent a certificate authority as such, but instead denotes that certificates will “sign themselves” using a given private key. In other words, the private key of the certificate will be used to sign the certificate itself.

This Issuer type is useful for bootstrapping a root certificate (CA) for a custom PKI (Public Key Infrastructure).

We will use this Issuer for bootstrapping our custom CA.

### CA Issuer

The CA issuer represents a Certificate Authority whereby its certificate and private key are stored inside the cluster as a Kubernetes Secret, and will be used to sign incoming certificate requests. This internal CA certificate can then be used to trust resulting signed certificates.

This issuer type is typically used in a private Public Key Infrastructure (PKI) setup to secure your infrastructure components to establish mTLS or otherwise provide a means to issue certificates where you also own the private key. Signed certificates with this custom CA will not be trusted by clients, such a web browser, by default.

### ACME issuers (Lets Encrypt)

The ACME Issuer type represents a single account registered with the Automated Certificate Management Environment (ACME) Certificate Authority server. See section [Let's Encrypt certificates](#lets-encrypt-certificates).


{{site.data.alerts.important}}

CertManager has been configured to have in the cluster a private PKI (Public Key Infrastructure) using a self-signed CA to issue auto-signed certificates.

CertManager integration with Let's Encrypt has not been configured since my DNS provider does not suppport yet the API for automating DNS challenges. See open issue [#16](https://github.com/ricsanfre/pi-cluster/issues/16).

CertManager has been configured to issue selfsigned certificates.
{{site.data.alerts.end}}


## Cert Manager Usage

Cert-manager add a set of Kubernetes custom resource (CRD):

- `Issuer` and `ClusterIssuer`: resources that represent certificate authorities (CA) able to genertate signed certificates in response to certificate signed request (CSR). `Issuer` is a namespaced resource, able to issue certificates only for the namespace where the issuer is located. `ClusterIssuer` is able to issue certificates across all namespaces.

- `Certificate`, resources that represent a human readable definition of a certificate request that need to be generated and keep up to date by an issuer.

In order to generate new SSL certificates a `Certificate` resource can be created.

Once the Certificate resource is created, Cert-manager signed the certificate issued by the specified issuer and stored it in a `kubernetes.io/tls Secret` resource, which is the one used to secure Ingress resource. See kuberentes [Ingress TLS documentation](https://kubernetes.io/docs/concepts/services-networking/ingress/#tls)

```yml
apiVersion: v1
kind: Secret
metadata:
name: testsecret-tls
namespace: default
data:
tls.crt: base64 encoded cert
tls.key: base64 encoded key
type: kubernetes.io/tls
```

See further details in the [cert-manager documentation](https://cert-manager.io/docs/usage/certificate/)


### Securing Ingress resources

`Ingress` resources can be configured using annotations, so cert-manager can automatically generate the needed self-signed certificates to secure the incoming communications using HTTPS/TLS

As stated in the [documentation](https://cert-manager.io/docs/usage/ingress/), cert-manager can be used to automatically request TLS signed certificates to secure any `Ingress` resources. By means of annotations cert-manager can generate automatically the needed certificates and store them in corresponding secrets used by Ingress resource

Ingress annotation `cert-manager.io/cluster-issuer` indicates the `ClusterIssuer` to be used.

Ingress rule example:

```yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
# add an annotation indicating the issuer to use.
cert-manager.io/cluster-issuer: nameOfClusterIssuer
name: myIngress
namespace: myIngress
spec:
rules:
- host: example.com
http:
paths:
- pathType: Prefix
path: /
backend:
service:
name: myservice
port:
number: 80
tls: # < placing a host in the TLS config will determine what ends up in the cert's subjectAltNames
- hosts:
- example.com
secretName: myingress-cert # < cert-manager will store the created certificate in this secret.
```


## Cert Manager Installation

Installation using `Helm` (Release 3):
Expand All @@ -37,18 +130,25 @@ Installation using `Helm` (Release 3):
- Step 3: Install Cert-Manager

```shell
helm install cert-manager jetstack/cert-manager --namespace certmanager-system --version v1.5.3 --set installCRDs=true
helm install cert-manager jetstack/cert-manager --namespace certmanager-system --set installCRDs=true
```
- Step 4: Confirm that the deployment succeeded, run:

```shell
kubectl -n certmanager-system get pod
```

## Self-signed Certificates
## Cert-Manager Configuration

A PKI (Public Key Infrastructure) with a custom CA will be created in the cluster and all certificates will be auto-signed by this CA. For doing so, A CA `ClusterIssuer` resource need to be created.

Root CA certificate is needed for generated this CA Issuer. A selfsigned `ClusterIssuer` resource will be used to generate that root CA certificate (self-signed root CA).

- Step 1: Create `ClusterIssuer`
In order to obtain certificates from cert-manager, we need to create an issuer to act as a certificate authority. We have the option of creating an `Issuer` which is a namespaced resource, or a `ClusterIssuer` which is a global resource. We’ll create a self-signed `ClusterIssuer` using the following definition:
- Step 1: Create selfsigned `ClusterIssuer`

First step is to create the self-signed issuer for being able to selfsign a custom root certificate of the PKI (CA certificate).

In order to obtain certificates from cert-manager, we need to create an issuer to act as a certificate authority. We have the option of creating an `Issuer` which is a namespaced resource, or a `ClusterIssuer` which is a global resource. We’ll create a self-signed `ClusterIssuer` using the following definition:

```yml
apiVersion: cert-manager.io/v1
Expand All @@ -59,44 +159,50 @@ In order to obtain certificates from cert-manager, we need to create an issuer t
selfSigned: {}
```

- Step 2: Configure Ingress rule to automatically use cert-manager to issue self-signed certificates

As stated in the [documentation](https://cert-manager.io/docs/usage/ingress/), cert-manager can be used to automatically request TLS signed certificates to secure any `Ingress` resources. By means of annotations cert-manager can generate automatically the needed certificates
- Step 2: Bootstrapping CA Issuers

Ingress annotation `cert-manager.io/cluster-issuer` indicates the `ClusterIssuer` to be used

Ingress rule example:
Bootstrap a custom root certificate for a private PKI (custom CA) and create the corresponding cert-manager CA issuer

```yml
apiVersion: networking.k8s.io/v1
kind: Ingress
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: my-selfsigned-ca
namespace: sandbox
spec:
isCA: true
commonName: my-selfsigned-ca
secretName: root-secret
privateKey:
algorithm: ECDSA
size: 256
issuerRef:
name: selfsigned-issuer
kind: ClusterIssuer
group: cert-manager.io
---
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
annotations:
# add an annotation indicating the issuer to use.
cert-manager.io/cluster-issuer: nameOfClusterIssuer
name: myIngress
namespace: myIngress
name: my-ca-issuer
namespace: sandbox
spec:
rules:
- host: example.com
http:
paths:
- pathType: Prefix
path: /
backend:
service:
name: myservice
port:
number: 80
tls: # < placing a host in the TLS config will determine what ends up in the cert's subjectAltNames
- hosts:
- example.com
secretName: myingress-cert # < cert-manager will store the created certificate in this secret.
ca:
secretName: root-secret
```

{{site.data.alerts.important}}

Algorithm used for creating private keys is ECDSA P-256. The use of this algorithm is required by the service mesh implementation I have selected for the cluster, Linkerd. RootCa and Linkerd identity issuer certificate must used ECDSA P-256 algorithm.

{{site.data.alerts.end}}



## Lets Encrypt Certificates

Lets Encrypt provide publicly validated TLS certificates for free. Not need to generate auti-signed SSL Certificates for the websites that are not automatic validated by HTTP browsers.
Lets Encrypt provide publicly validated TLS certificates for free. Not need to generate auto-signed SSL Certificates for the websites that are not automatic validated by HTTP browsers.

The process is the following, we issue a request for a certificate to Let's Encrypt for a domain name that we own. Let's Encrypt verifies that we own that domain by using an ACME DNS or HTTP validation mechanism. If the verification is successful, Let's Encrypt provides us with certificates that cert-manager installs in our website (or other TLS encrypted endpoint). These certificates are good for 90 days before the process needs to be repeated. Cert-manager, however, will automatically keep the certificates up-to-date for us.

Expand All @@ -121,7 +227,7 @@ Since Dec 2020, IONOS launched an API for remotelly configure DNS, and so the in

Unfortunally IONOS API is part of a beta program that it is not available yet in my location (Spain).

### Let`s Encrypt HTTP validation method
### Lets Encrypt HTTP validation method

HTTP validation method requires to actually expose a "challenge URL" in the Public Internet using the DNS domain associated to the SSL certificate.

Expand Down
28 changes: 15 additions & 13 deletions docs/_docs/index.md
Expand Up @@ -2,8 +2,8 @@
title: What is this project about?
permalink: /docs/home/
redirect_from: /docs/index.html
description: The scope of this project is to create a kubernetes cluster at home using Raspberry Pis and to use Ansible to automate the deployment and configuration. How to automatically deploy K3s baesed kubernetes cluster, Longhorn as distributed block storage for PODs' persisten volumes, Prometheus as monitoring solution, EFK stack as centralized log management solution and Velero and Restic as backup solution.
last_modified_at: "25-02-2022"
description: The scope of this project is to create a kubernetes cluster at home using Raspberry Pis and to use Ansible to automate the deployment and configuration. How to automatically deploy K3s baesed kubernetes cluster, Longhorn as distributed block storage for PODs' persisten volumes, Prometheus as monitoring solution, EFK stack as centralized log management solution, Velero and Restic as backup solution and Linkerd as service mesh architecture.
last_modified_at: "05-04-2022"
---


Expand All @@ -12,7 +12,7 @@ The scope of this project is to create a kubernetes cluster at home using **Rasp

This is an educational project to explore kubernetes cluster configurations using an ARM architecture and its automation using Ansible.

As part of the project the goal is to use a lightweight Kubernetes flavor based on [K3S](https://ks3.io/) and deploy cluster basic services such as: 1) distributed block storage for POD's persistent volumes, [LongHorn](https://longhorn.io/), 2) centralized monitoring tool, [Prometheus](https://prometheus.io/) 3) centralized log managemeent, EFK stack ([Elasticsearch](https://www.elastic.co/elasticsearch/)-[Fluentbit](https://fluentbit.io/)-[Kibana](https://www.elastic.co/kibana/) and 3) backup/restore solution for the cluster, [Velero](https://velero.io/) and [Restic](https://restic.net/).
As part of the project the goal is to use a lightweight Kubernetes flavor based on [K3S](https://ks3.io/) and deploy cluster basic services such as: 1) distributed block storage for POD's persistent volumes, [LongHorn](https://longhorn.io/), 2) centralized monitoring tool, [Prometheus](https://prometheus.io/) 3) centralized log managemeent, EFK stack ([Elasticsearch](https://www.elastic.co/elasticsearch/)-[Fluentbit](https://fluentbit.io/)-[Kibana](https://www.elastic.co/kibana/), 3) backup/restore solution for the cluster, [Velero](https://velero.io/) and [Restic](https://restic.net/) and 4) service mesh architecture, [Linkerd](https://linkerd.io/)


The following picture shows the set of opensource solutions used for building this cluster:
Expand Down Expand Up @@ -94,21 +94,23 @@ The software used and the latest version tested of each component
| OS | Ubuntu | 20.04.3 | OS need to be tweaked for Raspberry PI when booting from external USB |
| Control | Ansible | 2.12.1 | |
| Control | cloud-init | 21.4 | version pre-integrated into Ubuntu 20.04 |
| Kubernetes | K3S | v1.22.6 | K3S version|
| Kubernetes | K3S | v1.22.7 | K3S version|
| Kubernetes | Helm | v3.6.3 ||
| Computing | containerd | v1.5.9-k3s1 | version pre-integrated into K3S |
| Networking | Flannel | v0.15.1 | version pre-integrated into K3S |
| Networking | Flannel | v0.16.13 | version pre-integrated into K3S |
| Networking | CoreDNS | v1.8.6 | version pre-integrated into K3S |
| Networking | Metal LB | v0.11.0 | Helm chart version: metallb-0.11.0 |
| Service Proxy | Traefik | v2.5.6 | Helm chart: traefik-10.9.100 version pre-integrated into K3S |
| Storage | Longhorn | v1.2.3 | Helm chart version: longhorn-1.2.3 |
| SSL Certificates | Certmanager | v1.7.1 | Helm chart version: cert-manager-v1.7.1 |
| Logging | ECK Operator | 2.0.0 | Helm chart version: eck-operator-2.0.0 |
| Networking | Metal LB | v0.12.1 | Helm chart version: metallb-0.12.1 |
| Service Mesh | Linkerd | v2.11.1 | Helm chart version: linkerd2-2.11.1 |
| Service Proxy | Traefik | v2.6.1 | Helm chart: traefik-10.14.100 version pre-integrated into K3S |
| Storage | Longhorn | v1.2.4 | Helm chart version: longhorn-1.2.4 |
| SSL Certificates | Certmanager | v1.7.2 | Helm chart version: cert-manager-v1.7.2 |
| Logging | ECK Operator | 2.1.0 | Helm chart version: eck-operator-2.1.0 |
| Logging | Elastic Search | 7.15 | Deployed with ECK Operator |
| Logging | Kibana | 7.15 | Deployed with ECK Operator |
| Logging | Fluentbit | 1.8.12 | Helm chart version: fluent-bit-0.19.19 |
| Monitoring | Kube Prometheus Stack | 0.54.0 | Helm chart version: kube-prometheus-stack-32.2.1 |
| Logging | Fluentbit | 1.8.15 | Helm chart version: fluent-bit-0.19.23 |
| Monitoring | Kube Prometheus Stack | 0.55.0 | Helm chart version: kube-prometheus-stack-34.6.0 |
| Backup | Minio | 2021-12-29T06:49:06Z | |
| Backup | Restic | 0.12.1 | |
| Backup | Velero |1.7.1 | Helm chart version: velero-2.27.2 |
| Backup | Velero | 1.8.1 | Helm chart version: velero-2.29.4 |

{: .table }

0 comments on commit c350a5e

Please sign in to comment.