Knative Service 是如何指定端口和协议的

简介: 如果使用 Knative Serving 部署一个 Nginx 你可能会发现服务起来了,但是无法访问到 Nginx 中的服务。当然这不是 Nginx 的问题,这是因为 Knative 对 Container 的端口有要求。

如果使用 Knative Serving 部署一个 Nginx 你可能会发现服务起来了,但是无法访问到 Nginx 中的服务。当然这不是 Nginx 的问题,这是因为 Knative 对 Container 的端口有要求。默认 Nginx 的服务端口是 80 ,而 Knative Serving queue 8012 默认是代理到容器的 8080 端口。所以如果业务容器监听的不是 8080 端口默认配置就不能对外暴露服务。具体的 spec 定义见这里: https://github.com/kubedemo/serving/blob/v0.6.0/docs/spec/spec.md

注:当然 如果想要监听多个端口也是不行的,虽然容器能够启动成功,都是无法通过 Service 暴露服务,从而无法通过 Istio gateway 暴露到外面,所以也就不能提供服务。

当你在查看上述 Spec 定义的时候你可能已经注意到了下面这两行注释。为什么会保留这几个端口呢?
image

下面我通过一张图来解释一下 Knative Serving 流量转发链路:
image

如上图所示,业务流量并不是从 Gateway 直接打到业务容器中的,而是经过 queue 容器转发的。queue 容器默认会监听 8012 和 8013 分别用于转发 http1 的流量和 http2 的流量。具体代码参见:
image

queue 容器在创建的时候会设定一个叫做 USER_PORT 的环境变量,queue 是通过这个环境变量来获取应该转发到业务容器的哪个端口的。所以只要我们能够修改 USER_PORT 这个环境变量我们就能自定义监听端口了。 USER_PORT 是通过 getUserPort 函数获取的,具体函数定义如下:
image

代码读到这里就已经很明朗了,创建 Knative Service 的时候可以指定 Ports 端口,然后可以通过端口的 containerPort 字段指定自定义端口。不过需要注意的是 Knative 只支持一个容器端口,所以虽然 Ports 是一个数组,但也只能设置一个。

实例如下:

apiVersion: serving.knative.dev/v1alpha1
kind: Service
metadata:
  name: wordpress-serving
  namespace: default
spec:
  template:
    metadata:
      labels:
        app: wordpress
      annotations:
        autoscaling.knative.dev/target: "100"
    spec:
      containers:
        - image: registry.cn-hangzhou.aliyuncs.com/knative-sample/wordpress:5.2-20190524100810
          ports:
            - name: http1
              containerPort: 80
          env:
          - name: WORDPRESS_DB_HOST
            value: rm-2xx.mysql.rds.aliyuncs.com:3306
          - name: WORDPRESS_DB_USER
            value: wordpress
          - name: WORDPRESS_DB_PASSWORD
            value: xxx
          imagePullPolicy: Always

上面在分析的过程中提到了 HTTP2 协议,如果当前提供的是 grpc 类型的服务就需要使用 http2 协议。

如果使用的是 HTTP2 协议那么也去请求就需要转发到 queue 的 8013 端口上,然后由 8013 转发给容器的业务端口。那么如何指定我们使用的协议呢?

在前面的分析中我们得出的结论是通过 port[0].containerPort 来指定自定义端口,其实也可以指定 port[0].name 字段。而 Revision Controller 生成 Deployment 部署服务的时候就是这个 name 字段来判断应该使用 http1(8012端口) 协议还是 http2(8013端口) 协议的。

  • http1 代表使用 http1(8012端口) 协议,同时 http1 也是默认策略,也就是说如果未指定那么默认也是 http1 协议
  • h2c 代表使用 http2(8013端口) 协议

代码分析如下:

https://github.com/kubedemo/serving/blob/release-0.6/pkg/apis/serving/v1alpha1/revision_lifecycle.go#L104

image

