經過Knative在Kubernetes上策劃一次從源碼到URL的部署

本文基於 knative 文檔中的 Orchestrating a source-to-URL deployment on Kubernetes 的簡單例子,經過從源碼到 URL 的部署流程一窺 Knative 給 Kubernetes 帶來的改變。node

環境需求

  • 一個安裝了 Knative 的 Kubernetes 集羣。若是你須要建立一個,按照安裝步驟來。
  • 安裝並配置了 Go。這是可選的,僅當你想要在本地運行示例應用時須要。

配置 Knative

源碼的構建是由 Knative build 子系統完成的,一般咱們須要在構建配置中定義一些構建步驟(step),經過這些構建步驟一步步地處理源碼,詳細能夠參考 Knative Build resources。但 Knative 也支持使用多種構建模板,下文就介紹如何使用 kaniko 構建模板完成示例代碼的構建。git

安裝 kaniko 構建模板

本示例藉助 kaniko build template 來在你的 Kubernetes 集羣上執行一次「從源碼到容器」的構建。github

kaniko 是谷歌開源的用於從 Dockerfile 構建容器鏡像的工具。它的特色在於不依賴 Docker daemon,並在用戶空間內執行 Dockerfile 中的每一行命令。這使得在一些不能方便地或安全地運行 Docker daemon 的環境中,如標準 Kubernetes 集羣中,也能構建容器鏡像。docker

使用 kubectl 來安裝 kaniko:編程

kubectl apply --filename https://raw.githubusercontent.com/knative/build-templates/master/kaniko/kaniko.yaml
複製代碼

填寫 Docker Hub 的密鑰

爲了將從源代碼構建獲得的容器推送到 Docker Hub,須要在 Kubernetes 上登記密鑰用於認證 Docker Hub。json

關於 Knative 中的認證,這是詳細的說明,下面是幾個關鍵步驟:api

  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 編碼的值:bash

    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
複製代碼
相關文章
相關標籤/搜索