Skip to content

Latest commit

 

History

History
446 lines (314 loc) · 14 KB

DEPLOYMENT.md

File metadata and controls

446 lines (314 loc) · 14 KB

Deployment

Prerequisites

Build Images

Lets build and push all images to a registry and then create deployments.

UI Image

Ensure you are in ui directory and logged in you image registry.

docker build -t <image> . && docker push <image>

Replace <image> with the registry and image name. eg. quay.io/<username>/ui

API & DB Migration Image

Ensure you are in api directory and logged in you image registry.

Build the API image using below command

docker build -t <image> . && docker push <image>

Replace <image> with the registry and image name. eg. quay.io/<username>/api

Now, Build the Db migration image using below command

docker build -f db.Dockerfile -t <image> . && docker push <image>

Replace <image> with the registry and image name. eg. quay.io/<username>/db-migration

Make sure all images are public before creating deployments.

Deploy Database

Now, we have all images pushed to registry. Lets deploy the database first.

Navigate to config directoy in the root of the project.

Execute below command

kubectl apply -f 00-init/

This will create tekton-hub namespace, db deployment with postgres image, secret to save db credentials, pvc for the db and a ClusterIP service to expose the db internally.

All resources are created in tekton-hub namespace.

Wait till the pod comes in a running state

kubectl get pod -n tekton-hub -w

Run Db migration

Once the pod is in running state now we can run db migration. This will create all the tables required in the database.

Edit the 01-db/10-db-migration.yaml and add the replace the image you created previously and apply the yaml.

kubectl apply -f 01-db/10-db-migration.yaml

This will create a job which will read the db credentials from the secret created while deploying database and create all required tables.

$ kubectl get pods -n tekton-hub
NAME                   READY   STATUS      RESTARTS   AGE
db-589d44fdd5-ksf8v    1/1     Running     0          50s
db-migration-8vhpd     0/1     Completed   0          17s

You can also check the logs using kubectl logs -n tekton-hub db-migration-8vhpd

The migration logs at the end should show

2020-09-22T15:35:16.412Z INFO migration/migration.go:91 Migration ran successfully !! {"service": "migration"}
2020-09-22T15:35:16.412Z INFO db/main.go:39 DB initialisation successful !! {"service": "main"}

Deploy API Service

Update API Secret

Edit 02-api/20-api-secret.yaml and update the configuration

  • Create a GitHub OAuth with Homepage URL and Authorization callback URL as http://localhost:5000. We will update this URL once we deploy the UI pod. Follow the steps given here to create a GitHub OAuth.
  • After creating the OAuth add the Client ID and Client Secret in the yaml file.
  • For JWT_SIGNING_KEY, you can add any random string, this is used to sign the JWT created for users.
  • For ACCESS_JWT_EXPIRES_IN and REFRESH_JWT_EXPIRES_IN add time you want the jwt to be expired in. Refresh time should be greater than Access time. eg. 1m = 1 minute, 1h = 1 hour, 1d = 1 day
apiVersion: v1
kind: Secret
metadata:
  name: api
  namespace: tekton-hub
type: Opaque
stringData:
  GH_CLIENT_ID: Oauth client id
  GH_CLIENT_SECRET: Oauth secret
  JWT_SIGNING_KEY: a-long-signing-key
  ACCESS_JWT_EXPIRES_IN: time such as 15m
  REFRESH_JWT_EXPIRES_IN: time such as 15m

Update API ConfigMap

If you want to change the config file passed to hub, you can edit the 02-api/21-api-configmap.yaml and change the URL to the file. By default it is pointing to config.yaml in Hub which has Application Data.

apiVersion: v1
kind: ConfigMap
metadata:
  name: api
  namespace: tekton-hub
  labels:
    app: api
data:
  CONFIG_FILE_URL: https://raw.githubusercontent.com/tektoncd/hub/master/config.yaml        ## Change the file URL here

