This helm chart will deploy IdentityServer4.Admin onto your k8s cluster.
Deployed components:
- Admin
- STS.Identity
- API
Note: Currently there is no support for TLS, external database services or namespaces. The API service is also missing at the moment.
Add the helm repo
helm repo add identityserver4admin https://bravecobra.github.io/identityserver4.admin-helm/charts/
helm repo updateCreate a identityserver-values.yaml file to override any default values, specific to your installation. The default values can be found in values.yaml
Then install the helm chart in the namespace you want. Here we choose to install the release identityserver4 in the infrastructure namespace.
helm upgrade --install identityserver4 identityserver4admin/identityserver4admin --namespace infrastructure --values .\identityserver-values.yamlApart from specifying overrides of the values.yml, there are 2 more things that need to be addressed.
- You need to adapt make sure that the admin pod can resolve the identity pod by it's external name. We'll do that by patching the ConfigMap of CoreDNS
- You need to route traffic through an ingress controller. An example of Traefik is being given here
Next, the client applications need to be able to verify the certificate, with which token are signed. To do that, they contact the Issuer url. That url is in the example http://login.k8s.local, which a pod will not be able to resolve correctly.
To do so, we patch the CoreDNS config file and point that hostname to the service that needs to respond. Note the 2 extra rewrite lines. Here they point to the services deployed in the infrastructure namespace.
.:53 {
errors
health {
lameduck 5s
}
rewrite name login.k8s.local identityserver4-identity.infrastructure.svc.cluster.local
rewrite name admin.login.k8s.local identityserver4-admin.infrastructure.svc.cluster.local
ready
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30
}
prometheus :9153
forward . /etc/resolv.conf {
max_concurrent 1000
}
cache 30
loop
reload
loadbalance
}First you want your ingress controller to have the domains you specified for the services to be forwarded to those services that were created.
In Traefik that would be something like the following.
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: "login-admin-ingressroute"
namespace: infrastructure #the namespace you installed in
spec:
entryPoints:
- web
routes:
- match: Host(`admin.login.k8s.local`) && PathPrefix(`/`)
kind: Rule
namespace: infrastructure #the namespace you installed in
services:
- name: identityserver4-admin
port: 80
path: /
passHostHeader: true
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: "login-ingressroute"
namespace: infrastructure #the namespace you installed in
spec:
entryPoints:
- web
routes:
- match: Host(`login.k8s.local`) && PathPrefix(`/`)
kind: Rule
namespace: infrastructure #the namespace you installed in
services:
- name: identityserver4-identity
port: 80
path: /
passHostHeader: trueIf you have cert-manager already install on your cluster, we can easily let this Chart autogenerate the certificates, provided there is an CA Root to sign them. You can use any method cert-manager provides. In this example we'll use the Self-Signed Issuer.
To install cert-manager on your cluster with helm, here's the quick start. For more info, look at their site
kubectl create namespace cert-manager
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace --version v1.3.1 --set installCRDs=trueFirst let's use mkcert to generate a CA Root on our dev machine. This CA root is only valid for local development.
# execute under elevated Administrator privileges
choco install mkcert
mkcert --installCreate a kubernetes secret from the CA Root.
copy $env:LOCALAPPDATA\mkcert\rootCA.pem ./src/examples/cacerts.crt
copy $env:LOCALAPPDATA\mkcert\rootCA-key.pem ./src/examples/cacerts.keyNext we turn this certificate into a Issuer for cert-manager to use. Any certificate requests it receives for it, will use this CA Root to sign the requested certificates and since our local dev manchine knows the CA Root as well, it'll be valid for both your cluster and for your local dev machine.
# Create a k8s secret manifest containing the CA Root certificate of mkcert to a cacerts.yaml file
kubectl create secret tls ca-key-pair --namespace=cert-manager --cert=./src/examples/cacerts.crt --key=./src/examples/cacerts.key --dry-run=client -o yaml > ./src/examples/cacerts.yaml
kubectl apply -f ./src/examples/cacerts.yamlNow add that new secret as an Issuer to cert-manager by applying the ./src/examples/cluster-issuer.yaml:
kubectl apply -f ./src/examples/cluster-issuer.yamlNext make sure you add the following to your values.yaml file and the helm chart will generate the certificates for each service if they have ssl: true.
certificates:
certManager:
enabled: true
issuerRef:
name: selfsigned-ca-issuer
kind: ClusterIssuerYou can also provide your own certificates if you want, by enabling ssl for the services and specifying the kubernetes secret name that contains the certificate. Make sure to add the CA root public key.
kind: Secret
apiVersion: v1
metadata:
name: identityserver4-cert-admin
namespace: infrastructure #the namespace you installed in
type: kubernetes.io/tls
data:
ca.crt: >-
LS0tLS1CRUdJTiBDRVJ....tLS0tCg==
tls.crt: >-
LS0tLS1CRUdJTiBDRVJUSUZ...0tLS0K
tls.key: >-
LS0tLS1CRUdJTiBSU0EgUFJ...LS0tLQo=This helm chart can provide 3 embedded database engines types.
- SqlServer
- MySql
- PostgreSQL
They can be enabled by setting either of them. Enabling one of these will add an extra deployment of that database type and configure the connectionstrings in the services automatically. Be sure to set the providerType correctly to match.
database:
providerType: SqlServer
# providerType: MySql
# providerType: PostgreSQL
mssql:
enabled: true
mysql:
enabled: false
postgresql:
enabled: falseYou can also use the database.connectionString value to override. This will override any generated connectionstring if you don't want to use any of the embedded engines and provide your own.
By default it'll provide a SQL Server instance if none of the values are set.