通过Knative在Kubernetes上策划一次从源码到URL的部署

本文基于 knative 文档中的 Orchestrating a source-to-URL deployment on Kubernetes 的简单例子,通过从源码到 URL 的部署流程一窥 Knative 给 Kubernetes 带来的改变。

环境需求

  • 一个安装了 Knative 的 Kubernetes 集群。如果你需要创建一个,按照安装步骤来。
  • 安装并配置了 Go。这是可选的,仅当你想要在本地运行示例应用时需要。

配置 Knative

源码的构建是由 Knative build 子系统完成的,通常我们需要在构建配置中定义一些构建步骤(step),通过这些构建步骤一步步地处理源码,详细可以参考 Knative Build resources。但 Knative 也支持使用多种构建模板,下文就介绍如何使用 kaniko 构建模板完成示例代码的构建。

安装 kaniko 构建模板

本示例借助 kaniko build template 来在你的 Kubernetes 集群上执行一次“从源码到容器”的构建。

kaniko 是谷歌开源的用于从 Dockerfile 构建容器镜像的工具。它的特点在于不依赖 Docker daemon,并在用户空间内执行 Dockerfile 中的每一行命令。这使得在一些不能方便地或安全地运行 Docker daemon 的环境中,如标准 Kubernetes 集群中,也能构建容器镜像。

使用 kubectl 来安装 kaniko:

kubectl apply --filename https://raw.githubusercontent.com/knative/build-templates/master/kaniko/kaniko.yaml
复制代码

填写 Docker Hub 的密钥

为了将从源代码构建得到的容器推送到 Docker Hub,需要在 Kubernetes 上登记密钥用于认证 Docker Hub。

关于 Knative 中的认证,这是详细的说明,下面是几个关键步骤:

  1. 创建一个 Secret 配置,用于存放你的 Docker Hub 认证信息。将文件保存为 docker-secret.yaml

    apiVersion: v1
    kind: Secret
    metadata:
      name: basic-user-pass
      annotations:
        build.knative.dev/docker-0: https://index.docker.io/v1/
    type: kubernetes.io/basic-auth
    data:
      # Use 'echo -n "username" | base64' to generate this string
      username: BASE64_ENCODED_USERNAME
      # Use 'echo -n "password" | base64' to generate this string
      password: BASE64_ENCODED_PASSWORD
    复制代码
  2. 上面的配置中,usernamepassword 都是需要 base64 加密的。在 macOS 或 Linux 系统中,用下面的命令可以生成 base64 编码的值:

    echo -n "username" | base64 -w 0
    echo -n "password" | base64 -w 0
    复制代码

    注意:如果在 macOS 上提示 "invalid option -w" 错误,试着改成base64 -b 0

  3. 创建一个Service Account配置,用于将构建进程链接到Secret。将文件保存为service-account.yaml

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: build-bot
    secrets:
      - name: basic-user-pass
    复制代码
  4. 创建好配置文件后,通过kubectl将它们应用到你的集群:

    kubectl apply -f docker-secret.yaml
    kubectl apply -f service-account.yaml
    复制代码

部署示例

