如何使用k3OS和Argo進行自動化邊緣部署?


本文轉自邊緣計算k3s社區

前 言

隨着Kubernetes生態系統的發展,新的技術正在被開發出來,以實現更廣泛的應用和用例。邊緣計算的發展推動了對其中一些技術的需求,以實現將Kubernetes部署到網絡邊緣資源受限的基礎設施上。在這篇文章中,我們將向你介紹一種將k3OS部署到邊緣的方法。你可以使用這種方法將你的邊緣機自動注冊到Rancher實例中作為控制平面。我們還將討論自動部署到物理機的一些好處。

k3OS於2019年4月由業界應用最為廣泛的Kubernetes管理平台創建者Rancher Labs(以下簡稱Rancher)推出,它是一個輕量的、專注於邊緣的Kubernetes操作系統,同時也是業界首個Kubernetes操作系統。它與K3s打包,使得應用程序能夠輕松地部署到資源受限的環境中,如部署在邊緣設備上。

雖然k3OS仍處於起步階段,但它已經通過了實戰測試,並被用於各種生產環境中。為了充分掌握邊緣計算的全部優勢,你需要在你部署的基礎設施上盡可能地節省空間。

Argo簡介

Argo是雲原生計算基金會(CNCF)的一個項目,旨在減輕在容器原生環境中運行計算密集型工作負載的一些痛苦。子項目Argo workflow是一個開源的容器原生workflow引擎,用於協調Kubernetes中的並行job。它以Kubernetes自定義資源(CRD)的形式實現,本質上是Kubernetes API的擴展。

通過Argo workflow,我們可以定義workflow,其中的每一步都是一個容器,並將多步工作流建模為任務序列,或使用有向無環圖(DAG)捕獲任務之間的依賴關系。這在自動化部署和配置邊緣原生服務時非常有用。我們將在本次demo的后面看到Argo Workflows的許多方面將會發揮作用。

Step 1 設置一個demo環境

為了模擬一個工作邊緣站點,我們需要在本地虛擬機上啟動k3OS,然后使用Argo工作流呼叫到遠程Rancher實例。在本節中,我們將:

  • 下載k3OS iso

  • 部署Rancher

  • 安裝Argo Workflows

設置本地VM(邊緣端)

安裝VirtualBox不在本次演示的范圍內,因此默認你已經安裝完成。然后,我們將其啟動並完成設置虛擬機和附加k3OS iso的初始過程。完成之后,我們將啟動機器並看到介紹屏幕:

在這里插入圖片描述

此時,我們將打開一個terminal並添加k3OS VM到我們的config.yaml文件。我們可以使用這個方便的幫忙腳本:

# Pull k3OS credentials
get_vm() {
gsed -i '/127.0.0.1/d' ~/.ssh/known_hosts
scp -P 3022 rancher@127.0.0.1:/etc/rancher/k3s/k3s.yaml ~/.kube/current_k3os_vm.yaml
sed 's/6443/4443/g' ~/.kube/current_k3os_vm.yaml > ~/.kube/current_k3os_master.yaml
export KUBECONFIG=~/.kube/current_k3os_master.yaml
rm ~/.kube/current_k3os_vm.yaml
}

請注意:需要轉發3022和4443端口

我們成功拉取.kubeconfig文件之后,我們應該准備好部署控制平面。

部署Rancher(雲端)

