{"id":17604288,"url":"https://github.com/cloudacademy/knative-demo","last_synced_at":"2025-04-30T10:09:28.362Z","repository":{"id":77791606,"uuid":"260823537","full_name":"cloudacademy/knative-demo","owner":"cloudacademy","description":"Knative Demo","archived":false,"fork":false,"pushed_at":"2020-12-10T18:11:02.000Z","size":3932,"stargazers_count":5,"open_issues_count":0,"forks_count":9,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-25T06:43:27.236Z","etag":null,"topics":["async","devops","eventdriven","knative","kubernetes","microservices","serverless"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cloudacademy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-05-03T03:49:20.000Z","updated_at":"2024-01-31T08:59:29.000Z","dependencies_parsed_at":"2023-04-30T04:34:28.139Z","dependency_job_id":null,"html_url":"https://github.com/cloudacademy/knative-demo","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudacademy%2Fknative-demo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudacademy%2Fknative-demo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudacademy%2Fknative-demo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudacademy%2Fknative-demo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cloudacademy","download_url":"https://codeload.github.com/cloudacademy/knative-demo/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242635331,"owners_count":20161437,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["async","devops","eventdriven","knative","kubernetes","microservices","serverless"],"created_at":"2024-10-22T14:08:34.018Z","updated_at":"2025-03-09T02:30:41.168Z","avatar_url":"https://github.com/cloudacademy.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Knative Deployment Instructions\n\nThe following instructions are used to demonstrate Knative Serving and Eventing configurations. \n\n**Note**: The following instructions require a K8s cluster with a LoadBalancer service which exposes a publicly routable IPv4 address. Consider using a cluster hosted on EKS, GKE, or AKS.\n\n**Update** (Wed 25 Nov 2020) - instructions upgraded to work with the following versions:\n- Kubernetes: `v1.18.10`\n- Istio: `v1.8.0`\n- Knative: `v0.19.0`\n\n# STEP 1:\n\nInstall Knative\n\n## STEP 1.1:\n\nDownload and install ```istioctl``` command locally. This is used to now install Istio into the Kubernetes cluster:\n\n```\ncurl -L https://istio.io/downloadIstio | sh -\ncd istio-1.8.0/bin\ncp istioctl /usr/local/bin/\n```\n\nList the available Istio configuration [profiles](https://istio.io/latest/docs/setup/additional-setup/config-profiles/):\n\n```\nistioctl profile list\n```\n\nInstall the **default** Istio configuration profile:\n\n```\nistioctl install --set profile=default -y\n```\n\n## STEP 1.2:\n\nThe following commands can be used to troubleshoot Istio installations:\n\n```\nkubectl get ns\nkubectl get pods -n istio-system\nkubectl get pods -n istio-system --watch\nkubectl describe pod -n istio-system\nkubectl describe deploy -n istio-system\n```\n\n## STEP 1.3:\n\nInstall Knative Serving\n\n* Serving CRDs\n* Serving Core Components\n* Knative Istio Controller needed for Serving\n\n```\nkubectl apply --filename https://github.com/knative/serving/releases/download/v0.19.0/serving-crds.yaml\nkubectl apply --filename https://github.com/knative/serving/releases/download/v0.19.0/serving-core.yaml\nkubectl apply --filename https://github.com/knative/net-istio/releases/download/v0.19.0/release.yaml\n```\n\n## STEP 1.4:\n\nCheck Knative Serving pods are running\n\n```\nkubectl get pods -n knative-serving\n```\n\n## STEP 1.5:\n\nSetup xip.io for custom domain - provides wildcarded dynamic dns\n\n```\nkubectl apply --filename https://github.com/knative/serving/releases/download/v0.19.0/serving-default-domain.yaml\n\n```\n\n## STEP 1.6:\n\nInstall Eventing\n\n* Eventing CRDs\n* Eventing Core\n* Default InMemory Channel (not suitable for production)\n* Default Broker\n\n```\nkubectl apply --filename https://github.com/knative/eventing/releases/download/v0.19.0/eventing-crds.yaml\nkubectl apply --filename https://github.com/knative/eventing/releases/download/v0.19.0/eventing-core.yaml\nkubectl apply --filename https://github.com/knative/eventing/releases/download/v0.19.0/in-memory-channel.yaml\nkubectl apply --filename https://github.com/knative/eventing/releases/download/v0.19.0/mt-channel-broker.yaml\n```\n\n## STEP 1.7:\n\nCheck Eventing pods are running\n\n```\nkubectl get pods -n knative-eventing\n```\n\n# STEP 2:\n\nCreate the ```cloudacademy``` namespace\n\n```\ncat \u003c\u003c EOF | kubectl apply -f -\napiVersion: v1\nkind: Namespace\nmetadata:\n  name: cloudacademy\n  labels:\n    name: cloudacademy\nEOF\n```\n\nConfigure the ```cloudacademy``` namespace to be the default\n\n```\nkubectl config set-context --current --namespace cloudacademy\n```\n\n# Step 3\n\nDeploy Example Knative Service\n\n# Step 3.1\n\nInstall example helloworld service\n\n```\nfor version in {1..2}; do\ncat \u003c\u003c EOF | kubectl apply -f -\napiVersion: serving.knative.dev/v1\nkind: Service\nmetadata:\n  name: hellosvc\n  namespace: cloudacademy\nspec:\n  template:\n    metadata:\n      name: hellosvc-v$version\n    spec:\n      containers:\n        - image: docker.io/cloudacademydevops/helloworld:v1\n          env:\n            - name: SENDER\n              value: \"cloudacademy.knative.v$version\"\nEOF\ndone\n```\n\nTest the ```hellosvc``` knative service\n\n```\nkubectl get ksvc\n\nHELLO_SVC_URL=$(kubectl get ksvc/hellosvc -o jsonpath=\"{.status.url}\")\necho $HELLO_SVC_URL\n\ncurl $HELLO_SVC_URL/hello\n```\n\nDisplay current revisions\n\n```\nkubectl get revision\n```\n\n# Step 3.2\n\nInstall example helloworld service with traffic splitting\n\n```\ncat \u003c\u003c EOF | kubectl apply -f -\napiVersion: serving.knative.dev/v1\nkind: Service\nmetadata:\n  name: hellosvc\n  namespace: cloudacademy\nspec:\n  template:\n    metadata:\n      name: hellosvc-v3\n    spec:\n      containers:\n        - image: docker.io/cloudacademydevops/helloworld:v1\n          env:\n            - name: SENDER\n              value: \"cloudacademy.knative.v3\"\n  traffic:\n  - tag: prod\n    revisionName: hellosvc-v3\n    percent: 50\n  - tag: staging\n    revisionName: hellosvc-v2\n    percent: 50\n  - tag: latest\n    latestRevision: true\n    percent: 0\nEOF\n```\n\nTest the ```hellosvc``` knative service traffic splitting\n\n```\nkubectl get ksvc\n\nHELLO_SVC_URL=$(kubectl get ksvc/hellosvc -o jsonpath=\"{.status.url}\")\necho $HELLO_SVC_URL\n\nfor i in {1..10}; do\ncurl $HELLO_SVC_URL/hello\ndone\n```\n\nTest tag based urls\n\n```\nHELLO_SVC_URL_PROD=${HELLO_SVC_URL/hellosvc/prod-hellosvc}\ncurl $HELLO_SVC_URL_PROD/hello\n\nHELLO_SVC_URL_STAGING=${HELLO_SVC_URL/hellosvc/staging-hellosvc}\ncurl $HELLO_SVC_URL_STAGING/hello\n```\n\n```\nkubectl get revision\n```\n\n# Step 4\n\nConfigure knative autoscaling using kpa and 2 requests in-flight per pod\n\n```\ncat \u003c\u003c EOF | kubectl apply -f -\napiVersion: serving.knative.dev/v1\nkind: Service\nmetadata:\n  name: hellosvc\n  namespace: cloudacademy\nspec:\n  template:\n    metadata:\n      name: hellosvc-v4\n      annotations:\n        # 2 requests in-flight per pod - for testing\n        autoscaling.knative.dev/class:  kpa.autoscaling.knative.dev\n        autoscaling.knative.dev/metric: concurrency\n        autoscaling.knative.dev/target: \"2\"\n        autoscaling.knative.dev/minScale: \"0\"\n        autoscaling.knative.dev/maxScale: \"20\"\n    spec:\n      containers:\n        - image: docker.io/cloudacademydevops/helloworld:v4\n          imagePullPolicy: Always\n          env:\n            - name: SENDER\n              value: \"cloudacademy.knative.v4\"\nEOF\n```\n\nSend 20 concurrent curl requests to service - 5 times - for a total of 100 requests\n\n```\nfor i in {1..100}; do echo $HELLO_SVC_URL/hello?id=$i; done | xargs -P 20 -n 1 curl\n```\n\nExamine pods\n\nNote: All pods should eventually scale to zero (terminate) when traffic has completed. Rerunning the previous command will cause the pods to auto scale out to a maximum of 20 to serve the incoming traffic.\n\n```\nkubectl get pods --watch\n```\n\n# Step 5\n\nInstall Eventing - Source to Sink\n\n## Step 5.1\n\nInstall PingSource\n\n```\ncat \u003c\u003c EOF | kubectl apply -f -\napiVersion: sources.knative.dev/v1alpha2\nkind: PingSource\nmetadata:\n  name: ping-cloudacademy\n  namespace: cloudacademy\nspec:\n  schedule: \"* * * * *\"\n  jsonData: '{\"message\": \"knative rocks!!\"}'\n  sink:\n    ref:\n      apiVersion: serving.knative.dev/v1\n      kind: Service\n      name: cloudacademy-service\nEOF\n```\n\n## Step 5.2\n\nInstall Service - SimpleLogger\n\n```\ncat \u003c\u003c EOF | kubectl apply -f -\napiVersion: serving.knative.dev/v1\nkind: Service\nmetadata:\n  name: cloudacademy-service\n  namespace: cloudacademy\nspec:\n  template:\n    metadata:\n      name: cloudacademy-service-v1\n    spec:\n      containers:\n      - image: cloudacademydevops/simplelogger:v1\n        ports:\n        - containerPort: 8080\nEOF\n```\n\n## Step 5.3\n\nExamine SimpleLogger pod log\n\n```\nSIMPLELOGGER_POD=$(kubectl get pod -l app=cloudacademy-service-v1 --no-headers=true -o custom-columns=:metadata.name)\necho $SIMPLELOGGER_POD\n\nkubectl logs $SIMPLELOGGER_POD -c user-container --follow\n```\n\n# Step 6\n\nInstall Eventing - Channel and Subscription\n\n## Step 6.1\n\nInstall InMemoryChannel\n\n```\ncat \u003c\u003c EOF | kubectl apply -f -\napiVersion: messaging.knative.dev/v1\nkind: InMemoryChannel\nmetadata:\n  name: cloudacademy-channel\n  namespace: cloudacademy\nEOF\n```\n\n## Step 6.2\n\nInstall PingSource\n\n```\ncat \u003c\u003c EOF | kubectl apply -f -\napiVersion: sources.knative.dev/v1alpha2\nkind: PingSource\nmetadata:\n  name: ping-cloudacademy\n  namespace: cloudacademy\nspec:\n  schedule: \"* * * * *\"\n  jsonData: '{\"message\": \"knative rocks!!\", \"from\": \"pingsource - channelsub\"}'\n  sink:\n    ref:\n      apiVersion: messaging.knative.dev/v1\n      kind: InMemoryChannel\n      name: cloudacademy-channel\nEOF\n```\n\n## Step 6.3\n\nInstall 2x Service - SimpleLogger\n\n```\ncat \u003c\u003c EOF | kubectl apply -f -\napiVersion: serving.knative.dev/v1\nkind: Service\nmetadata:\n  name: cloudacademy-service1\n  namespace: cloudacademy\nspec:\n  template:\n    metadata:\n      name: cloudacademy-service1-v1\n      annotations:\n        autoscaling.knative.dev/minScale: \"1\"\n        autoscaling.knative.dev/maxScale: \"1\"\n    spec:\n      containers:\n      - image: cloudacademydevops/simplelogger:v1\n        ports:\n        - containerPort: 8080\n---\napiVersion: serving.knative.dev/v1\nkind: Service\nmetadata:\n  name: cloudacademy-service2\n  namespace: cloudacademy\nspec:\n  template:\n    metadata:\n      name: cloudacademy-service2-v1\n      annotations:\n        autoscaling.knative.dev/minScale: \"1\"\n        autoscaling.knative.dev/maxScale: \"1\"\n    spec:\n      containers:\n      - image: cloudacademydevops/simplelogger:v1\n        ports:\n        - containerPort: 8080\nEOF\n```\n\n## Step 6.4\n\nInstall 2x Subscription\n\n```\ncat \u003c\u003c EOF | kubectl apply -f -\napiVersion: messaging.knative.dev/v1\nkind: Subscription\nmetadata:\n  name: cloudacademy-sub1\n  namespace: cloudacademy\nspec:\n  channel:\n    apiVersion: messaging.knative.dev/v1\n    kind: InMemoryChannel\n    name: cloudacademy-channel\n  subscriber:\n    ref:\n      apiVersion: serving.knative.dev/v1\n      kind: Service\n      name: cloudacademy-service1\n---\napiVersion: messaging.knative.dev/v1\nkind: Subscription\nmetadata:\n  name: cloudacademy-sub2\n  namespace: cloudacademy\nspec:\n  channel:\n    apiVersion: messaging.knative.dev/v1\n    kind: InMemoryChannel\n    name: cloudacademy-channel\n  subscriber:\n    ref:\n      apiVersion: serving.knative.dev/v1\n      kind: Service\n      name: cloudacademy-service2\nEOF\n```\n\n## Step 6.5\n\nExamine SimpleLogger pods - log\n\n```\nSIMPLELOGGER_SVC1_POD=$(kubectl get pod -l app=cloudacademy-service1-v1 --no-headers=true -o custom-columns=:metadata.name)\nSIMPLELOGGER_SVC2_POD=$(kubectl get pod -l app=cloudacademy-service2-v1 --no-headers=true -o custom-columns=:metadata.name)\n\necho $SIMPLELOGGER_SVC1_POD\necho $SIMPLELOGGER_SVC2_POD\n\nkubectl logs $SIMPLELOGGER_SVC1_POD -c user-container --follow\nkubectl logs $SIMPLELOGGER_SVC2_POD -c user-container --follow\n```\n\n# Step 7\n\nInstall Eventing - Broker and Trigger\n\n## Step 7.1\n\nConfigure automatic knative eventing injection\n\n```\nkubectl label ns cloudacademy knative-eventing-injection=enabled\n```\n\nInstall default Broker\n\n```\ncat \u003c\u003c EOF | kubectl apply -f -\napiVersion: eventing.knative.dev/v1\nkind: broker\nmetadata:\n name: default\n namespace: cloudacademy\nEOF\n```\n\nGet the broker url for the cloudacademy namespace\n\n```\nkubectl config set-context --current --namespace cloudacademy\nkubectl get broker default\n```\n\n## Step 7.2\n\nInstall PingSource\n\n```\ncat \u003c\u003c EOF | kubectl apply -f -\napiVersion: sources.knative.dev/v1alpha2\nkind: PingSource\nmetadata:\n  name: ping-cloudacademy\n  namespace: cloudacademy\nspec:\n  schedule: \"* * * * *\"\n  jsonData: '{\"message\": \"knative rocks!!\", \"from\": \"pingsource - brokertrigger\"}'\n  sink:\n    ref:\n      apiVersion: eventing.knative.dev/v1\n      kind: Broker\n      name: default\nEOF\n```\n\n## Step 7.3\n\nInstall 3x Service - SimpleLogger\n\n```\ncat \u003c\u003c EOF | kubectl apply -f -\napiVersion: serving.knative.dev/v1\nkind: Service\nmetadata:\n  name: cloudacademy-service1\n  namespace: cloudacademy\nspec:\n  template:\n    metadata:\n      name: cloudacademy-service1-v1\n      annotations:\n        autoscaling.knative.dev/minScale: \"1\"\n        autoscaling.knative.dev/maxScale: \"1\"\n    spec:\n      containers:\n      - image: cloudacademydevops/simplelogger:v1\n        ports:\n        - containerPort: 8080\n---\napiVersion: serving.knative.dev/v1\nkind: Service\nmetadata:\n  name: cloudacademy-service2\n  namespace: cloudacademy\nspec:\n  template:\n    metadata:\n      name: cloudacademy-service2-v1\n      annotations:\n        autoscaling.knative.dev/minScale: \"1\"\n        autoscaling.knative.dev/maxScale: \"1\"\n    spec:\n      containers:\n      - image: cloudacademydevops/simplelogger:v1\n        ports:\n        - containerPort: 8080\n---\napiVersion: serving.knative.dev/v1\nkind: Service\nmetadata:\n  name: cloudacademy-service3\n  namespace: cloudacademy\nspec:\n  template:\n    metadata:\n      name: cloudacademy-service3-v1\n      annotations:\n        autoscaling.knative.dev/minScale: \"1\"\n        autoscaling.knative.dev/maxScale: \"1\"\n    spec:\n      containers:\n      - image: cloudacademydevops/simplelogger:v1\n        ports:\n        - containerPort: 8080\nEOF\n```\n\n## Step 7.4\n\nInstall 3x Trigger\n\n```\ncat \u003c\u003c EOF | kubectl apply -f -\napiVersion: eventing.knative.dev/v1\nkind: Trigger\nmetadata:\n  name: cloudacademy-trigger1\n  namespace: cloudacademy\nspec:\n  broker: default\n  filter:\n    attributes:\n      type: dev.knative.sources.ping\n  subscriber:\n    ref:\n      apiVersion: serving.knative.dev/v1\n      kind: Service\n      name: cloudacademy-service1\n---\napiVersion: eventing.knative.dev/v1\nkind: Trigger\nmetadata:\n  name: cloudacademy-trigger2\n  namespace: cloudacademy\nspec:\n  broker: default\n  filter:\n    attributes:\n      type: dev.knative.sources.ping\n  subscriber:\n    ref:\n      apiVersion: serving.knative.dev/v1\n      kind: Service\n      name: cloudacademy-service2\n---\napiVersion: eventing.knative.dev/v1\nkind: Trigger\nmetadata:\n  name: cloudacademy-trigger3\n  namespace: cloudacademy\nspec:\n  broker: default\n  filter:\n    attributes:\n      type: cloudacademy.app.blah\n  subscriber:\n    ref:\n      apiVersion: serving.knative.dev/v1\n      kind: Service\n      name: cloudacademy-service3\nEOF\n```\n\n## Step 7.5\n\nCreate Curler Pod\n\n```\ncat \u003c\u003c EOF | kubectl apply -f -\napiVersion: v1\nkind: Pod\nmetadata:\n  labels:\n    run: curler\n  name: curler\n  namespace: cloudacademy\nspec:\n  containers:\n  - name: curler\n    image: fedora:latest\n    tty: true\nEOF\n```\n\n## Step 7.6\n\nRetrieve broker url\n\n```\nBROKER_URL=$(kubectl get broker default -o jsonpath='{.status.address.url}')\necho BROKER_URL: $BROKER_URL\n```\n\n## Step 7.7\n\nPerform an HTTP POST - send CloudEvent message \n\n```\nkubectl exec -it curler -- curl -v $BROKER_URL \\\n-H \"Ce-Id: say-hello\" \\\n-H \"Ce-Specversion: 1.0\" \\\n-H \"Ce-Type: cloudacademy.app.blah\" \\\n-H \"Ce-Source: mycurl\" \\\n-H \"Content-Type: application/json\" \\\n-d '{\"key\":\"curl cloudevent message!!\"}'\n```\n\n## Step 7.8\n\nExamine SimpleLogger pods - log\n\n```\nSIMPLELOGGER_SVC1_POD=$(kubectl get pod -l app=cloudacademy-service1-v1 --no-headers=true -o custom-columns=:metadata.name)\nSIMPLELOGGER_SVC2_POD=$(kubectl get pod -l app=cloudacademy-service2-v1 --no-headers=true -o custom-columns=:metadata.name)\nSIMPLELOGGER_SVC3_POD=$(kubectl get pod -l app=cloudacademy-service3-v1 --no-headers=true -o custom-columns=:metadata.name)\n\necho $SIMPLELOGGER_SVC1_POD\necho $SIMPLELOGGER_SVC2_POD\necho $SIMPLELOGGER_SVC3_POD\n\nkubectl logs $SIMPLELOGGER_SVC1_POD -c user-container --follow\nkubectl logs $SIMPLELOGGER_SVC2_POD -c user-container --follow\nkubectl logs $SIMPLELOGGER_SVC3_POD -c user-container --follow\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcloudacademy%2Fknative-demo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcloudacademy%2Fknative-demo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcloudacademy%2Fknative-demo/lists"}