本示例使用 github.com/mchmarny/si… 作为一个基础 Go 应用,但你也可以替换为你自己的 GitHub 项目。唯一要注意的是,项目必须包含一个Dockerfile来描述如何为应用构建一个容器。

  1. 需要创建一个 service 配置来定义服务如何部署,包括源代码在哪儿、使用哪个构建模板。创建service.yaml并复制如下定义。将{DOCKER_USERNAME}替换为你自己的 Docker Hub 用户名:

     apiVersion: serving.knative.dev/v1alpha1
     kind: Service
     metadata:
       name: app-from-source
       namespace: default
     spec:
       runLatest:
         configuration:
           build:
             apiVersion: build.knative.dev/v1alpha1
             kind: Build
             spec:
               serviceAccountName: build-bot
               source:
                 git:
                   url: https://github.com/mchmarny/simple-app.git
                   revision: master
               template:
                 name: kaniko
                 arguments:
                   - name: IMAGE
                     value: docker.io/{DOCKER_USERNAME}/app-from-source:latest
           revisionTemplate:
             spec:
               container:
                 image: docker.io/{DOCKER_USERNAME}/app-from-source:latest
                 imagePullPolicy: Always
                 env:
                   - name: SIMPLE_MSG
                     value: "Hello from the sample app!"
    复制代码
  2. 使用kubectl应用配置,并观察结果:

    kubectl apply -f service.yaml
    kubectl get po --watch
    复制代码

    输出类似于:

    NAME                          READY     STATUS       RESTARTS   AGE
    app-from-source-00001-zhddx   0/1       Init:2/3     0          7s
    app-from-source-00001-zhddx   0/1       PodInitializing   0         37s
    app-from-source-00001-zhddx   0/1       Completed   0         38s
    app-from-source-00001-deployment-6d6ff665f9-xfhm5   0/3       Pending   0         0s
    app-from-source-00001-deployment-6d6ff665f9-xfhm5   0/3       Pending   0         0s
    app-from-source-00001-deployment-6d6ff665f9-xfhm5   0/3       Init:0/1   0         0s
    app-from-source-00001-deployment-6d6ff665f9-xfhm5   0/3       Init:0/1   0         2s
    app-from-source-00001-deployment-6d6ff665f9-xfhm5   0/3       PodInitializing   0         3s
    app-from-source-00001-deployment-6d6ff665f9-xfhm5   2/3       Running   0         6s
    app-from-source-00001-deployment-6d6ff665f9-xfhm5   3/3       Running   0         11s
    复制代码

    能看到先是app-from-source-00001启动,执行“从源码到镜像”的过程,再启动app-from-source-00001-deployment拉取镜像,提供服务。

    需要特别说明的是,笔者这个步骤失败了多次,都是app-from-source-00001初始化过程意外退出。通过kubectl describe查看详细信息,提示构建超时(默认构建超时是10分钟)。构建过程需要拉取一些镜像,推测可能由于网络原因,该步骤耗时过长。可以在构建过程中,通过kubectl describe po app-from-source-00001-zhddx查看相关 Event,找到构建具体是在哪一步耗时过长。笔者最后多试几次成功了:)

  3. 当你看到 deployment pod 变为Running状态时,Ctrl+C退出观察。此时你的容器已经完成构建和部署了!

  4. 要检查服务的状态,可以

    kubectl get ksvc app-from-source --output yaml
    复制代码
  5. 当你创建服务时,Knative 随即执行以下步骤:

    • 从 GitHub 拉取revision指定的代码并构建到容器中
    • 将容器推送到 Docker Hub
    • 为当前应用的版本创建一个新的不可变的revision
    • 通过网络编程为你的应用创建routeingressservice和负载均衡服务
    • 自动伸缩你的 pods(包括缩至0个活动 pods)
  6. 要获取你的集群的入口 IP,使用如下命令。如果你的集群是新建的,服务获取一个外部 IP 地址可能会花一些时间:

    # In Knative 0.2.x and prior versions, the `knative-ingressgateway` service was used instead of `istio-ingressgateway`.
    INGRESSGATEWAY=knative-ingressgateway
    
    # The use of `knative-ingressgateway` is deprecated in Knative v0.3.x.
    # Use `istio-ingressgateway` instead, since `knative-ingressgateway`
    # will be removed in Knative v0.4.
    if kubectl get configmap config-istio -n knative-serving &> /dev/null; then
        INGRESSGATEWAY=istio-ingressgateway
    fi
    
    kubectl get svc $INGRESSGATEWAY --namespace istio-system
    复制代码

    需要注意的是,minikube 搭建的集群通过上面的方式是获取不到外部 IP 的。应该执行:

    echo $(minikube ip):$(kubectl get svc $INGRESSGATEWAY --namespace istio-system --output 'jsonpath={.spec.ports[?(@.port==80)].nodePort}')
    复制代码
  7. 要找到服务的 URL,输入:

    kubectl get ksvc app-from-source  --output=custom-columns=NAME:.metadata.name,DOMAIN:.status.domain
    复制代码
  8. 现在你可以向你的应用发送一个请求来看看结果。将{IP_ADDRESS}替换为你上一步获得的地址:

    curl -H "Host: app-from-source.default.example.com" http://{IP_ADDRESS}
    复制代码

清理示例应用部署

要从你的集群移除示例应用,删除服务记录:

kubectl delete -f service.yaml
复制代码

转载于:https://juejin.im/post/5c7521f551882561f34de695

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值