那么怎样才能指定容器的自定义端口呢?通过查阅代码可知

https://github.com/kubedemo/serving/blob/release-0.6/pkg/reconciler/serverlessservice/resources/services.go#L32
image

小结

Knative Service 可以给容器添加 ports 字段,并且 ports 只能设置一个端口。ports 有两个关键字段 Name 和 ContainerPort

          ports:
            - name: http1
              containerPort: 80
  • name 字段表示使用的协议,有效值有 http1 和 h2c 两个,其中:

    • http1 表示使用 http1 协议,比如 web 服务和 websock 都可以使用 http1
    • grpc 需要设置成 h2c
  • containerPort 字段就是容器提供服务的唯一端口。业务端口可以设置 1-65535 这个范围中除了 8012、8013、8022、8091 和 8092 以外的任意端口

image

目录
相关文章
|
30天前
|
负载均衡 网络协议 算法
slb监听协议与端口
SLB是云服务商提供的负载均衡服务,用于分发客户端请求到多台后端服务器,提升服务可用性和响应速度。关键概念包括监听协议(TCP、UDP、HTTP、HTTPS、TCPSSL)和监听端口。监听协议决定了SLB处理请求的方式,而监听端口则是SLB接收请求的入口。配置时需根据应用选择合适协议和端口,并可设置负载均衡算法(如轮询、最少连接等)。客户端应通过SLB统一入口访问后端服务,避免绕过SLB导致的问题。
159 2
|
30天前
|
负载均衡 网络协议 安全
slb选择监听协议和端口
阿里云SLB中,监听协议(TCP、HTTP、HTTPS)与端口(80、443等)决定客户端请求的处理方式。TCP适用于纯TCP或自处理HTTP的场景,HTTP用于智能调度Web服务,HTTPS提供安全的HTTP传输。监听端口通常匹配应用标准,如80 for HTTP,443 for HTTPS。配置时,可考虑HTTPS重定向和传递`X-Forwarded-Proto`头以识别请求来源。选择应基于业务需求和安全考虑。
69 3
|
7天前
|
网络协议 NoSQL 算法
TCP协议:超时重传、流量控制、keep-alive和端口号,你真的了解吗?
【6月更文挑战第2天】本文探讨了TCP协议的关键机制,包括超时重传计算(基于SRTT和RTT),流量控制(使用滑动窗口适应接收方处理能力),TCP keep-alive(通过定期探测保持连接活性),以及端口号的作用(区分不同服务和应用)。这些内容对于理解TCP的工作原理和面试准备至关重要。
|
8天前
网络编程中的互联网协议 , IP地址 , 域名 , 端口 , 架构 , 网页数据请求 , 响应码
网络编程中的互联网协议 , IP地址 , 域名 , 端口 , 架构 , 网页数据请求 , 响应码
|
30天前
|
安全 网络安全 数据安全/隐私保护
|
30天前
|
存储 安全 网络安全
HTTP与HTTPS的区别:安全性、协议地址和默认端口等比较
HTTP与HTTPS的区别:安全性、协议地址和默认端口等比较
205 0
|
30天前
|
SQL 安全 网络协议
网络端口号和协议号(大全)
网络端口号和协议号(大全)
302 2
|
网络协议 安全 Shell
常见的协议的协议号及端口
常见的协议的协议号及端口
216 0
|
网络协议 安全 定位技术
网络编程概述、网络编程三要素、InetAddress类及端口和协议介绍
网络编程概述、网络编程三要素、InetAddress类及端口和协议介绍
76 0
|
关系型数据库 MySQL Apache
Service Apache can not start. Reason:(OS 10048)通常每个套接字地址(协议/网络地址/端口)只允许使用一-次。: AH00072: make_ sock
Service Apache can not start. Reason:(OS 10048)通常每个套接字地址(协议/网络地址/端口)只允许使用一-次。: AH00072: make_ sock
168 0