The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

解決一個非常罕見的 Azure Functions Runtime is unreachable 問題

上周我們遇到一個非常罕見的問題,一群人費了九牛二虎之力才徹底釐清案情,並且成功修復問題。我們在部署 Azure Functions 的時候,大部分的情境底下都是正常的,唯獨將站台重新部署到 Linux 平台的 App Service Plan 之後,詭異的狀況就此發生。由於案發過程過於冗長,我打算摘要記錄一下我們遭遇的現況與解決方法。

建立 Function App 的三種方法

  1. 透過 ARM Template

    所有 Azure 部署的核心技術,就是 ARM Template,所有最新、最完整的部署設定,都可以從 ARM Template 找到!

  2. 透過 Azure CLI

    最新版的 Azure CLI 通常可以跟上 ARM Template 的腳步,但還是會慢一點點

  3. 透過 PowerShell Az Module

    最新版的 PowerShell Az Module 通常比 Azure CLI 還要強大,我不知道為什麼 Az 模組就是功能比較強、問題少,而且強型別的設計也確實好用許多,但我就是不愛用。😅

  4. 透過 Azure Portal

    事實上 Azure Portal 的底層主要還是依賴 ARM Template 在運行,只是 Azure Portal 的 UI 變動的很慢,方便歸方便,但完全依賴 Azure Portal 的人,使用新技術是很容易鬼打牆的。

自動部署 Function App 的兩種方法

  1. 使用 Azure Functions Core Tools 工具手動部署

    func azure functionapp publish $name
    
  2. 使用 Azure Pipelines 的 Azure Functions 工作 (Task) 自動部署

問題描述

我們的 Function App 跑在 dotnet-isolated 執行環境下,而且採用 .NET 6.0 版本。

透過 Azure Portal 建立 Function App 時,目前 Runtime 無法選取 .NET Isolated,只能選擇 .NET + 6 而已。

透過 Azure Functions Core Tools 部署 Function App 時,工具會幫我自動調整 Function App 的 Runtime 設定,所以部署完成後是可以跑起來的。

如果你用 Azure Pipelines 的 Azure Functions 工作 (Task) 部署 Function App 的話,預設並不會自動調整 Function App 的 Runtime 設定,所以部署完成後 Function App 的 Runtime 設定不會變更,如果執行模式不同,就會導致 Azure Functions Runtime is unreachable 的問題!

重點是,目前 Azure Portal 無法在建立 Function App 之後手動調整 Runtime 設定,完全看不到選項可以調整,所以你不會在第一時間發現是這個設定有錯。(雷)

但是,當你使用一次 Azure Functions Core Tools 來部署 Function App,問題就會迎刃而解。

重現問題

我們的開發環境、測試環境,原本順利運行好幾週,但我想要重跑一次自動基礎環境部署流程,我原本自信滿滿,自動化部署跑了無數次,我在把資源群組砍掉後重建,就再也起不來了。這下慘了,Function 應用程式怎樣都跑不起來,真的是鬼打牆一整天,一個是我、一位來自上海的技術支援工程師、一位來自台灣的技術支援工程師、兩位負責應用程式開發的工程師,五個人花了 8 小時,才徹底釐清是上述的問題,成本之高啊!🤧

以下是全新環境的部署流程:

  1. 我們透過 ARM Template 部署 Function App,並沒有指定 linuxFxVersion 屬性

    當時不知道有這個屬性存在,也覺得這個設定不重要,因為之前沒設定也跑得好好的,沒想到 Azure Functions Core Tools 部署 Function App 時會幫我自動調整 Function App 的 Runtime 設定!

    這裡的 linuxFxVersion 屬性預設值為 DOTNET|6.0

  2. 啟動 Azure Pipelines 自動建置與部署 Function App

    我是使用 Azure Function Deployment: ARM 進行部署,所以預設並不會自動調整 Function App 的 Runtime 設定,也因此我的 Function App 就爆掉了,完全無法啟動,Azure Portal 會一直出現 Azure Functions Runtime is unreachable 訊息提示,不過即便看了官方的 Troubleshoot error: Azure Functions Runtime is unreachable 文件依然完全沒有幫助。

    此時我們還不知道是 linuxFxVersion 屬性屬性錯誤的問題。

  3. 接下來就是各種參數的排列組合,然後重建 Function App 數十次都沒有效果!

    老實說,我當下有想到嘗試用 Azure Functions Core Tools 來部署,但心理就是不願意嘗試這種作法,因為我就是不想用手動部署環境。也還好我沒有這樣嘗試,否則問題的主因(Root Cause)就有可能找不到了。

    我們一度以為 ARM Template 寫錯了,但一直無法讓服務恢復正常,深深覺得非常困擾!!!😡

  4. 最後嘗試用 Azure Functions Core Tools 來部署,想不到網站復活了!

    經過將近 7 個小時的努力,終於第一次讓服務動起來,而且從 func azure functionapp publish $name 執行過程的訊息中,發現了一行不太顯眼的訊息,發現了他竟然在背景偷偷的幫我調整 App Service 的 linuxFxVersion 屬性,是真的很貼心沒錯啦,但文件要寫啊!(怒)😡

    老實說,如果一開始就用 Azure Functions Core Tools 來部署,也不一定會發現這個小秘密,這 7 個小時實在是經歷太多技術細節了,真的是上帝要你學會這麼多東西,你還不能不接受呢!😅

解決方案

我最終的解決方案有兩個面向,兩種二選一都可以解決問題:

  1. 直接從 ARM Template 調整,建立 Function App 資源時就先指定好 linuxFxVersion 屬性為 DOTNET-ISOLATED|6.0 即可。

  2. 調整 Azure Pipelines 的 Azure Functions 工作 (Task),在部署時自動調整目標 App Service 的 linuxFxVersion 屬性為 DOTNET-ISOLATED|6.0

    Azure Functions - Update a function app with .NET, Python, JavaScript, PowerShell, Java based web applications

    steps:
    - task: AzureFunctionApp@1
      displayName: 'Azure Function App Deploy: myfuncapp1'
      inputs:
        azureSubscription: 'sp-cicd-staging'
        appType: functionAppLinux
        appName: myfuncapp1
        package: '$(System.DefaultWorkingDirectory)/_MyFuncApp1-CI/drop'
        appSettings: '-FUNCTIONS_WORKER_RUNTIME dotnet-isolated'
        configurationStrings: '-linuxFxVersion DOTNET-ISOLATED|6.0'
    

我不期望有多少人看懂我這篇文章,但我希望我以後再也不用透過 Google 查到這篇文章的存在! 😅

希望 Azure 變的更好的 murmur

  1. 要是 Azure Portal 不要這麼雞婆,隱藏他們認為不需要的設定,直接把所有選項都顯示在畫面上,問題可能會少很多。
  2. 要是 Azure Portal 可以更新的即時一點,都說未來要推 dotnet-isolated 了,為什麼到現在還不能在建立資源時選擇這個選項。
  3. 要是 Azure Pipelines 可以雞婆一點,把預設的 linuxFxVersion 設定上去,並顯示在 Log 中,我可以不用查問題查這麼久。
  4. 要是 Azure Functions Core Tools 發行時,可以把變更 linuxFxVersion 屬性的行為變成「警告」,我可能會比較容易看出問題。
  5. 要是 Azure ARM Template 可以要求我一定要加上 linuxFxVersion 屬性,我不會鬼打牆這麼久。

相關連結