要部署Rancher到雲端環境,請執行以下步驟:

  1. Clone或下載該倉庫(https://github.com/rancher/quickstart)到本地文件夾

  2. 選擇一個雲提供商並導航到提供商的文件夾中

  3. 將terraform.tfvars.example復制或重命名為terraform.tfvars並填入所有必要的變量

  4. 運行terraform init

  5. 運行terraform apply

當配置完成之后,Terraform將輸出連接到Rancher服務器的URL。還會生成兩套Kubernetes配置:

Apply complete! Resources: 16 added, 0 changed, 0 destroyed.

Outputs:

rancher_node_ip = xx.xx.xx.xx
rancher_server_url = https://xx-xx-xx-xx.nip.io
workload_node_ip = yy.yy.yy.yy

kube_config_server.yaml包含了訪問支持Rancher server的RKE集群的憑證, kube_config_workload.yaml包含了訪問配置工作負載集群的憑證。

有關每個雲提供商的更多詳情,請參閱 repo 中各自文件夾中的文檔。

Step 2 安裝Argo Workflow

安裝Argo CLI:

你可以從Argo release頁面下載最新的Argo CLI:

https://github.com/argoproj/argo/releases

安裝controller:

在這一步中,我們將安裝Argo Workflows,通過workflow CRD擴展Kubernetes API。這將允許我們將多個“job”依次鏈在一起。安裝Argo Workflows就像切換到k3OS集群並運行一樣簡單:

kubectl create namespace argo
kubectl apply -n argo -f https://raw.githubusercontent.com/argoproj/argo/stable/manifests/install.yaml

請注意:在GKE上,你可能需要授予你的賬戶創建新集群角色的能力。

kubectl create clusterrolebinding YOURNAME-cluster-admin-binding --clusterrole=cluster-admin --user=YOUREMAIL@gmail.com

Step 3 配置服務賬戶以運行workflows

角色、角色綁定以及ServiceAccount

為了讓Argo支持工件、輸出、訪問secret等功能,它需要使用Kubernetes API與Kubernetes資源進行通信。為了做到這一點,Argo使用ServiceAccount來驗證自己與Kubernetes API的關系。你可以通過使用RoleBinding將一個Role綁定到ServiceAccount上,指定Argo使用的ServiceAccount是哪個Role(即哪個權限)。

然后,在提交workflow時,指定Argo使用哪個ServiceAccount:

argo submit --serviceaccount <name>

當沒有提供ServiceAccount時,Argo將使用運行的命名空間的默認ServiceAccount,默認情況下它的權限幾乎總是不夠的。

授予管理員權限

在本次demo中,我們將授予defaultServiceAccount管理員權限(即我們將綁定adminRole到當前命名空間的defaultServiceAccount中):

kubectl create rolebinding default-admin --clusterrole=admin --serviceaccount=argo:default -n argo

請注意:這將向命令運行的命名空間中的default ServiceAccount授予管理權限,因此你將只能在制作RoleBinding的命名空間中運行workflows。

Step 4 運行workflow

從這里,你可以通過CLI以多種方式提交Argo workflow:

argo submit -n argo --watch https://raw.githubusercontent.com/argoproj/argo/master/examples/hello-world.yaml
argo submit -n argo --watch https://raw.githubusercontent.com/argoproj/argo/master/examples/coinflip.yaml
argo submit -n argo --watch https://raw.githubusercontent.com/argoproj/argo/master/examples/loops-maps.yaml
argo list -n argo
argo get xxx-workflow-name-xxx -n argo
argo logs xxx-pod-name-xxx -n argo #from get command above

你也能使用kubectl直接創建Workflow,但是Argo CLI會提供諸如YAML驗證、workflow可視化、參數傳遞、重試以及重新提交、暫停和恢復等額外的功能:

kubectl create -n argo -f https://raw.githubusercontent.com/argoproj/argo/master/examples/hello-world.yaml
kubectl get wf -n argo
kubectl get wf hello-world-xxx -n argo
kubectl get po -n argo --selector=workflows.argoproj.io/workflow=hello-world-xxx
kubectl logs hello-world-yyy -c main -n argo

所以,我們創建一個workflow.yaml文件並把這里的內容全部加進去:

apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
  name: cluster-up
spec:
  serviceAccountName: argo-serviceaccount
  entrypoint: main
  templates:
    - name: main
      steps:
        - - name: rancher-dance
            template: rancher-dance

    - name: rancher-dance
      inputs:
        artifacts:
          - name: kubectl
            path: /bin/kubectl
            mode: 0755
            http:
              url: https://storage.googleapis.com/kubernetes-release/release/v1.18.0/bin/linux/amd64/kubectl
      container:
        image: giantswarm/tiny-tools:3.10
        command:
          - /bin/sh
          - -c
          - |
            echo "Log in to Rancher"
            LOGIN_RESPONSE=$(curl -s "https://$RANCHER_URI/v3-public/localProviders/local?action=login" \
              -H 'content-type: application/json' \
              --data-binary '{"username":"'$RANCHER_USER'","password":"'$RANCHER_PASS'"}')

            LOGIN_TOKEN=$(echo $LOGIN_RESPONSE | jq -r .token)

            echo "Obtain Rancher API token"
            API_RESPONSE=$(curl -s "https://$RANCHER_URI/v3/token" \
              -H 'content-type: application/json' \
              -H "Authorization: Bearer $LOGIN_TOKEN" \
              --data-binary '{"type":"token","description":"automation"}')

            API_TOKEN=$(echo $API_RESPONSE | jq -r .token)

            echo "Configure server-url"
            RANCHER_SERVER_URL="https://$RANCHER_URI/latest/meta-data/public-ipv4"
            curl -s 'https://$RANCHER_URI/v3/settings/server-url' \
              -H 'content-type: application/json' -H "Authorization: Bearer $API_TOKEN" \
              -X PUT --data-binary '{"name":"server-url","value":"'$RANCHER_SERVER_URL'"}'

            echo "Create the cluster, or get the info on an existing cluster"
            CLUSTER_RESPONSE=$(curl -sf "https://$RANCHER_URI/v3/cluster" \
              -H 'content-type: application/json' -H "Authorization: Bearer $API_TOKEN" \
              --data-binary '{"type": "cluster",
                "name": "'$CLUSTER_NAME'",
                "enableClusterAlerting":true,
                "enableClusterMonitoring":false}'\
                || curl -s "https://$RANCHER_URI/v3/cluster?name=$CLUSTER_NAME" \
                -H 'content-type: application/json' \
                -H "Authorization: Bearer $API_TOKEN" \
                | jq ".data | .[]" )

            echo "Extract the cluster ID"
            CLUSTER_ID=$(echo $CLUSTER_RESPONSE | jq -r .id)

            echo "Generate the cluster registration token"
            CLUSTER_JSON=$(curl -s "https://$RANCHER_URI/v3/clusterregistrationtoken" \
              -H 'content-type: application/json' -H "Authorization: Bearer $API_TOKEN" \
              --data-binary '{"type":"clusterRegistrationToken","clusterId":"'$CLUSTER_ID'"}')

            echo "Extract the cluster registration token"
            CLUSTER_TOKEN=$(echo $CLUSTER_JSON | jq -r .token)

            echo "Notify Slack of import"
            curl -s "https://$RANCHER_URI/v3/notifiers" \
              -H 'content-type: application/json' \
              -H "Authorization: Bearer $API_TOKEN" \
              --data-binary  '{"clusterId":"'$CLUSTER_ID'",
                "name":"slack-alerter",
                "namespaceId":"",
                "pagerdutyConfig":null,
                "sendResolved":true,
                "slackConfig":{"url":"'$SLACK_WEBHOOK_URI'"},
                "smtpConfig":null,
                "webhookConfig":null,
                "wechatConfig":null}'

            echo "Retrieve and Apply Manifests"
            kubectl apply -f "https://$RANCHER_URI/v3/import/$CLUSTER_TOKEN.yaml"
        env:
          - name: RANCHER_URI
            value: "x.x.x.x.x.x"
          - name: CLUSTER_NAME
            valueFrom:
              configMapKeyRef:
                name: cluster-name
                key: CLUSTER_NAME
          - name: RANCHER_USER
            valueFrom:
              secretKeyRef:
                name: rancher-credentials
                key: RANCHER_USER
          - name: RANCHER_PASS
            valueFrom:
              secretKeyRef:
                name: rancher-credentials
                key: RANCHER_PASS
          - name: SLACK_WEBHOOK_URI
            value: https://hooks.slack.com/services/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

在一個較高的層次上,這個workflow本質上是將一個腳本作為一個pod在我們的集群中運行,並允許它使用某些變量。

  • 登錄到Rancher API

  • cURL,一個Rancher API令牌,使用TinyTools

  • 將Rancher server的URL設置為一個變量。

  • 提取集群ID

  • 檢索和應用manifest

接下來,我們要把workflow cd到目錄中,然后運行:

argo submit -n argo workflow.yaml

你可以看到workflow在你的集群中配置一個名為cluster-up的pod,它將會與Rancher連接:

在這里插入圖片描述

總結:為什么要在邊緣自動執行任務

現在你已經了解了如何使用k3OS和Argo進行自動化邊緣部署,讓我們來討論一下為什么這種類型的自動化如此重要。在為工業物聯網(IIOT)等業務啟動物理機器時,自動化這些任務是有益的,與機器交互的人是硬件技術人員,而不是雲工程師。

在邊緣,往往物理機器的配置是很費力的——但不應該一次只配置一台。通過這種方法,技術人員可以簡單地插入類似USB的東西,它會啟動一個ISO,然后運行一個腳本來啟動機器的配置,然后注冊到控制平面。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM