How to install Spinnaker in a Kubernetes Cluster?

AsherAsher
3 min read

Installing Spinnaker in a Kubernetes cluster is very straightforward. Here are the things we will do:

  • Install Spinnaker Operator

  • Install Spinnaker

    • Modify spinnakerservice. (Add overridebaseUrl & GitHub Oath)
  • Exposing spinnaker via Ingress

    • Install nginx ingress controller

    • Create an ingress manifest

    • Route Loadbalancer IP to a domain (deck and gate)

  • Add SSL to a domain via cert-manager

    • Installing cert manager

    • clusterissuer and certificates manifest

  • Demo: Create a simple CICD flow using Github (CI), Docker Hub (Registry) and Spinnaker(CD)

    • Configure a provider

    • Create a Sample CD pipeline

Prerequisite

  • A kubernetes cluster. In my case I'm having Digital Ocean managed Kubernetes with (4vcpu and 8gbram-> for nodes). If you are looking at self-hosted k8s, check Metallb for load balancing, else not needed as long as your infrastructure supports it.

Install Spinnaker Operator

Instructions: https://github.com/armory/spinnaker-operator

Install Spinnaker

Instructions: https://github.com/armory/spinnaker-kustomize-patches

  • Modify the SpinnakerService

Here we modify the spinnakerservice.yaml by adding the overridebaseurl and oauth2 for Github. Get your GH api keys:

We need to prepare the kind: SpinnakerService to accomodate custom domain and Github SSO by editing spinnakerservice.yml:


      security:                # Authentication and authorization.
        uiSecurity:
          overrideBaseUrl: https://deck.spinnaker.asherl.com
        apiSecurity:
          overrideBaseUrl: https://gate.spinnaker.asherl.com 
        authn:
          oauth2:
            enabled: true
            client:
              clientId: ab0c2XXXXXXXXXX24fbb81
              clientSecret: 819c736da46XXXXXXXXX712847f1f0c
              accessTokenUri: https://github.com/login/oauth/access_token
              userAuthorizationUri: https://github.com/login/oauth/authorize
              scope: user:email
            resource:
              userInfoUri: https://api.github.com/user
            userInfoRequirements: {}
            userInfoMapping:
              email: email
              firstName: ''
              lastName: name
              username: login
            provider: GITHUB

Then hit:

# Build the kustomize template and deploy in kubernetes
kustomize build . | kubectl apply -f -

        helm repo add nginx-stable https://helm.nginx.com/stable
        helm repo update

        helm install my-release nginx-stable/nginx-ingress

This will create a Loadbalancer service.

  • Create an ingress manifest. Here you only need to change the host.
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: spinnaker-ui-ingress
      namespace: spinnaker
      annotations:
        kubernetes.io/tls-acme: "true"
        kubernetes.io/ingress.class: "nginx"
        cert-manager.io/cluster-issuer: "letsencrypt-prod"
        acme.cert-manager.io/http01-edit-in-place: "true"
        nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    spec:
      tls:
      - hosts:
        - deck.spinnaker.asherl.com
        secretName: spin-deck-tls
      rules:
        - host: deck.spinnaker.asherl.com 
          http:
            paths:
              - path: /
                pathType: Prefix
                backend:
                  service:
                    name: spin-deck
                    port:
                      number: 9000

    ---

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: spinnaker-api-ingress
      namespace: spinnaker
      annotations:
        kubernetes.io/tls-acme: "true"
        kubernetes.io/ingress.class: "nginx"
        cert-manager.io/cluster-issuer: "letsencrypt-prod"
        acme.cert-manager.io/http01-edit-in-place: "true"
        nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    spec:
      tls:
      - hosts:
        - gate.spinnaker.asherl.com
        secretName: spin-gate-tls
      rules:
        - host: "gate.spinnaker.asherl.com" 
          http:
            paths:
              - path: /
                pathType: Prefix
                backend:
                  service:
                    name: spin-gate
                    port:
                      number: 8084

  • Route Loadbalancer IP to a domain via your DNS provider (deck and gate)

  • Add SSL to a domain via cert-manager

    • Installing cert manager
    kubectl create namespace cert-manager
    helm repo add jetstack https://charts.jetstack.io
    helm repo update

    kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.11.0/cert-manager.crds.yaml

    helm install \
      cert-manager jetstack/cert-manager \
      --namespace cert-manager \
      --create-namespace \
      --version v1.11.0 \
      # --set installCRDs=true
  • clusterissuer and certificates manifests

    • clusterissuer.yaml

    •   apiVersion: cert-manager.io/v1
        kind: ClusterIssuer
        metadata:
          name: letsencrypt-prod
          namespace: spinnaker
        spec:
          acme:
            # Email address used for ACME registration
            email: asher01000001@gmail.com
            server: https://acme-v02.api.letsencrypt.org/directory
            privateKeySecretRef:
              # Name of a secret used to store the ACME account private key
              name: letsencrypt-prod-private-key
            # Add a single challenge solver, HTTP01 using nginx
            solvers:
            - http01:
                ingress:
                  class: nginx
      
  • certificate.yaml

  •   apiVersion: cert-manager.io/v1
      kind: Certificate
      metadata:
        name: my-domain-spinnaker  
        namespace: spinnaker
      spec:
        secretName: test-domain-tls
        issuerRef:
          name: letsencrypt-prod
          kind: ClusterIssuer
        duration: 2160h # 90d
        renewBefore: 720h # 30d before SSL will expire, renew it
        dnsNames:
          - "deck.spinnaker.asherl.com"
          - "gate.spinnaker.asherl.com"
    

    Then we apply:

  •    k apply -f certificate.yaml -f clusterissuer.yaml
    

    Demo: Create a simple CD flow

We will be using Kubernetes as our provider. Create a manifest file. (e.g. Deploying simple nginx application)

You can use AWS, Azure, etc to deploy: https://docs.armory.io/continuous-deployment/installation/armory-operator/op-manifest-reference/providers/

Congratulations!

0
Subscribe to my newsletter

Read articles from Asher directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Asher
Asher