Serving Red Hat OpenShift Serverless 1.35 Getting started with Knative Serving and configuring services Red Hat OpenShift Documentation Team

Commands:
apiVersion: serving.knative.dev/v1 kind: Service metadata: name: showcase 1 namespace: default 2 spec: template: spec: containers: - image: quay.io/openshift-knative/showcase 3 env: - name: GREET 4 value: Ciao
kn service create <service-name> --image <image> --tag <tag-value>
kn service create showcase --image quay.io/openshift-knative/showcase
Creating service 'showcase' in namespace 'default': 0.271s The Route is still working to reflect the latest desired specification. 0.580s Configuration "showcase" is waiting for a Revision to become ready. 3.857s 3.861s Ingress has not yet been reconciled. 4.270s Ready to serve. Service 'showcase' created with latest revision 'showcase-00001' and URL: http://showcase-default.apps-crc.testing
apiVersion: serving.knative.dev/v1 kind: Service metadata: name: showcase namespace: default spec: template: spec: containers: - image: quay.io/openshift-knative/showcase env: - name: GREET value: Bonjour
oc apply -f <filename>
apiVersion: serving.knative.dev/v1 kind: Service metadata: name: showcase 1 namespace: default 2 spec: template: spec: containers: - image: quay.io/openshift-knative/showcase 3 env: - name: GREET 4 value: Ciao
kn service create showcase --image quay.io/openshift-knative/showcase --target ./ --namespace test
Service 'showcase' created in namespace 'test'.
tree ./
./ └── test └── ksvc └── showcase.yaml 2 directories, 1 file
cat test/ksvc/showcase.yaml
apiVersion: serving.knative.dev/v1 kind: Service metadata: creationTimestamp: null name: showcase namespace: test spec: template: metadata: annotations: client.knative.dev/user-image: quay.io/openshift-knative/showcase creationTimestamp: null spec: containers: - image: quay.io/openshift-knative/showcase name: "" resources: {} status: {}
kn service describe showcase --target ./ --namespace test
Name: showcase Namespace: test Age: URL: Revisions: Conditions: OK TYPE AGE REASON
kn service create -f test/ksvc/showcase.yaml
Creating service 'showcase' in namespace 'test': 0.058s The Route is still working to reflect the latest desired specification. 0.098s 0.168s Configuration "showcase" is waiting for a Revision to become ready. 23.377s 23.419s Ingress has not yet been reconciled. 23.534s Waiting for load balancer to be ready 23.723s Ready to serve. Service 'showcase' created to latest revision 'showcase-00001' is available at URL: http://showcase-test.apps.example.com
oc get ksvc <service_name>
NAME URL LATESTCREATED LATESTREADY READY REASON showcase http://showcase-default.example.com showcase-00001 showcase-00001 True
http showcase-default.example.com
https showcase-default.example.com
HTTP/1.1 200 OK Content-Type: application/json Server: Quarkus/2.13.7.Final-redhat-00003 Java/17.0.7 X-Config: {"sink":"http://localhost:31111","greet":"Ciao","delay":0} X-Version: v0.7.0-4-g23d460f content-length: 49 { "artifact": "knative-showcase", "greeting": "Ciao" }
curl http://showcase-default.example.com
artifact: knative-showcase
greeting: Ciao
https --verify=no showcase-default.example.com
HTTP/1.1 200 OK Content-Type: application/json Server: Quarkus/2.13.7.Final-redhat-00003 Java/17.0.7 X-Config: {"sink":"http://localhost:31111","greet":"Ciao","delay":0} X-Version: v0.7.0-4-g23d460f content-length: 49 { "artifact": "knative-showcase", "greeting": "Ciao" }
curl https://showcase-default.example.com --cacert <file>
artifact: knative-showcase
greeting: Ciao
apiVersion: operator.knative.dev/v1beta1 kind: KnativeServing metadata: name: knative-serving namespace: knative-serving spec: high-availability: replicas: 1 1 workloads: - name: activator replicas: 2 2 resources: - container: activator requests: cpu: 250m 3 memory: 60Mi 4 limits: cpu: 1000m memory: 600Mi - name: controller replicas: 1 5 resources: - container: controller requests: cpu: 10m memory: 100Mi limits: 6 cpu: 200m memory: 300Mi - name: webhook replicas: 2 resources: - container: webhook requests: cpu: 100m 7 memory: 60Mi limits: cpu: 200m memory: 200Mi podDisruptionBudgets: 8 - name: activator-pdb minAvailable: 1 - name: webhook-pdb minAvailable: 1
apiVersion: operator.knative.dev/v1beta1 kind: KnativeServing metadata: name: knative-serving namespace: knative-serving spec: high-availability: replicas: 2 1 workloads: - name: component-name 2 replicas: 2 3 resources: - container: container-name requests: cpu: 4 memory: limits: cpu: memory: podDisruptionBudgets: 5 - name: name-of-pod-disruption-budget minAvailable: 1
apiVersion: serving.knative.dev/v1 kind: Service metadata: name: showcase namespace: default spec: template: metadata: annotations: autoscaling.knative.dev/min-scale: "0"
kn service create <service_name> --image <image_uri> --scale-min <integer>
kn service create showcase --image quay.io/openshift-knative/showcase --scale-min 2
apiVersion: serving.knative.dev/v1 kind: Service metadata: name: showcase namespace: default spec: template: metadata: annotations: autoscaling.knative.dev/max-scale: "10"
kn service create <service_name> --image <image_uri> --scale-max <integer>
kn service create showcase --image quay.io/openshift-knative/showcase --scale-max 10
apiVersion: serving.knative.dev/v1 kind: Service metadata: name: showcase namespace: default spec: template: metadata: annotations: autoscaling.knative.dev/target: "200"
kn service create <service_name> --image <image_uri> --concurrency-target <integer>
kn service create showcase --image quay.io/openshift-knative/showcase --concurrency-target 50
apiVersion: serving.knative.dev/v1 kind: Service metadata: name: showcase namespace: default spec: template: spec: containerConcurrency: 50
kn service create <service_name> --image <image_uri> --concurrency-limit <integer>
kn service create showcase --image quay.io/openshift-knative/showcase --concurrency-limit 50
apiVersion: serving.knative.dev/v1 kind: Service metadata: name: showcase namespace: default spec: template: metadata: annotations: autoscaling.knative.dev/target-utilization-percentage: "70"
apiVersion: operator.knative.dev/v1beta1 kind: KnativeServing metadata: name: knative-serving spec: config: autoscaler: enable-scale-to-zero: "false" 1
apiVersion: operator.knative.dev/v1beta1 kind: KnativeServing metadata: name: knative-serving spec: config: autoscaler: scale-to-zero-grace-period: "30s" 1
apiVersion: serving.knative.dev/v1 kind: Service spec: template: spec: containers: - name: first-container 1 image: gcr.io/knative-samples/helloworld-go ports: - containerPort: 8080 2 - name: second-container 3 image: gcr.io/knative-samples/helloworld-java
spec: config: features: "multi-container-probing": enabled 1
oc apply -f <filename>
apiVersion: serving.knative.dev/v1 kind: Service spec: template: spec: containers: - name: first-container image: ghcr.io/knative/helloworld-go:latest ports: - containerPort: 8080 readinessProbe: 1 httpGet: port: 8080 - name: second-container image: gcr.io/knative-samples/helloworld-java readinessProbe: 2 httpGet: port: 8090
apiVersion: operator.knative.dev/v1beta1 kind: KnativeServing metadata: name: knative-serving spec: config: features: kubernetes.podspec-volumes-emptydir: enabled
spec: config: features: "kubernetes.podspec-persistent-volume-claim": enabled "kubernetes.podspec-persistent-volume-write": enabled
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: example-pv-claim namespace: my-ns spec: accessModes: - ReadWriteMany storageClassName: ocs-storagecluster-cephfs resources: requests: storage: 1Gi
apiVersion: serving.knative.dev/v1 kind: Service metadata: namespace: my-ns spec: template: spec: containers: volumeMounts: 1 - mountPath: /data name: mydata readOnly: false volumes: - name: mydata persistentVolumeClaim: 2 claimName: example-pv-claim readOnly: false 3
apiVersion: operator.knative.dev/v1beta1 kind: KnativeServing metadata: name: knative-serving spec: config: features: kubernetes.podspec-init-containers: enabled
apiVersion: serving.knative.dev/v1 kind: Service spec: template: spec: containers: - name: first-container image: <image> ports: - containerPort: 8080 # startupProbe: 1 httpGet: port: 8080 path: "/" - name: second-container image: <image> # startupProbe: 2 httpGet: port: 8081 path: "/"
apiVersion: serving.knative.dev/v1 kind: Service spec: template: metadata: annotations: serving.knative.dev/progress-deadline: "60s" spec: containers: - image: ghcr.io/knative/helloworld-go:latest
oc -n knative-serving create secret generic custom-secret --from-file=<secret_name>.crt=<path_to_certificate>
apiVersion: operator.knative.dev/v1beta1 kind: KnativeServing metadata: name: knative-serving namespace: knative-serving spec: controller-custom-certs: name: custom-secret type: Secret
apiVersion: operator.knative.dev/v1beta1 kind: KnativeServing metadata: name: knative-serving spec: config: deployment: registriesSkippingTagResolving: "registry.example.com, another.registry.com"
apiVersion: operator.knative.dev/v1beta1 kind: KnativeServing metadata: name: knative-serving spec: config: deployment: runtime-class-name: | kata: {} gvisor: selector: my-label: selector
apiVersion: operator.knative.dev/v1beta1 kind: KnativeServing metadata: name: knative-serving spec: config: deployment: progressDeadline: "60s"
oc get cm kourier-bootstrap -n knative-serving-ingress -o yaml
Name: kourier-bootstrap Namespace: knative-serving-ingress Labels: app.kubernetes.io/component=net-kourier app.kubernetes.io/name=knative-serving app.kubernetes.io/version=release-v1.10 networking.knative.dev/ingress-provider=kourier serving.knative.openshift.io/ownerName=knative-serving serving.knative.openshift.io/ownerNamespace=knative-serving Annotations: manifestival: new
dynamic_resources: ads_config: transport_api_version: V3 api_type: GRPC rate_limit_settings: {} grpc_services: - envoy_grpc: {cluster_name: xds_cluster} cds_config: resource_api_version: V3 ads: {} lds_config: resource_api_version: V3 ads: {} node: cluster: kourier-knative id: 3scale-kourier-gateway static_resources: listeners: - name: stats_listener address: socket_address: address: 0.0.0.0 port_value: 9000 filter_chains: - filters: - name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager stat_prefix: stats_server http_filters: - name: envoy.filters.http.router typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router route_config: virtual_hosts: - name: admin_interface domains: - "*" routes: - match: safe_regex: regex: '/(certs|stats(/prometheus)?|server_info|clusters|listeners|ready)?' headers: - name: ':method' string_match: exact: GET route: cluster: service_stats clusters: - name: service_stats connect_timeout: 0.250s type: static load_assignment: cluster_name: service_stats endpoints: lb_endpoints: endpoint: address: pipe: path: /tmp/envoy.admin - name: xds_cluster # This keepalive is recommended by envoy docs. # https://www.envoyproxy.io/docs/envoy/latest/api-docs/xds_protocol typed_extension_protocol_options: envoy.extensions.upstreams.http.v3.HttpProtocolOptions: "@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicit_http_config: http2_protocol_options: connection_keepalive: interval: 30s timeout: 5s connect_timeout: 1s load_assignment: cluster_name: xds_cluster endpoints: lb_endpoints: endpoint: address: socket_address: address: "net-kourier-controller.knative-serving-ingress.svc.cluster.local." port_value: 18000 type: STRICT_DNS admin: access_log: - name: envoy.access_loggers.stdout typed_config: "@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog address: pipe: path: /tmp/envoy.admin layered_runtime: layers: - name: static-layer static_layer: envoy.reloadable_features.override_request_timeout_by_gateway_timeout: false
Events: <none>
apiVersion: operator.knative.dev/v1beta1 kind: KnativeServing metadata: name: knative-serving namespace: knative-serving spec: config: network: ingress-class: kourier.ingress.networking.knative.dev ingress: kourier: bootstrap-configmap: my-configmap enabled: true
pipe: path: /tmp/envoy.admin
socket_address: 1 address: 127.0.0.1 port_value: 9901
clusters: - name: service_stats connect_timeout: 0.250s type: static load_assignment: cluster_name: service_stats endpoints: lb_endpoints: endpoint: address: socket_address: address: 127.0.0.1 port_value: 9901
admin: access_log: - name: envoy.access_loggers.stdout typed_config: "@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog address: socket_address: address: 127.0.0.1 port_value: 9901
kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: deny-by-default namespace: example-namespace spec: podSelector: ingress: []
oc label namespace knative-serving knative.openshift.io/system-namespace=true
oc label namespace knative-serving-ingress knative.openshift.io/system-namespace=true
oc label namespace knative-eventing knative.openshift.io/system-namespace=true
oc label namespace knative-kafka knative.openshift.io/system-namespace=true
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: <network_policy_name> 1 namespace: <namespace> 2 spec: ingress: - from: - namespaceSelector: matchLabels: knative.openshift.io/system-namespace: "true" podSelector: {} policyTypes: - Ingress
apiVersion: operator.knative.dev/v1beta1 kind: KnativeServing metadata: name: knative-serving namespace: knative-serving spec: config: defaults: revision-timeout-seconds: "300"
apiVersion: serving.knative.dev/v1 kind: Service metadata: namespace: my-ns spec: template: spec: timeoutSeconds: 300 containers: - image: ghcr.io/knative/helloworld-go:latest
If this value is increased, the activator `terminationGracePeriodSeconds` should also be increased to prevent in-flight requests being disrupted.
apiVersion: operator.knative.dev/v1beta1 kind: KnativeServing metadata: name: knative-serving namespace: knative-serving spec: config: defaults: max-revision-timeout-seconds: "600"
Error from server (InternalError): error when applying patch: {"metadata":{"annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"serving.knative.dev/v1\",\"kind\":\"Route\",\"metadata\":{\"annotations\":{},\"name\":\"route-example\",\"namespace\":\"default\"},\"spec\":{\"traffic\":[{\"configurationName\":\"configuration-example\",\"percent\":50}]}}\n"}},"spec":{"traffic":[{"configurationName":"configuration-example","percent":50}]}} to: &{0xc421d98240 0xc421e77490 default route-example STDIN 0xc421db0488 264682 false} for: "STDIN": Internal error occurred: admission webhook "webhook.knative.dev" denied the request: mutation failed: The route must have traffic percent sum equal to 100. ERROR: Non-zero return code '1' from command: Process exited with status 1
oc get pods
NAME READY STATUS RESTARTS AGE configuration-example-00001-deployment-659747ff99-9bvr4 2/2 Running 0 3h configuration-example-00002-deployment-5f475b7849-gxcht 1/2 CrashLoopBackOff 2 36s
oc get pod <pod_name> --output yaml
oc get configuration <configuration_name> --output jsonpath="{.status.latestCreatedRevisionName}"
oc get revision <revision-name> --output yaml
oc get svc -n istio-system istio-ingressgateway
oc describe svc istio-ingressgateway -n istio-system
oc get route <route_name> --output yaml
oc get ingresses.networking.internal.knative.dev -o=custom-columns='NAME:.metadata.name,LABELS:.metadata.labels'
NAME LABELS helloworld-go map[serving.knative.dev/route:helloworld-go serving.knative.dev/routeNamespace:default serving.knative.dev/service:helloworld-go]
oc get ingresses.networking.internal.knative.dev <ingress_name> --output yaml
oc get virtualservice -l networking.internal.knative.dev/ingress=<ingress_name> -n <ingress_namespace> --output yaml
apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: knative-serving-selfsigned-issuer spec: selfSigned: {}
oc apply -f <filename>
apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: knative-serving-selfsigned-ca namespace: cert-manager 1 spec: secretName: knative-serving-ca 2 isCA: true commonName: selfsigned-ca privateKey: algorithm: ECDSA size: 256 issuerRef: name: knative-serving-selfsigned-issuer kind: ClusterIssuer group: cert-manager.io
oc apply -f <filename>
apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: knative-serving-ca-issuer spec: ca: secretName: knative-serving-ca 1
oc apply -f <filename>
apiVersion: operator.knative.dev/v1beta1 kind: KnativeServing metadata: name: knative-serving namespace: knative-serving spec: config: certmanager: clusterLocalIssuerRef: | kind: ClusterIssuer name: knative-serving-ca-issuer 1 systemInternalIssuerRef: | kind: ClusterIssuer name: knative-serving-ca-issuer 2 network: cluster-local-domain-tls: Enabled 3 system-internal-tls: Enabled 4
oc apply -f <filename>
apiVersion: operator.openshift.io/v1 kind: IngressController spec: defaultCertificate: name: ca-ingress-cert
spec: config: network: system-internal-tls: Enabled openshift-ingress-default-certificate: "ca-ingress-cert"
oc rollout restart deploy/controller -n knative-serving
oc rollout restart deploy/activator -n knative-serving
apiVersion: v1 data: cacerts.pem: | 1 -----BEGIN CERTIFICATE----- MIIDDTCCAfWgAwIBAgIQMQuip05h7NLQq2TB+j9ZmTANBgkqhkiG9w0BAQsFADAW MRQwEgYDVQQDEwtrbmF0aXZlLmRldjAeFw0yMzExMjIwOTAwNDhaFw0yNDAyMjAw OTAwNDhaMBYxFDASBgNVBAMTC2tuYXRpdmUuZGV2MIIBIjANBgkqhkiG9w0BAQEF AAOCAQ8AMIIBCgKCAQEA3clC3CV7sy0TpUKNuTku6QmP9z8JUCbLCPCLACCUc1zG FEokqOva6TakgvAntXLkB3TEsbdCJlNm6qFbbko6DBfX6rEggqZs40x3/T+KH66u 4PvMT3fzEtaMJDK/KQOBIvVHrKmPkvccUYK/qWY7rgBjVjjLVSJrCn4dKaEZ2JNr Fd0KNnaaW/dP9/FvviLqVJvHnTMHH5qyRRr1kUGTrc8njRKwpHcnUdauiDoWRKxo Zlyy+MhQfdbbyapX984WsDjCvrDXzkdGgbRNAf+erl6yUm6pHpQhyFFo/zndx6Uq QXA7jYvM2M3qCnXmaFowidoLDsDyhwoxD7WT8zur/QIDAQABo1cwVTAOBgNVHQ8B Af8EBAMCAgQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUwAwEB/zAd BgNVHQ4EFgQU7p4VuECNOcnrP9ulOjc4J37Q2VUwDQYJKoZIhvcNAQELBQADggEB AAv26Vnk+ptQrppouF7yHV8fZbfnehpm07HIZkmnXO2vAP+MZJDNrHjy8JAVzXjt +OlzqAL0cRQLsUptB0btoJuw23eq8RXgJo05OLOPQ2iGNbAATQh2kLwBWd/CMg+V KJ4EIEpF4dmwOohsNR6xa/JoArIYH0D7gh2CwjrdGZr/tq1eMSL+uZcuX5OiE44A 2oXF9/jsqerOcH7QUMejSnB8N7X0LmUvH4jAesQgr7jo1JTOBs7GF6wb+U76NzFa 8ms2iAWhoplQ+EHR52wffWb0k6trXspq4O6v/J+nq9Ky3vC36so+G1ZFkMhCdTVJ ZmrBsSMWeT2l07qeei2UFRU= -----END CERTIFICATE----- kind: ConfigMap metadata: labels: networking.knative.dev/trust-bundle: "true" name: knative-bundle 2 namespace: knative-serving
apiVersion: serving.knative.dev/v1 kind: Service metadata: name: test-webapp namespace: test-namespace spec: template: spec: containers: - image: docker.io/openshift/hello-openshift env: - name: RESPONSE value: "Hello Serverless!"
oc apply -f <filename>
oc get ksvc -n test-namespace -o yaml
apiVersion: serving.knative.dev/v1 kind: Service metadata: name: test-webapp namespace: test-namespace spec: status: address: # cluster-local-domain: url: https://helloworld.test.svc.cluster.local 1
oc logs your-pod -n test-namespace -c queue-proxy | grep -E 'certDir|Certificate|tls'
{"severity":"INFO","timestamp":"2024-01-03T07:07:32.892810888Z","logger":"queueproxy","caller":"certificate/watcher.go:62","message":"Starting to watch the following directories for changes{certDir 15 0 /var/lib/knative/certs <nil>} {keyDir 15 0 /var/lib/knative/certs <nil>}","commit":"86420f2-dirty","knative.dev/key":"first/helloworld-00001","knative.dev/pod":"helloworld-00001-deployment-75fbb7d488-qgmxx"} {"severity":"INFO","timestamp":"2024-01-03T07:07:32.89397512Z","logger":"queueproxy","caller":"certificate/watcher.go:131","message":"Certificate and/or key have changed on disk and were reloaded.","commit":"86420f2-dirty","knative.dev/key":"first/helloworld-00001","knative.dev/pod":"helloworld-00001-deployment-75fbb7d488-qgmxx"} {"severity":"INFO","timestamp":"2024-01-03T07:07:32.894232939Z","logger":"queueproxy","caller":"sharedmain/main.go:282","message":"Starting tls server admin:8022","commit":"86420f2-dirty","knative.dev/key":"first/helloworld-00001","knative.dev/pod":"helloworld-00001-deployment-75fbb7d488-qgmxx"} {"severity":"INFO","timestamp":"2024-01-03T07:07:32.894268548Z","logger":"queueproxy","caller":"sharedmain/main.go:282","message":"Starting tls server main:8112","commit":"86420f2-dirty","knative.dev/key":"first/helloworld-00001","knative.dev/pod":"helloworld-00001-deployment-75fbb7d488-qgmxx"}
apiVersion: serving.knative.dev/v1 kind: Service metadata: name: example-service namespace: default spec: traffic: - latestRevision: true percent: 100 status: traffic: - percent: 100 revisionName: example-service
apiVersion: serving.knative.dev/v1 kind: Service metadata: name: example-service namespace: default spec: traffic: - tag: current revisionName: example-service percent: 100 - tag: latest latestRevision: true percent: 0
apiVersion: serving.knative.dev/v1 kind: Service metadata: name: example-service namespace: default spec: traffic: - tag: current revisionName: example-service-1 percent: 50 - tag: candidate revisionName: example-service-2 percent: 50 - tag: latest latestRevision: true percent: 0
kn service update <service_name> --traffic <revision>=<percentage>
kn service update showcase --traffic @latest=20,stable=80
kn service update showcase --traffic @latest=10,stable=60
kn service update <service_name> --tag @latest=example-tag
kn service update <service_name> --untag example-tag
oc get ksvc <service_name> -o=jsonpath='{.status.latestCreatedRevisionName}'
oc get ksvc showcase -o=jsonpath='{.status.latestCreatedRevisionName}'
showcase-00001
spec: traffic: - revisionName: <first_revision_name> percent: 100 # All traffic goes to this revision
oc get ksvc <service_name>
oc get ksvc <service_name> -o=jsonpath='{.status.latestCreatedRevisionName}'
spec: traffic: - revisionName: <first_revision_name> percent: 100 # All traffic is still being routed to the first revision - revisionName: <second_revision_name> percent: 0 # No traffic is routed to the second revision tag: v2 # A named route
oc get ksvc <service_name> --output jsonpath="{.status.traffic[*].url}"
spec: traffic: - revisionName: <first_revision_name> percent: 50 - revisionName: <second_revision_name> percent: 50 tag: v2
spec: traffic: - revisionName: <first_revision_name> percent: 0 - revisionName: <second_revision_name> percent: 100 tag: v2
apiVersion: serving.knative.dev/v1 kind: Service metadata: name: <service_name> labels: <label_name>: <label_value> annotations: <annotation_name>: <annotation_value>
kn service create <service_name> --image=<image> --annotation <annotation_name>=<annotation_value> --label <label_value>=<label_value>
oc get routes.route.openshift.io -l serving.knative.openshift.io/ingressName=<service_name> \ 1 -l serving.knative.openshift.io/ingressNamespace=<service_namespace> \ 2 -n knative-serving-ingress -o yaml | grep -e "<label_name>: \"<label_value>\"" -e "<annotation_name>: <annotation_value>" 3
apiVersion: serving.knative.dev/v1 kind: Service metadata: name: <service_name> annotations: serving.knative.openshift.io/disableRoute: "true" spec: template: spec: containers: - image: <image>
oc apply -f <filename>
kn service create <service_name> --image=gcr.io/knative-samples/helloworld-go --annotation serving.knative.openshift.io/disableRoute=true
USD oc get routes.route.openshift.io -l serving.knative.openshift.io/ingressName=USDKSERVICE_NAME -l serving.knative.openshift.io/ingressNamespace=USDKSERVICE_NAMESPACE -n knative-serving-ingress
No resources found in knative-serving-ingress namespace.
apiVersion: route.openshift.io/v1 kind: Route metadata: annotations: haproxy.router.openshift.io/timeout: 600s 1 name: <route_name> 2 namespace: knative-serving-ingress 3 spec: host: <service_host> 4 port: targetPort: http2 to: kind: Service name: kourier weight: 100 tls: insecureEdgeTerminationPolicy: Allow termination: edge 5 key: |- -----BEGIN PRIVATE KEY----- [...] -----END PRIVATE KEY----- certificate: |- -----BEGIN CERTIFICATE----- [...] -----END CERTIFICATE----- caCertificate: |- -----BEGIN CERTIFICATE----- [...] -----END CERTIFICATE---- wildcardPolicy: None
oc apply -f <filename>
spec: config: network: default-external-scheme: "https"
spec: config: network: default-external-scheme: "http"
oc label ksvc <service_name> networking.knative.dev/visibility=cluster-local
oc get ksvc
NAME URL LATESTCREATED LATESTREADY READY REASON hello http://hello.default.svc.cluster.local hello-tx2g7 hello-tx2g7 True
export san="knative"
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=Example/CN=Example' -keyout ca.key -out ca.crt
openssl req -out tls.csr -newkey rsa:2048 -nodes -keyout tls.key -subj "/CN=Example/O=Example" -addext "subjectAltName = DNS:USDsan"
openssl x509 -req -extfile <(printf "subjectAltName=DNS:USDsan") -days 365 -in tls.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out tls.crt
oc create -n knative-serving-ingress secret tls server-certs --key=tls.key --cert=tls.crt --dry-run=client -o yaml | oc apply -f -
spec: config: kourier: cluster-cert-secret: server-certs
spec: ingress: kourier: service-type: ClusterIP
spec: ingress: kourier: service-type: LoadBalancer
oc annotate knativeserving <your_knative_CR> -n knative-serving serverless.openshift.io/default-enable-http2=true
oc get svc -n knative-serving-ingress kourier -o jsonpath="{.spec.ports[0].appProtocol}"
h2c
import "google.golang.org/grpc" grpc.Dial( YOUR_URL, 1 grpc.WithTransportCredentials(insecure.NewCredentials())), 2 )
apiVersion: operator.openshift.io/v1 kind: IngressController metadata: name: ingress-dev 1 namespace: openshift-ingress-operator spec: routeSelector: matchLabels: router: dev 2 domain: "dev.serverless.cluster.example.com" 3 # --- apiVersion: operator.openshift.io/v1 kind: IngressController metadata: name: ingress-prod 4 namespace: openshift-ingress-operator spec: routeSelector: matchLabels: router: prod 5 domain: "prod.serverless.cluster.example.com" 6 #
spec: config: domain: 1 dev.serverless.cluster.example.com: | selector: router: dev prod.serverless.cluster.example.com: | selector: router: prod #
apiVersion: serving.knative.dev/v1 kind: Service metadata: name: hello-dev labels: router: dev 1 spec: template: spec: containers: - image: docker.io/openshift/hello-openshift --- apiVersion: serving.knative.dev/v1 kind: Service metadata: name: hello-prod labels: router: prod 2 spec: template: spec: containers: - image: docker.io/openshift/hello-openshift #
oc get ksvc
NAME URL LATESTCREATED LATESTREADY READY REASON hello-dev https://hello-dev-default.dev.serverless.cluster.example.com hello-dev-00001 hello-dev-00001 True hello-prod https://hello-prod-default.prod.serverless.cluster.example.com hello-prod-00001 hello-prod-00001 True
oc get route -n knative-serving-ingress -o jsonpath='{range .items[*]}{@.metadata.name}{" "}{@.spec.host}{" "}{@.status.ingress[*].routerName}{"\n"}{end}'
route-19e6628b-77af-4da0-9b4c-1224934b2250-323461616533 hello-prod-default.prod.serverless.cluster.example.com ingress-prod route-cb5085d9-b7da-4741-9a56-96c88c6adaaa-373065343266 hello-dev-default.dev.serverless.cluster.example.com ingress-dev
apiVersion: operator.knative.dev/v1beta1 kind: KnativeServing metadata: name: knative-serving spec: config: network: httpProtocol: "redirected"
apiVersion: serving.knative.dev/v1 kind: Service metadata: name: example namespace: default annotations: networking.knative.dev/http-protocol: "redirected" spec:
apiVersion: serving.knative.dev/v1 kind: Service metadata: name: example-service namespace: default spec: template: metadata: annotations: features.knative.dev/http-full-duplex: "Enabled"
apiVersion: serving.knative.dev/v1 kind: Service metadata: name: <service_name> spec: template: metadata: annotations: sidecar.istio.io/inject: "true" 1 sidecar.istio.io/rewriteAppHTTPProbers: "true" 2
oc apply -f <filename>
apiVersion: security.istio.io/v1beta1 kind: RequestAuthentication metadata: name: jwt-example namespace: <namespace> spec: jwtRules: - issuer: testing@secure.istio.io jwksUri: https://raw.githubusercontent.com/istio/istio/release-1.8/security/tools/jwt/samples/jwks.json
oc apply -f <filename>
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: allowlist-by-paths namespace: <namespace> spec: action: ALLOW rules: - to: - operation: paths: - /metrics 1 - /healthz 2
oc apply -f <filename>
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: require-jwt namespace: <namespace> spec: action: ALLOW rules: - from: - source: requestPrincipals: ["testing@secure.istio.io/testing@secure.istio.io"]
oc apply -f <filename>
curl http://hello-example-1-default.apps.mycluster.example.com/
RBAC: access denied
TOKEN=USD(curl https://raw.githubusercontent.com/istio/istio/release-1.8/security/tools/jwt/samples/demo.jwt -s) && echo "USDTOKEN" | cut -d '.' -f2 - | base64 --decode -
curl -H "Authorization: Bearer USDTOKEN" http://hello-example-1-default.apps.example.com
Hello OpenShift!
apiVersion: serving.knative.dev/v1 kind: Service metadata: name: <service_name> spec: template: metadata: annotations: sidecar.istio.io/inject: "true" 1 sidecar.istio.io/rewriteAppHTTPProbers: "true" 2
oc apply -f <filename>
apiVersion: authentication.istio.io/v1alpha1 kind: Policy metadata: name: default namespace: <namespace> spec: origins: - jwt: issuer: testing@secure.istio.io jwksUri: "https://raw.githubusercontent.com/istio/istio/release-1.6/security/tools/jwt/samples/jwks.json" triggerRules: - excludedPaths: - prefix: /metrics 1 - prefix: /healthz 2 principalBinding: USE_ORIGIN
oc apply -f <filename>
curl http://hello-example-default.apps.mycluster.example.com/
Origin authentication failed.
TOKEN=USD(curl https://raw.githubusercontent.com/istio/istio/release-1.6/security/tools/jwt/samples/demo.jwt -s) && echo "USDTOKEN" | cut -d '.' -f2 - | base64 --decode -
curl http://hello-example-default.apps.mycluster.example.com/ -H "Authorization: Bearer USDTOKEN"
Hello OpenShift!
apiVersion: operator.knative.dev/v1beta1 kind: KnativeServing metadata: name: knative-serving namespace: knative-serving spec: config: deployment: "kube-rbac-proxy-cpu-request": "10m" 1 "kube-rbac-proxy-memory-request": "20Mi" 2 "kube-rbac-proxy-cpu-limit": "100m" 3 "kube-rbac-proxy-memory-limit": "100Mi" 4
apiVersion: operator.knative.dev/v1beta1 kind: KnativeServing metadata: name: knative-serving namespace: knative-serving spec: workloads: - name: net-kourier-controller env: - container: controller envVars: - name: KUBE_API_BURST value: "200" 1 - name: KUBE_API_QPS value: "200" 2
apiVersion: serving.knative.dev/v1beta1 kind: DomainMapping metadata: name: <domain_name> 1 namespace: <namespace> 2 spec: ref: name: <target_name> 3 kind: <target_type> 4 apiVersion: serving.knative.dev/v1
apiVersion: serving.knative.dev/v1beta1 kind: DomainMapping metadata: name: example.com namespace: default spec: ref: name: showcase kind: Service apiVersion: serving.knative.dev/v1
apiVersion: serving.knative.dev/v1beta1 kind: DomainMapping metadata: name: example.com namespace: default spec: ref: name: example-route kind: Route apiVersion: serving.knative.dev/v1
oc apply -f <filename>
kn domain create <domain_mapping_name> --ref <target_name>
kn domain create example.com --ref showcase
kn domain create <domain_mapping_name> --ref <ksvc:service_name:service_namespace>
kn domain create example.com --ref ksvc:showcase:example-namespace
kn domain create <domain_mapping_name> --ref <kroute:route_name>
kn domain create example.com --ref kroute:example-route
apiVersion: serving.knative.dev/v1beta1 kind: DomainMapping metadata: name: <domain_name> 1 namespace: <namespace> 2 spec: ref: name: <target_name> 3 kind: <target_type> 4 apiVersion: serving.knative.dev/v1
apiVersion: serving.knative.dev/v1beta1 kind: DomainMapping metadata: name: custom-ksvc-domain.example.com namespace: default spec: ref: name: showcase kind: Service apiVersion: serving.knative.dev/v1
curl custom-ksvc-domain.example.com
artifact: knative-showcase
greeting: Welcome
spec: config: kourier: cipher-suites: ECDHE-ECDSA-AES128-GCM-SHA256,ECDHE-ECDSA-CHACHA20-POLY1305
oc create secret tls <tls_secret_name> --cert=<path_to_certificate_file> --key=<path_to_key_file>
oc label secret <tls_secret_name> networking.internal.knative.dev/certificate-uid="<id>"
apiVersion: serving.knative.dev/v1beta1 kind: DomainMapping metadata: name: <domain_name> namespace: <namespace> spec: ref: name: <service_name> kind: Service apiVersion: serving.knative.dev/v1 TLS block specifies the secret to be used tls: secretName: <tls_secret_name>
oc get domainmapping <domain_name>
NAME URL READY REASON example.com https://example.com True
curl https://<domain_name>
apiVersion: operator.knative.dev/v1beta1 kind: KnativeServing metadata: name: knative-serving namespace: knative-serving spec: workloads: - env: - container: controller envVars: - name: ENABLE_SECRET_INFORMER_FILTERING_BY_CERT_UID value: 'false' name: net-kourier-controller
apiVersion: operator.knative.dev/v1beta1 kind: KnativeServing metadata: name: knative-serving namespace: knative-serving spec: high-availability: replicas: 3
apiVersion: operator.knative.dev/v1beta1 kind: KnativeServing metadata: name: knative-serving namespace: knative-serving spec: high-availability: replicas: 3 workloads: - name: webhook replicas: 4
oc get hpa -n knative-serving
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE activator Deployment/activator 0%/100% 3 22 3 2m24s webhook Deployment/webhook 2%/100% 4 8 4 2m23s
apiVersion: operator.knative.dev/v1beta1 kind: KnativeServing metadata: name: knative-serving namespace: knative-serving spec: podDisruptionBudgets: - name: activator-pdb minAvailable: 70%
apiVersion: operator.knative.dev/v1beta1 kind: KnativeServing metadata: name: ks namespace: knative-serving spec: high-availability: replicas: 2 workloads: - name: net-kourier-controller readinessProbes: 1 - container: controller timeoutSeconds: 10 - name: webhook resources: - container: webhook requests: cpu: 300m memory: 60Mi limits: cpu: 1000m memory: 1000Mi replicas: 3 labels: example-label: label annotations: example-annotation: annotation nodeSelector: disktype: hdd
apiVersion: serving.knative.dev/v1 kind: Service metadata: name: example-service namespace: default spec: template: metadata: annotations: queue.sidecar.serving.knative.dev/cpu-resource-request: "1" queue.sidecar.serving.knative.dev/cpu-resource-limit: "2" queue.sidecar.serving.knative.dev/memory-resource-request: "1Gi" queue.sidecar.serving.knative.dev/memory-resource-limit: "2Gi" queue.sidecar.serving.knative.dev/ephemeral-storage-resource-request: "400Mi" queue.sidecar.serving.knative.dev/ephemeral-storage-resource-limit: "450Mi"