In this file we add users who have additional scopes which can be used to

  • refresh a catalog,
  • refresh config file
  • create an agent token

All users have default scopes rating:read and rating:write they get after login which allows them to rate the resources.

Update API Image

Edit the 02-api/22-api-deployment.yaml and replace the image with the one created previously and executed below command

kubectl apply -f 02-api/

This will create the deployment, secret, configmap and a NodePort service to expose the API server.

Setup Route or Ingress

After the deployment is done successfully, we need to expose the URL to access the API.

  • If deploying on OpenShift:-

    kubectl apply -f 04-openshift/40-api-route.yaml
  • If deploying on Kubernetes:-

    • Create the secret containing tls cert and tls key

      kubectl create secret tls api-hub-tekton-dev-tls --cert=path/to/cert/file --key=path/to/key/file -n tekton-hub
    • Apply the Ingress

      kubectl apply -f 04-kubernetes/40-api-ingress.yaml

Verify if api route is accessible

For OpenShift:-

curl -k -X GET $(oc get -n tekton-hub routes api --template='https://{{ .spec.host }}/v1/categories')

NOTE: At this moment, there are no resources in the db. Only the tags and categories from hub config are added in the db.

Let's deploy the UI first and then we will add the resources in db.

Deploy UI

Update UI ConfigMap

Edit config/10-config.yaml and set your GitHub OAuth Client ID and the API URL.

You can get the API URL using below command (OpenShift)

  kubectl get -n tekton-hub routes api --template='https://{{ .spec.host }}'
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: ui
  namespace: tekton-hub
data:
  API_URL: API URL   <<< Update this by API url
  GH_CLIENT_ID: GH OAuth Client ID   <<< Update this OAuth client id

Update UI Image

Edit the 03-ui/30-ui-configmap.yaml and replace the image with the one created previously and executed below command

kubectl apply -f 03-ui/

This will create the deployment, configmap and a NodePort service to expose the UI.

Ensure pods are up and running

kubectl get pods -n tekton-hub

eg. wait till status of UI pod is running

NAME                   READY   STATUS      RESTARTS   AGE
api-6dfc6f97d9-vk66r   1/1     Running     3          21m
db-9bd4cdf99-zsq89     1/1     Running     0          21m
db-migration-26ngs     0/1     Completed   0          21m
ui-55fc66cc6b-69dsp    1/1     Running     0          58s

Setup Route or Ingress

After the deployment is done successfully, we need to expose the URL to access the UI.

  • If deploying on OpenShift:-

    kubectl apply -f 04-openshift/41-ui-route.yaml
  • If deploying on Kubernetes:-

    • Create the secret containing tls cert and tls key

      kubectl create secret tls ui-hub-tekton-dev-tls --cert=path/to/cert/file --key=path/to/key/file -n tekton-hub
    • Apply the Ingress

      kubectl apply -f 04-kubernetes/41-ui-ingress.yaml

Verify if ui route is accessible

For OpenShift:-

    kubectl get routes -n tekton-hub ui --template='https://{{ .spec.host }} '

Open the URL in a browser.

Note: In UI you won't be able see the resources on homepage as there are not any in the db but you should see Categories on the left side.

Update your GitHub OAuth created with the UI route in place of Homepage URL and Authorization callback URL.

Add resources in DB

  1. Add your GitHub username with required scopes in config.yaml. For adding resources in DB, you will need catalog:refresh scope.

  2. Login through the UI. Click on Login on right corner and then Sign in with GitHub.

