欢迎光临
我们一直在努力

Serverless 与 K8s 的碰撞:利用 Knative 实现按需拉起的零副本应用架构

在传统的 Kubernetes 部署中,即使应用长时间处于闲置状态,也会保持至少一个或多个 Pod 运行,这导致了计算资源的浪费。Serverless 架构的核心优势之一就是能够按需启动和关闭应用,实现“零副本”待机。Knative,作为构建在 Kubernetes 之上的 Serverless 平台,完美地解决了这一问题。

本文将聚焦于 Knative Serving 组件,演示如何部署一个服务,使其在没有流量时自动缩容到零副本,并在接收到请求时快速拉起。

1. Knative 简介与核心机制

Knative 是 Google 开源的一套 K8s 扩展,主要包含 Serving、Eventing 和 Functions 三个部分。Knative Serving 提供了请求驱动的计算模型,通过以下关键机制实现零副本伸缩:

  1. Activator (激活器): 当服务缩容到零时,所有流量会首先被路由到 Activator。Activator 会缓存请求,并向 Autoscaler 发出信号,要求启动 Pod。
  2. Autoscaler (自动伸缩器): 负责监控服务的请求并发量,并根据配置策略(如目标并发数)动态调整 K8s Deployment 的副本数。

2. 环境准备与 Knative 安装(使用 Kourier 网络)

假设您已拥有一个可用的 Kubernetes 集群(v1.24+)。我们将使用 Knative 官方推荐的 Kourier 作为网络层,因为它比 Istio 更轻量。

步骤 2.1:安装 Knative Serving Core

# 1. 安装 Knative Serving CRDs
kubectl apply -f https://github.com/knative/serving/releases/download/knative-v1.13.0/serving-crds.yaml

# 2. 安装 Knative Serving Core Components
kubectl apply -f https://github.com/knative/serving/releases/download/knative-v1.13.0/serving-core.yaml

步骤 2.2:安装 Kourier Networking

# 3. 安装 Kourier Network Layer
kubectl apply -f https://github.com/knative/net-kourier/releases/download/knative-v1.13.0/kourier.yaml

# 4. 配置 Knative 使用 Kourier 作为默认 Ingress
kubectl patch configmap/config-network \n  --namespace knative-serving \n  --type merge \n  --patch '{"data": {"default-ingress-class": "kourier.ingress.networking.knative.dev"}}'

# 5. 等待所有 Knative Pod 启动完毕
kubectl wait --for=condition=ready pod -l '!job-name' -n knative-serving --timeout=300s

3. 部署零副本待机应用示例

我们使用一个简单的 Python Flask 应用作为示例。

步骤 3.1:创建 Dockerfile 和应用代码

创建一个简单的 app.py

# app.py
from flask import Flask
import os

app = Flask(__name__)

@app.route('/')
def hello():
    return f"Hello from Knative! Pod: {os.environ.get('KUBERNETES_POD_NAME', 'Unknown')}"

if __name__ == '__main__':
    # Knative 通常使用 PORT 环境变量指定的端口,默认为 8080
    app.run(host='0.0.0.0', port=int(os.environ.get('PORT', 8080)))

创建一个 Dockerfile

# Dockerfile
FROM python:3.10-slim
WORKDIR /app
COPY app.py .
RUN pip install flask gunicorn
CMD ["python", "app.py"]

将镜像构建并推送到容器仓库(例如 docker.io/your_user/knative-zero-scale:latest)。

步骤 3.2:定义 Knative Service

Knative Service 是其核心抽象。创建一个 service.yaml 文件。

注意: Knative 默认就支持缩容到零,除非您明确设置 minScale: 1。下面的配置确保其默认行为。

# service.yaml
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: zero-scale-demo
  namespace: default
spec:
  template:
    metadata:
      annotations:
        # 关键注解:设置目标并发数,用于控制何时扩容。默认 100
        autoscaling.knative.dev/target: "10"
        # 关键注解:定义从零启动时的最小实例数 (这里默认为 0,但可以显式设置)
        autoscaling.knative.dev/minScale: "0"
    spec:
      containers:
        - image: docker.io/your_user/knative-zero-scale:latest  # 替换为您的镜像地址

步骤 3.3:部署与验证

应用 Knative Service:

kubectl apply -f service.yaml

获取 Kourier Ingress 网关地址和 Knative Service URL:

# 获取 Knative Ingress IP/Hostname
export KNATIVE_INGRESS_IP=$(kubectl -n kourier-system get service kourier -o jsonpath='{.status.loadBalancer.ingress[0].ip}' || \
                           kubectl -n kourier-system get service kourier -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')

# 获取 Knative Service 域名
export SERVICE_URL=$(kubectl get ksvc zero-scale-demo -o jsonpath='{.status.url}')

echo "Ingress IP: $KNATIVE_INGRESS_IP"
echo "Service URL: $SERVICE_URL"

验证零副本待机:

几分钟后,查看 Pod 状态。您会发现该服务的 Pod 数量为 0。

kubectl get pods -l serving.knative.dev/service=zero-scale-demo
# 预期输出:No resources found in default namespace.

触发拉起 (Scale Up):

发送请求到 Knative Service (需要将请求头的 Host 设置为 Knative Service 的域名,路由到 Kourier 网关 IP)。

curl -H "Host: ${SERVICE_URL#*//}" http://$KNATIVE_INGRESS_IP
# 第一次请求可能经历短暂的冷启动延迟。

立即查看 Pod 状态:

kubectl get pods -l serving.knative.dev/service=zero-scale-demo
# 预期输出:会看到一个新的 Pod 正在 Running 状态 (e.g., zero-scale-demo-xxxxx-deployment-xxxxx-xxxxx 1/1 Running)

验证自动缩容 (Scale Down):

停止发送请求。如果 Pod 在一段时间(默认为 300 秒,可配置)内没有接收到新的流量,Knative Autoscaler 会指示 K8s 将副本数再次降为零。

4. 总结

通过 Knative Serving,我们成功地将 Serverless 的核心能力(按需启动、缩容到零)引入到了标准的 Kubernetes 环境中。这使得团队能够更有效地管理资源,仅在实际需要时才消耗计算资源,完美地结合了 K8s 的容器编排能力与 Serverless 的弹性优势。

【本站文章皆为原创,未经允许不得转载】:汤不热吧 » Serverless 与 K8s 的碰撞:利用 Knative 实现按需拉起的零副本应用架构
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址