knative-extensions / net-kourier

Purpose-built Knative Ingress implementation using just Envoy with no additional CRDs
Apache License 2.0
290 stars 80 forks source link

Kourier

This component is GA

Kourier is an Ingress for Knative Serving. Kourier is a lightweight alternative for the Istio ingress as its deployment consists only of an Envoy proxy and a control plane for it.

Kourier is passing the knative serving e2e and conformance tests: Kourier Testgrid.

Getting started

kubectl apply -f https://github.com/knative/serving/releases/latest/download/serving-crds.yaml
kubectl apply -f https://github.com/knative/serving/releases/latest/download/serving-core.yaml
kubectl apply -f https://github.com/knative/net-kourier/releases/latest/download/kourier.yaml
kubectl patch configmap/config-network \
  -n knative-serving \
  --type merge \
  -p '{"data":{"ingress.class":"kourier.ingress.networking.knative.dev"}}'
kubectl patch configmap/config-domain \
  -n knative-serving \
  --type merge \
  -p '{"data":{"127.0.0.1.nip.io":""}}'
cat <<-EOF | kubectl apply -f -
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: helloworld-go
spec:
  template:
    spec:
      containers:
      - image: gcr.io/knative-samples/helloworld-go
        env:
        - name: TARGET
          value: Go Sample v1
EOF
kubectl port-forward --namespace kourier-system $(kubectl get pod -n kourier-system -l "app=3scale-kourier-gateway" --output=jsonpath="{.items[0].metadata.name}") 8080:8080 19000:9000 8443:8443

curl -v -H "Host: helloworld-go.default.127.0.0.1.nip.io" http://localhost:8080

Deployment

By default, the deployment of the Kourier components is split between two different namespaces:

To change the Kourier gateway namespace, you will need to:

Features

Setup TLS certificate

Create a secret containing your TLS certificate and Private key:

kubectl create secret tls ${CERT_NAME} --key ${KEY_FILE} --cert ${CERT_FILE}

Add the following env vars to net-kourier-controller in the "kourier" container :

CERTS_SECRET_NAMESPACE: ${NAMESPACES_WHERE_THE_SECRET_HAS_BEEN_CREATED}
CERTS_SECRET_NAME: ${CERT_NAME}

Cipher Suites

You can specify the cipher suites for TLS external listener. To specify the cipher suites you want to allow, run the following command to patch config-kourier ConfigMap:

kubectl -n "knative-serving" patch configmap/config-kourier \
  --type merge \
  -p '{"data":{"cipher-suites":"ECDHE-ECDSA-AES128-GCM-SHA256,ECDHE-ECDSA-CHACHA20-POLY1305"}}'

The default uses the default cipher suites of the envoy version.

External Authorization Configuration

If you want to enable the external authorization support you can set these ENV vars in the net-kourier-controller deployment:

* Required

Proxy Protocol Configuration

Note: this is an experimental/alpha feature.

To enable proxy protocol feature, run the following command to patch config-kourier ConfigMap:

kubectl patch configmap/config-kourier \
  -n knative-serving \
  --type merge \
  -p '{"data":{"enable-proxy-protocol":"true"}}'

Ensure that the file was updated successfully:

kubectl get configmap config-kourier --namespace knative-serving --output yaml

LoadBalancer configuration:

We need to:

Example (Scaleway provider):

apiVersion: v1
kind: Service
metadata:
  name: kourier
  namespace: kourier-system
  annotations:
    service.beta.kubernetes.io/scw-loadbalancer-proxy-protocol-v2: '*'
    service.beta.kubernetes.io/scw-loadbalancer-use-hostname: "true"
  labels:
    networking.knative.dev/ingress-provider: kourier
spec:
  ports:
    - name: http2
      port: 80
      protocol: TCP
      targetPort: 8080
    - name: https
      port: 443
      protocol: TCP
      targetPort: 8443
  selector:
    app: 3scale-kourier-gateway
  externalTrafficPolicy: Local
  type: LoadBalancer

Tips

Domain Mapping is configured to explicitly use http2 protocol only. This behaviour can be disabled by adding the following annotation to the Domain Mapping resource

kubectl annotate domainmapping <domain_mapping_name> kourier.knative.dev/disable-http2=true --namespace <namespace>

A good use case for this configuration is DomainMapping with Websocket

Note: This annotation is an experimental/alpha feature. We may change the annotation name in the future.

License

Apache 2.0 License