This will add you in db, but yet you have only the default scopes i.e. rating:read and rating:write which you can check with your jwt. On UI, in right corner there is an option to Copy Hub Token and paste in any jwt decoder. for eg. https://jwt.io/

  1. We save the checksum of config file in db to avoid reading the config file again and again if the api pod is deleted due to some reason. The config file is read by API pod before starting the server.

  2. To make API pod read config we need to delete the entry in db. Exec into the database pod

    kubectl exec -n tekton-hub -it <db-pod-name> bash
  3. Open PostgreSQL terminal by executing the command

    psql -U postgres -d hub

    You'll see the terminal changed to

    hub=#
  4. Execute the SQL query

    hub=# delete from configs;
  5. Quit the database pod by first executing

    hub=# \q

    and then exit.

  6. Delete the API pod by executing the following command

    kubectl delete pod -n tekton-hub <pod-name>

    This will delete the previously created pod and spin a new pod which will add the additional scopes from hub config in the DB.

  7. Once the pod is running again, Logout from Hub UI and login again.

  8. Now, if you copy your token from UI and check in jwt decoder, you will have additional scopes.

  9. To add resources, you need to make a POST api call passing your jwt token with the additional scopes in Header.

curl -X POST -H "Authorization: <access-token>" \
    <api-url>/catalog/refresh 

Replace <access-token> with your Hub token copied from UI and replace <api-url> with your api pod url.

This will give an output as below

{"id":1,"status":"queued"}
  1. Refresh your UI, you will be able to see resources.

Setup Catalog Refresh CronJob

You can setup a cronjob which will refresh your db after an interval if there are any changes in your catalog.

NOTE: The catalog refresh will add new resources or update existing resource if it is updated in catalog but it doesn't delete a resource in db even if it is deleted in catalog.

  1. You will need a JWT token with catalog refresh scope which can be used.

  2. A User token is short lived so you can create an agent token which will not expire.

  3. To create an agent, you can use the /system/user/agent. You will need agent:create scope in your JWT which has to be added in config.yaml

    curl -X PUT --header "Content-Type: application/json" \
        -H "Authorization: <access-token>" \
        --data '{"name":"catalog-refresh-agent","scopes": ["catalog:refresh"]}' \
        <api-route>/system/user/agent
    

    Replace <access-token> with your JWT, you can create an agent with any required scopes. In this case we need the agent with catalog:refresh. You can give any name to agent.

    This will gives an output as:

    {"token":"agent jwt token"}
    

    A token will be returned with the requested scopes. You can check using the jwt decoder. Use this token for the catalog refresh cron job.

  4. Edit 05-catalog-refresh-cj/50-catalog-refresh-secret.yaml and Set the Hub Token

    apiVersion: v1
    kind: Secret
    metadata:
      name: catalog-refresh
      namespace: tekton-hub
    type: Opaque
    stringData:
      HUB_TOKEN: hub token

    Set the token created in last step as Hub token.

  5. Apply the YAMLs

    kubectl apply -f 05-catalog-refresh-cj/
    

    The cron job is configured to run every 30 min, you can change the interval in 05-catalog-refresh-cj/51-catalog-refresh-cronjob.yaml.

Adding New Users in Config

By default when any user login for the first time, they will have only default scope even if they are added in config.yaml. To get additinal scopes, make sure the user has logged in once.

Now, we need to refresh the config. To do that do a POST API call.

curl -X POST -H "Authorization: <access-token>" \
    --header "Content-Type: application/json" \
    --data '{"force": true} \
  <api-route>/system/config/refresh

Replace <access-token> with your JWT token. you must have config-refresh scope to call this API.

Troubleshooting

UI is not showing resources but catalog refresh is successful

  • If you have insecure connection the UI might not be able to hit the API.
  • So, hit the API URL in your browser https://<api-url> once you get the response as status: ok, refresh you UI.

UI is not showing resources but catalog refresh is successful (Console Error)

  • Verify catalog refresh is successful by hitting the /v1/resources API using the API URL.
  • If is returning resources than check for console errors on UI.
  • Right click -> Inspect or (Ctrl + Shift + I) (For Chrome). Then click on console tab.
  • If there is cors error then check the UI config map and the URL you have added.
  • The URL should be for example https://api.hub.tekton.dev and not https://api.hub.tekton.dev/ there shouldn't be / at the end.