本地运行 Knative Serving 全指南
1. 安装 Minikube 和 kubectl
要在本地运行 Knative Serving,首先需要安装 Minikube 和 kubectl。可以使用 gcloud 来完成这两个组件的安装。
- 步骤如下:
1. 确保 gcloud 是最新版本:
gcloud components update
- 安装 Minikube,此过程可能需要一些时间,尤其是在网络带宽有限的情况下:
gcloud components install minikube
- 安装完成后,检查 Minikube 是否安装成功:
minikube version
输出应显示类似
minikube version: v1.13.0
(或更高版本)。
4. 安装 kubectl,即 Kubernetes 客户端:
gcloud components install kubectl
- 检查 kubectl 是否安装成功,输入以下命令,若成功安装,将看到一长串可用命令:
kubectl
2. 启动本地集群
使用以下命令创建一个单节点的本地 Kubernetes 集群:
minikube start --kubernetes-version=1.19.2
该命令会使用本地虚拟机或 Docker 容器来运行 Kubernetes 节点。对于 macOS 用户,虚拟机驱动可能比 Docker 驱动更稳定,若使用 Docker 驱动出现高 CPU 使用率问题,可使用以下命令删除基于 Docker 的集群,并选择虚拟机驱动:
minikube delete
minikube start --driver=hyperkit --kubernetes-version=1.19.2
命令执行完成后(可能需要一些时间),检查集群是否正常运行:
minikube status
输出应类似如下内容,表明服务正在运行:
minikube
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured
Minikube 还会更新 kubectl 配置,使其连接到新的集群。可以使用以下命令列出集群中已在运行的内部组件:
kubectl get --namespace kube-system pods
输出示例:
NAMESPACE NAME READY STATUS
kube-system coredns-66bff467f8-h9djq 1/1 Running
kube-system etcd-minikube 1/1 Running
kube-system kube-apiserver-minikube 1/1 Running
kube-system kube-controller-manager-minikube 1/1 Running
kube-system kube-proxy-lwcr2 1/1 Running
kube-system kube-scheduler-minikube 1/1 Running
kube-system storage-provisioner 1/1 Running
如果所有 Pod 都处于
Running
状态,则集群可以正常使用。
3. 安装 Knative Operator
在本地主机上运行 Kubernetes 集群后,就可以添加 Knative Serving 了。第一步是安装 Knative Operator,它可以帮助我们安装 Knative Serving。
- 使用以下命令安装 Operator:
kubectl apply -f https://git.io/JUd0x
仔细查看命令输出,会发现它添加了两个自定义资源并部署了
knative-operator
。
- 可以使用以下命令检查其是否正在运行:
kubectl get deployments
输出示例:
NAME READY UP-TO-DATE AVAILABLE
knative-operator 1/1 1 1
-
接下来,添加
knative-serving命名空间:
kubectl create namespace knative-serving
输出应显示
namespace/knative-serving created
。
4. 启动 Minikube 隧道
在一个单独的终端标签中,启动 Minikube 隧道并保持其运行。此命令需要 root 权限来创建到集群的网络路径,确保可以访问集群上的私有 IP:
minikube tunnel
5. 安装 Knative Serving
将描述 Knative Serving 扩展的对象放入 YAML 文件中,并使用 kubectl apply 发送到 API 服务器,Operator 会自动安装 Knative Serving。
- 创建
knative-serving.yml
文件,内容如下:
apiVersion: operator.knative.dev/v1alpha1
kind: KnativeServing
metadata:
namespace: knative-serving
name: knative-serving
spec:
config:
network:
ingress.class: "kourier.ingress.networking.knative.dev"
- 使用以下命令将文件发送到 API 服务器:
kubectl apply -f knative-serving.yml
输出应显示
knativeserving.operator.knative.dev/knative-serving created
。
- 检查并等待所有部署完成(所有应显示
AVAILABLE 1
):
kubectl get deployment -n knative-serving
输出示例:
NAME READY UP-TO-DATE AVAILABLE AGE
activator 1/1 1 1 3m48s
autoscaler 1/1 1 1 3m48s
autoscaler-hpa 1/1 1 1 3m44s
controller 1/1 1 1 3m47s
webhook 1/1 1 1 3m47s
6. 安装 HTTP 负载均衡器
为了将传入请求转发到 Knative Serving,需要安装一个 HTTP 负载均衡器。这里选择 Kourier,因为它最容易设置和路由流量。
- 使用以下命令安装 Kourier v0.17.0:
kubectl apply -f https://git.io/JUdus
- 查找负载均衡器入口的 IP:
kubectl -n kourier-system describe services kourier
输出中找到
LoadBalancer Ingress
字段,复制其 IP。如果没有该字段,需要检查 Minikube 隧道是否正在运行。
7. 配置 DNS
Minikube 隧道会添加从主机到本地 Kubernetes 集群内部 IP 的路由,由于 Knative 使用基于主机的路由,因此需要设置 DNS。这里使用 nip.io 服务。
- 编辑
config-domain.yml
文件,内容如下:
apiVersion: v1
kind: ConfigMap
metadata:
name: config-domain
namespace: knative-serving
data:
xxx.xxx.xxx.xxx.nip.io: ""
将
xxx.xxx.xxx.xxx
替换为从负载均衡器入口复制的 IP,保存文件并应用:
kubectl apply -f config-domain.yml
至此,设置阶段完成,现在本地机器上已经安装了一个完全正常运行的 Knative Serving。下面是部署服务的步骤。
8. 部署服务
由于 Cloud Run 和 Knative 使用相同的资源模型,因此可以使用相同的服务定义文件将服务部署到 Cloud Run 和 Knative Serving。
- 创建
service.yml
文件,内容如下:
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: hello
spec:
template:
spec:
containers:
- image: gcr.io/cloud-run-book/inspect
- 将服务部署到 Knative Serving:
kubectl apply -f service.yml
输出应显示
service.serving.knative.dev/hello created
。
- 查找服务的 URL:
kubectl get ksvc
输出示例:
NAME URL
hello http://hello.default.xxx.xxx.xxx.xxx.nip.io
打开该 URL,应看到与之前部署的示例服务相同的页面。
9. 将相同服务部署到 Cloud Run
使用相同的 YAML 文件将服务部署到 Cloud Run:
gcloud beta run services replace service.yml
还需要添加 IAM 策略绑定以访问该服务:
gcloud run services add-iam-policy-binding hello \
--member allUsers \
--role roles/run.invoker
打开服务 URL,应看到相同的页面(显示不同的环境变量)。
10. 替代 API 客户端说明
使用 gcloud 部署到 Cloud Run,而使用不同的客户端部署到 Kubernetes,主要是因为 Kubernetes 和 Google Cloud 处理身份验证的方式不同。虽然通过一些技巧可以解决,但如果想了解更多,可以参考相关博客文章。
11. 关闭本地环境
当不再需要本地环境时,可以按照以下步骤关闭:
- 停止 Minikube 隧道:回到运行
minikube tunnel
的终端标签,停止该命令(正确停止将移除路由)。
- 删除单节点 Kubernetes 集群:
minikube delete
12. Knative Serving 与 Cloud Run 的差异
-
服务功能
:
- Cloud Run 提供自定义域名,并自动获取和更新 TLS 证书(用于 HTTPS),而在 Knative 上实现这些功能需要额外配置。
-
迁移难度
:
- Knative 运行在 Kubernetes 之上,可以访问所有其他 Kubernetes 原语。例如,可以使用 CronJob 资源来调度定时任务。
- Cloud Run 的容器运行时(gVisor)有一些限制,如不能挂载 NFS 卷,而在 Kubernetes 上使用不同的容器运行时则可以。
- 当容器在 Cloud Run 上不处理请求时会被节流,而在 Kubernetes 上没有此限制。从 Knative Serving 迁移到 Cloud Run 可能会遇到更多问题。
-
服务身份和认证
:
- Cloud Run 使用 Cloud IAM 处理服务身份和认证。
- 在 Kubernetes 领域,这是一个创新的领域,有多种方法,目前 Istio 和 Envoy 是值得探索的项目。
-
专有托管服务
:
- 如果使用 Google Cloud 上没有开源替代方案的专有托管服务,将应用迁移到其他平台时,可能需要继续使用这些服务(如果可行的话),如 Cloud IAM、Firestore、Cloud Tasks 和 Cloud Scheduler。
总结
通过以上步骤,我们学习了如何在本地安装和运行 Knative Serving,并将服务部署到 Knative Serving 和 Cloud Run。同时,了解了 Knative Serving 与 Cloud Run 的差异。Kubernetes 是一个庞大的主题,如果想深入学习,可以参考相关书籍。即使可能永远不需要离开 Google Cloud,但了解迁移的方法也是有必要的。
以下是整个部署流程的 mermaid 流程图:
graph TD;
A[安装 Minikube 和 kubectl] --> B[启动本地集群];
B --> C[安装 Knative Operator];
C --> D[启动 Minikube 隧道];
D --> E[安装 Knative Serving];
E --> F[安装 HTTP 负载均衡器];
F --> G[配置 DNS];
G --> H[部署服务到 Knative Serving];
H --> I[部署相同服务到 Cloud Run];
I --> J[关闭本地环境];
通过这个流程图,可以更清晰地看到从开始安装到最终部署和关闭的整个过程。同时,在每个步骤中,我们都提供了详细的命令和说明,希望能帮助你顺利在本地运行 Knative Serving。
本地运行 Knative Serving 全指南(续)
13. 部署服务的注意事项
在部署服务到 Knative Serving 和 Cloud Run 时,有一些关键的注意事项需要牢记,这些注意事项有助于确保服务的顺利部署和稳定运行。
13.1 容器镜像
- 大小优化 :容器镜像应尽可能小,以减少启动时间和资源占用。可以使用 distroless 等技术来创建更小的容器镜像。例如,在构建 Go 容器时,可以使用 ko 工具,它能帮助创建精简的容器镜像。
# 使用 ko 构建并推送容器镜像
ko publish gcr.io/cloud-run-book/inspect
-
镜像配置
:确保容器镜像的配置正确,包括端口号、工作目录等。在
service.yml文件中,可以通过spec.template.spec.containers部分进行配置。
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: hello
spec:
template:
spec:
containers:
- image: gcr.io/cloud-run-book/inspect
ports:
- containerPort: 8080
workingDir: /app
13.2 服务配置
- 并发设置 :根据服务的负载情况,合理设置并发请求限制。在 Knative Serving 和 Cloud Run 中,可以通过配置文件或命令行参数来设置并发数。
# 设置 Cloud Run 服务的并发数
gcloud beta run services update hello --concurrency=10
- 自动伸缩 :了解自动伸缩的机制,确保服务能够根据负载自动调整实例数量。在 Knative Serving 中,自动伸缩器会根据请求情况自动调整容器数量。
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: hello
spec:
template:
metadata:
annotations:
autoscaling.knative.dev/minScale: "1"
autoscaling.knative.dev/maxScale: "10"
spec:
containers:
- image: gcr.io/cloud-run-book/inspect
14. 监控与日志
14.1 监控
- Cloud Monitoring :使用 Cloud Monitoring 来监控服务的性能指标,如 CPU 使用率、内存使用率、请求响应时间等。可以设置告警规则,当指标超过阈值时及时通知。
# 创建一个基于日志的指标
gcloud monitoring metrics describe logging.googleapis.com/user/request_latency
- 自定义指标 :除了使用内置的指标,还可以定义自定义指标来监控特定的业务指标。例如,可以监控服务的订单处理数量、错误率等。
// 在 Go 代码中定义并记录自定义指标
package main
import (
"log"
"net/http"
"contrib.go.opencensus.io/exporter/stackdriver"
"go.opencensus.io/stats"
"go.opencensus.io/stats/view"
"go.opencensus.io/tag"
)
var (
mOrderCount = stats.Int64("order_count", "Number of orders processed", stats.UnitDimensionless)
keyService = tag.MustNewKey("service")
)
func main() {
exporter, err := stackdriver.NewExporter(stackdriver.Options{
ProjectID: "your-project-id",
})
if err != nil {
log.Fatalf("Failed to create Stackdriver exporter: %v", err)
}
view.RegisterExporter(exporter)
err = view.Register(&view.View{
Name: "order_count_view",
Measure: mOrderCount,
Description: "Number of orders processed",
Aggregation: view.Count(),
TagKeys: []tag.Key{keyService},
})
if err != nil {
log.Fatalf("Failed to register view: %v", err)
}
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
ctx, _ := tag.New(r.Context(), tag.Insert(keyService, "hello-service"))
stats.Record(ctx, mOrderCount.M(1))
w.Write([]byte("Order processed"))
})
log.Fatal(http.ListenAndServe(":8080", nil))
}
14.2 日志
- Cloud Logging :使用 Cloud Logging 来收集和查看服务的日志。可以通过命令行或 Web 控制台查看日志。
# 查看 Cloud Run 服务的日志
gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=hello"
- 结构化日志 :使用结构化日志可以更方便地分析和查询日志。在 Go 代码中,可以使用 zerolog 等库来记录结构化日志。
package main
import (
"log"
"net/http"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
)
func main() {
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
log.Info().
Str("method", r.Method).
Str("url", r.URL.String()).
Msg("Received request")
w.Write([]byte("Hello, World!"))
})
log.Fatal(http.ListenAndServe(":8080", nil))
}
15. 安全与权限
15.1 身份验证与授权
- Cloud IAM :在 Cloud Run 中,使用 Cloud IAM 来管理服务的身份验证和授权。可以为服务账户分配不同的角色和权限。
# 创建一个新的服务账户
gcloud iam service-accounts create hello-service-account --display-name "Hello Service Account"
# 为服务账户分配 Cloud Run Invoker 角色
gcloud projects add-iam-policy-binding your-project-id --member "serviceAccount:hello-service-account@your-project-id.iam.gserviceaccount.com" --role "roles/run.invoker"
- ID 令牌 :使用 ID 令牌来进行身份验证。在发送请求时,可以在 HTTP 头中添加 ID 令牌。
# 获取 ID 令牌
gcloud auth print-identity-token
# 在请求中添加 ID 令牌
curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" http://hello.default.xxx.xxx.xxx.xxx.nip.io
15.2 网络安全
- VPC 连接器 :使用 VPC 连接器来连接到私有网络,确保服务可以访问私有资源。
# 创建 VPC 连接器
gcloud compute networks vpc-access connectors create my-connector --network default --region your-region --range 10.8.0.0/28
# 将服务连接到 VPC 连接器
gcloud beta run services update hello --vpc-connector my-connector
- 防火墙规则 :设置防火墙规则来限制对服务的访问。可以使用 Google Cloud 的防火墙规则来控制流量。
# 创建防火墙规则,允许特定 IP 地址访问服务
gcloud compute firewall-rules create allow-http-from-my-ip --direction=INGRESS --priority=1000 --network=default --action=ALLOW --rules=tcp:8080 --source-ranges=your-ip-address/32
16. 持续集成与持续部署(CI/CD)
16.1 自动化部署
-
Cloud Build
:使用 Cloud Build 来实现自动化构建和部署。可以编写 Cloud Build 的配置文件(
cloudbuild.yaml)来定义构建和部署步骤。
# cloudbuild.yaml
steps:
- name: 'gcr.io/cloud-builders/docker'
args: ['build', '-t', 'gcr.io/your-project-id/hello:$SHORT_SHA', '.']
- name: 'gcr.io/cloud-builders/docker'
args: ['push', 'gcr.io/your-project-id/hello:$SHORT_SHA']
- name: 'gcr.io/cloud-builders/gcloud'
args: ['beta', 'run', 'services', 'replace', 'service.yml', '--image', 'gcr.io/your-project-id/hello:$SHORT_SHA']
images:
- 'gcr.io/your-project-id/hello:$SHORT_SHA'
16.2 版本控制
- Git :使用 Git 进行版本控制,确保代码的可追溯性和协作性。可以使用 GitHub 或 Google Cloud Source Repositories 来托管代码。
# 初始化 Git 仓库
git init
# 添加文件到 Git 仓库
git add .
# 提交更改
git commit -m "Initial commit"
# 推送到远程仓库
git push origin master
17. 常见问题与解决方案
17.1 容器启动失败
- 检查镜像配置 :确保容器镜像的配置正确,包括端口号、工作目录等。
- 查看日志 :使用 Cloud Logging 查看容器启动时的日志,找出错误原因。
gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=hello"
17.2 服务无法访问
- 检查网络配置 :确保 Minikube 隧道正常运行,VPC 连接器配置正确。
- 检查 DNS 配置 :确保 DNS 配置正确,服务的 URL 可以正常解析。
17.3 自动伸缩异常
- 检查自动伸缩配置 :确保自动伸缩的配置正确,包括最小和最大实例数等。
- 查看监控指标 :使用 Cloud Monitoring 查看服务的负载情况,找出自动伸缩异常的原因。
总结
通过以上详细的介绍,我们全面了解了在本地运行 Knative Serving 的整个流程,包括安装、部署、监控、安全等方面。同时,也了解了 Knative Serving 与 Cloud Run 的差异以及如何根据实际需求进行选择和配置。在实际应用中,需要根据具体的业务场景和需求,合理运用这些技术,确保服务的高效、稳定运行。
以下是一个总结的表格,对比了 Knative Serving 和 Cloud Run 的主要特点:
| 特点 | Knative Serving | Cloud Run |
| ---- | ---- | ---- |
| 自定义域名 | 需要额外配置 | 提供自定义域名 |
| TLS 证书 | 需要额外配置 | 自动获取和更新 |
| 容器运行时限制 | 无 | 有(如不能挂载 NFS 卷) |
| 身份验证 | 多种方法(如 Istio、Envoy) | Cloud IAM |
| 迁移难度 | 相对容易迁移到 Cloud Run | 从 Knative Serving 迁移可能有问题 |
希望本文能为你在本地运行 Knative Serving 和使用 Cloud Run 提供有价值的参考,帮助你顺利开展容器化应用的开发和部署工作。
超级会员免费看
54

被折叠的 条评论
为什么被折叠?



