Kourier 是一个基于 Envoy 架构实现的轻量级网关,是 Knative 社区提供的开源网关实现,提供 Knative Revisions 流量分发,支持 gRPC 服务、超时和重试、TLS 证书和外部认证授权等功能。
介绍
Kourier 已达到 GA 状态
Kourier 是 Knative Serving 的一个 Ingress。Kourier 是 Istio Ingress 的一个轻量级替代方案,因为它部署时只包含一个 Envoy 代理和一个用于它的控制平面。
Kourier 正在通过 Knative Serving 的端到端(e2e)和一致性测试:Kourier Testgrid。
功能
- 在 Knative 修订版本(revisions)之间进行流量拆分
- 自动更新随着扩展而变化的端点
- 支持 gRPC 服务
- 支持超时和重试
- 支持 TLS
- 支持密码套件
- 支持外部授权
- 支持 Proxy Protocol(一项实验性/Alpha 功能)
特点
- 轻量级:相比 Istio,Kourier 的部署更为轻量,减少了资源消耗和管理复杂度
- 高性能:基于 Envoy Proxy,Kourier 提供了高性能的流量管理和路由能力
- 易用性:Kourier 的安装和配置非常简单,适合快速上手和部署
- 灵活性:支持多种高级功能,如流量拆分、自动更新端点、gRPC 支持、TLS 配置等
- 实验性功能:Kourier 还提供了一些实验性功能,如 Proxy Protocol 支持,为用户提供更多选择
部署
默认情况下,Kourier 组件的部署被分割到两个不同的命名空间:
- Kourier 控制平面部署在
knative-serving
命名空间
- Kourier 网关部署在
kourier-system
命名空间
要更改 Kourier 网关的命名空间,需要:
-
修改 config/
目录下的文件,将所有带有 kourier-system
的命名空间字段替换为所需的命名空间
-
在 kourier-control 部署中,将 KOURIER_GATEWAY_NAMESPACE
环境变量设置为新的命名空间
-
安装 Knative Serving,最好不要包含 Istio:
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
- 配置 Knative Serving 以使用正确的 “ingress.class”:
kubectl patch configmap/config-network \
-n knative-serving \
--type merge \
-p '{"data":{"ingress.class":"kourier.ingress.networking.knative.dev"}}'
- (可选)设置你想要的域名(将 127.0.0.1.nip.io 替换为你偏好的域名):
kubectl patch configmap/config-domain \
-n knative-serving \
--type merge \
-p '{"data":{"127.0.0.1.nip.io":""}}'
- (可选)部署一个示例的 hello world 应用:
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
- (可选)为了测试目的,你可以使用端口转发(port-forwarding)从你的机器向 Kourier 发出请求:
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
使用
设置 TLS 证书
创建证书:
openssl genrsa -out tls.key 4096
openssl req -subj "/CN=*.xiexianbin.cn/L=*.xiexianbin.cn" -sha256 -new -key tls.key -out tls.csr
echo subjectAltName = DNS:default.xiexianbin.cn,DNS:*.default.xiexianbin.cn > extfile.cnf
openssl x509 -req -days 3650 -sha256 -in tls.csr -signkey tls.key -out tls.crt -extfile extfile.cnf
创建一个包含 TLS 证书和私钥的 Secret:
kubectl create secret tls ${CERT_NAME} --key ${KEY_FILE} --cert ${CERT_FILE}
kubectl -n knative-serving create secret tls kourier-cert --key tls.key --cert tls.crt
在 “kourier” 容器中,为 net-kourier-controller
添加以下环境变量(kubectl -n knative-serving edit deployment net-kourier-controller
):
...
spec:
containers:
- env:
- name: CERTS_SECRET_NAMESPACE
value: ${NAMESPACES_WHERE_THE_SECRET_HAS_BEEN_CREATED-knative-serving}
- name: CERTS_SECRET_NAME
value: ${CERT_NAME-kourier-cert}
...
访问:
curl -H "host: helloworld-go.default.127.0.0.1.nip.io" -k --cert tls.crt --key tls.key http://localhost:8080 -v
密码套件/Cipher Suites
可以为外部 TLS 监听器指定密码套件。要指定你想要允许的密码套件,请运行以下命令来修补 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"}}'
默认情况下,它使用 Envoy 版本的默认密码套件。
外部授权配置
如果你想启用外部授权支持,可以在 net-kourier-controller
部署中设置以下环境变量:
KOURIER_EXTAUTHZ_HOST*
:外部授权服务及其端口,例如 my-auth:2222
。
KOURIER_EXTAUTHZ_FAILUREMODEALLOW*
:如果外部授权服务宕机,是否允许流量通过。接受 true
或 false
。
KOURIER_EXTAUTHZ_PROTOCOL
:用于查询外部授权服务的协议。可以是:grpc
、http
或 https
。默认为 grpc
。
KOURIER_EXTAUTHZ_MAXREQUESTBYTES
:最大请求字节数,如果未设置,默认为 8192 字节。更多信息请参阅 Envoy 文档。
KOURIER_EXTAUTHZ_TIMEOUT
:等待外部授权服务的最大时间(毫秒)。默认为 2 秒。
KOURIER_EXTAUTHZ_PATHPREFIX
:如果 KOURIER_EXTAUTHZ_PROTOCOL
等于 http
或 https
,此项为查询外部授权服务的路径。例如:如果设置为 /verify
,它将查询 /verify/
(注意末尾的斜杠)。如果未设置,它将查询 /
。
KOURIER_EXTAUTHZ_PACKASBYTES
:如果 KOURIER_EXTAUTHZ_PROTOCOL
等于 grpc
,此项将请求正文作为原始字节发送,而不是 UTF-8 字符串。仅接受 true
/false
、t
/f
或 1
/0
。尝试设置其他值会抛出错误。默认为 false
。更多信息请参阅 Envoy 文档。
*
为必填项。
Proxy Protocol 配置
注意:这是一项实验性/Alpha 功能。
要启用 Proxy Protocol 功能,请运行以下命令修补 config-kourier
ConfigMap:
kubectl patch configmap/config-kourier \
-n knative-serving \
--type merge \
-p '{"data":{"enable-proxy-protocol":"true"}}'
确保文件已成功更新:
kubectl get configmap config-kourier --namespace knative-serving --output yaml
LoadBalancer 配置
我们需要:
- 使用你的 LB 提供商的注解来启用 Proxy Protocol。
- 如果你计划启用外部域名 TLS,使用你的 LB 提供商的注解来指定一个自定义名称用于 LoadBalancer。这是为了解决 kube-proxy 将外部 LB 地址添加到节点本地 iptables 规则的问题,该问题会导致集群内部对 LB 的请求中断(如果 LB 期望终止 SSL 或 Proxy Protocol)。
- 将
externalTrafficPolicy
更改为 Local
,这样 LB 将保留客户端源 IP,并避免了对 LoadBalancer 的第二次跳跃。
示例 (Scaleway 提供商):
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
域名映射
域名映射(Domain Mapping)被配置为仅显式使用 http2
协议。通过向域名映射资源添加以下注解可以禁用此行为:
kubectl annotate domainmapping <domain_mapping_name> kourier.knative.dev/disable-http2=true --namespace <namespace>
此配置的一个很好用例是带有 Websocket 的域名映射。
注意:此注解是一项实验性/Alpha 功能。我们将来可能会更改注解名称。
扩展