Knative Serverless K8s 平台

FreeGuideOnline 最新 2026-07-11

bash minikube start --memory=4096 --cpus=2


#### 4.1 安装 Knative Serving

1. 部署核心自定义资源:
```bash
kubectl apply -f https://github.com/knative/serving/releases/download/knative-v1.12.0/serving-crds.yaml
  1. 部署核心组件:
kubectl apply -f https://github.com/knative/serving/releases/download/knative-v1.12.0/serving-core.yaml

4.2 安装网络层(选择 Kourier)

Knative 依赖网络层接收外部流量。这里推荐轻量的 Kourier:

kubectl apply -f https://github.com/knative/net-kourier/releases/download/knative-v1.12.0/kourier.yaml

配置 Kourier 为默认网络:

kubectl patch configmap/config-network \
  --namespace knative-serving \
  --type merge \
  --patch '{"data":{"ingress-class":"kourier.ingress.networking.knative.dev"}}'

4.3 配置 DNS(本地环境使用 sslip.io)

kubectl patch configmap/config-domain \
  --namespace knative-serving \
  --type merge \
  --patch '{"data":{"example.com":""}}'

实际上,在 minikube 中可以借助 sslip.io 自动解析:

kubectl patch configmap/config-domain \
  --namespace knative-serving \
  --type merge \
  --patch '{"data":{"<你的IP>.sslip.io":""}}'

获取 IP 的命令:

minikube ip

4.4 验证安装

所有 Pod 处于 Running 状态即表示成功:

kubectl get pods -n knative-serving
kubectl get pods -n kourier-system

5. 部署第一个无服务器应用

我们来部署一个超简单的 “Hello World” 服务,该服务读取请求并返回友好的问候。

创建 hello-service.yaml

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: hello
spec:
  template:
    spec:
      containers:
        - image: gcr.io/knative-samples/helloworld-go
          env:
            - name: TARGET
              value: "Knative Learner"

部署:

kubectl apply -f hello-service.yaml

查看资源:

kubectl get ksvc hello

当 READY 为 True 时,获取访问 URL:

kubectl get ksvc hello -o jsonpath='{.status.url}'

用 curl 测试(替换为你的实际 URL):

curl http://hello.default.192.168.49.2.sslip.io
# 输出:Hello Knative Learner!

几秒钟内如果没有新请求,Pod 将会缩减至 0。再次 curl 会触发冷启动(稍慢),然后 Pod 迅速拉起。

6. 深入探索 Knative Serving

6.1 流量管理与版本发布

假设你要发布新版本 v2,但希望先让 10% 用户试用。修改 Service 的 spec.traffic

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: hello
spec:
  template:
    spec:
      containers:
        - image: gcr.io/knative-samples/helloworld-go
          env:
            - name: TARGET
              value: "v2 Users"
  traffic:
  - percent: 90
    revisionName: hello-00001   # 旧版本
  - percent: 10
    latestRevision: true       # 当前最新版本

应用后,10% 的请求会路由到新版本。你可以使用 kubectl get revisions 查看历史版本。

6.2 自定义并发与扩缩参数

在 Revision 模板中指定:

spec:
  template:
    spec:
      containerConcurrency: 5   # 每个 Pod 同时处理不超过5个请求
      scaleTargetRef:           # 指定扩缩目标
        apiVersion: apps/v1
        kind: Deployment
        name: hello-00001-deployment
      minScale: 1               # 最少保留1个副本,避免冷启动
      maxScale: 10

也可以通过注解设置全局或单服务参数:

metadata:
  annotations:
    autoscaling.knative.dev/target: "10"          # 目标并发数
    autoscaling.knative.dev/min-scale: "2"
    autoscaling.knative.dev/max-scale: "100"
    autoscaling.knative.dev/scale-to-zero-grace-period: "60s"

7. 事件驱动:Knative Eventing 实战

7.1 部署一个简单的 Eventing 示例

  1. 安装 Knative Eventing(如果尚未安装):
kubectl apply -f https://github.com/knative/eventing/releases/download/knative-v1.12.0/eventing-crds.yaml
kubectl apply -f https://github.com/knative/eventing/releases/download/knative-v1.12.0/eventing-core.yaml
  1. 启用 Broker 实现(选 InMemoryChannel):
kubectl apply -f https://github.com/knative/eventing/releases/download/knative-v1.12.0/in-memory-channel.yaml
kubectl apply -f https://github.com/knative/eventing/releases/download/knative-v1.12.0/mt-channel-broker.yaml

7.2 创建 Broker 和 Trigger

创建一个默认 Broker:

kubectl create -f - <<EOF
apiVersion: eventing.knative.dev/v1
kind: Broker
metadata:
  name: default
EOF

部署一个接收日志事件的消费者服务:

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: event-display
spec:
  template:
    spec:
      containers:
        - image: gcr.io/knative-releases/knative.dev/eventing/cmd/event_display

接着创建 Trigger,让 default Broker 将所有 dev.knative.sample.event 类型的事件发送给 event-display

apiVersion: eventing.knative.dev/v1
kind: Trigger
metadata:
  name: display-trigger
spec:
  broker: default
  filter:
    attributes:
      type: dev.knative.sample.event
  subscriber:
    ref:
      apiVersion: serving.knative.dev/v1
      kind: Service
      name: event-display

7.3 发送测试事件

模拟事件生产者:

curl -v "http://broker-ingress.knative-eventing.svc.cluster.local/default/default" \
  -X POST \
  -H "Ce-Id: say-hello" \
  -H "Ce-Specversion: 1.0" \
  -H "Ce-Type: dev.knative.sample.event" \
  -H "Ce-Source: curl" \
  -H "Content-Type: application/json" \
  -d '{"msg":"Hello from event!"}'

查看 event-display 的日志:

kubectl logs -l serving.knative.dev/service=event-display -c user-container

你会看到事件已经被成功接收。

8. 生产实践与常见陷阱

8.1 镜像拉取与私有仓库

Knative Service 拉取私有镜像需要配置 Secret,并在 Service Account 中引用。创建 Secret:

kubectl create secret docker-registry myregistrykey \
  --docker-server=<your-registry> \
  --docker-username=<user> \
  --docker-password=<password> \
  --docker-email=<email>

然后让 default ServiceAccount 引用它:

kubectl patch serviceaccount default -p '{"imagePullSecrets": [{"name": "myregistrykey"}]}'

8.2 资源限制与请求

合理设置 CPU 和内存请求/限制,避免 OOMKill 或性能抖动:

containers:
- image: ...
  resources:
    requests:
      cpu: 100m
      memory: 128Mi
    limits:
      cpu: 500m
      memory: 256Mi