Függvény létrehozása Linux rendszerben egyéni tárolóval

Ebben az oktatóanyagban létrehozhatja és üzembe helyezheti a kódot egy Azure Functions Docker-tárolóként egy Linux-alapként szolgáló rendszerkép használatával. Általában egyéni rendszerképet használ, ha a függvények egy adott nyelvi verziót igényelnek, vagy olyan függőséggel vagy konfigurációval rendelkezik, amelyet nem a beépített rendszerkép biztosít.

Azure Functions bármilyen nyelvet vagy futásidőt támogat egyéni kezelők használatával. Bizonyos nyelvek, például az oktatóanyagban használt R programozási nyelv esetében a futásidejű vagy további kódtárakat olyan függőségekként kell telepítenie, amelyek egyéni tároló használatát igénylik.

A függvénykód egyéni Linux-tárolóban való üzembe helyezéséhez Prémium vagy Dedikált (App Service) csomag üzemeltetése szükséges. Ennek az oktatóanyagnak az elvégzése néhány amerikai dollár költségekkel jár az Azure-fiókjában, ami az erőforrások feleslegessé tevésével csökkenthető, ha elkészült.

Használhat egy alapértelmezett Azure App Service is, amely a Linux rendszeren üzemeltetett első függvényének létrehozása oldalon található. A támogatott alapként Azure Functions rendszerképek a Azure Functions rendszerkép-Azure Functions találhatók.

Eben az oktatóanyagban az alábbiakkal fog megismerkedni:

  • Függvényalkalmazás és Docker-fájl létrehozása a Azure Functions Core Tools.
  • Egyéni rendszerkép készítése a Docker használatával.
  • Egyéni rendszerkép közzététele egy tárolójegyzékben.
  • Támogató erőforrások létrehozása az Azure-ban a függvényalkalmazáshoz
  • Függvényalkalmazás üzembe helyezése a Docker Hubból.
  • Alkalmazásbeállítások hozzáadása a függvényalkalmazáshoz.
  • Folyamatos üzembe helyezés engedélyezése.
  • Engedélyezze az SSH-kapcsolatokat a tárolóhoz.
  • Adjon hozzá egy Kimeneti kötést a Queue Storage-hez.
  • Függvényalkalmazás és Docker-fájl létrehozása a Azure Functions Core Tools.
  • Egyéni rendszerkép készítése a Docker használatával.
  • Egyéni rendszerkép közzététele egy tárolójegyzékben.
  • Támogató erőforrások létrehozása az Azure-ban a függvényalkalmazáshoz
  • Függvényalkalmazás üzembe helyezése a Docker Hubból.
  • Alkalmazásbeállítások hozzáadása a függvényalkalmazáshoz.
  • Folyamatos üzembe helyezés engedélyezése.
  • Engedélyezze az SSH-kapcsolatokat a tárolóhoz.

Ezt az oktatóanyagot bármely Windows, macOS vagy Linux rendszerű számítógépen követheti.

A helyi környezet konfigurálása

Mielőtt hozzákezd, a következőkre lesz majd kíváncsi:

  • Node.js, Active LTS és Maintenance LTS verziók (8.11.1 és 10.14.1 ajánlott).
  • Fejlesztői eszközök az Ön által használt nyelvhez. Ez az oktatóanyag az R programozási nyelvet használja példaként.

Virtuális környezet létrehozása és aktiválása

Egy megfelelő mappában futtassa a következő parancsokat a nevű virtuális környezet létrehozásához és aktiválásához .venv . Ügyeljen arra, hogy a Azure Functions által támogatott Python 3,8, 3,7 vagy 3,6-ot használja.

python -m venv .venv
source .venv/bin/activate

Ha a Python nem telepítette a venv csomagot a Linux-disztribúcióban, futtassa a következő parancsot:

sudo apt-get install python3-venv

Az összes további parancsot futtatja ebben az aktivált virtuális környezetben.

A helyi függvényprojekt létrehozása és tesztelése

Egy terminálban vagy parancssorban futtassa az alábbi parancsot a választott nyelvhez egy nevű mappában található függvényalkalmazás-projekt LocalFunctionsProject létrehozásához.

func init LocalFunctionsProject --worker-runtime dotnet --docker
func init LocalFunctionsProject --worker-runtime node --language javascript --docker
func init LocalFunctionsProject --worker-runtime powershell --docker
func init LocalFunctionsProject --worker-runtime python --docker
func init LocalFunctionsProject --worker-runtime node --language typescript --docker

Egy üres mappában futtassa a következő parancsot a Functions-projekt Maven archetype-ból való létrehozásához.

mvn archetype:generate -DarchetypeGroupId=com.microsoft.azure -DarchetypeArtifactId=azure-functions-archetype -DjavaVersion=8 -Ddocker

A -DjavaVersion paraméter jelzi a Functions-runtime-nak, hogy a Java melyik verzióját használja. Használja a -DjavaVersion=11 kapcsolót, ha a függvényeket Java 11-en szeretné futtatni. Ha nem adja meg a értéket, a -DjavaVersion Maven alapértelmezés szerint a Java 8-at használja. További információ: Java-verziók.

Fontos

A cikk befejezéséhez a környezeti változót a JDK megfelelő verziójának telepítési JAVA_HOME helyére kell beállítani.

A Maven az üzembe helyezéshez szükséges projekt létrehozásához szükséges értékeket kéri.
Amikor a rendszer kéri, adja meg a következő értékeket:

Adatkérés Érték Leírás
csoportazonosító com.fabrikam Egy érték, amely egyedileg azonosítja a projektet az összes projektben, a Java csomagelnevezési szabályait követi.
artifactId (összetevő-azonosító) fabrikam-functions Egy érték, amely a jar neve verziószám nélkül.
Változat 1.0-SNAPSHOT Válassza az alapértelmezett értéket.
Csomag com.fabrikam.functions Egy érték, amely a generált függvénykód Java-csomagja. Használja az alapértelmezettet.

A Y megerősítéshez írja be vagy nyomja le az Enter billentyűt.

A Maven létrehozza a projektfájlokat egy új mappában artifactId néven, amely ebben a példában fabrikam-functions a .

func init LocalFunctionsProject --worker-runtime custom --docker

A beállítás létrehoz egy et a projekthez, amely definiál egy megfelelő egyéni tárolót a Azure Functions és a --docker Dockerfile kiválasztott futásidővel.

Lépjen a projektmappába:

cd LocalFunctionsProject
cd fabrikam-functions

Adjon hozzá egy függvényt a projekthez a következő paranccsal, ahol az argumentum a függvény egyedi neve, az argumentum pedig a függvény --name --template eseményindítóját határozza meg. func newlétrehoz egy almappát, amely megegyezik a függvény nevével, amely tartalmazza a projekt választott nyelvének megfelelő kódfájlt, valamint egy nevű konfigurációs fájlt function.jsa fájlban.

func new --name HttpExample --template "HTTP trigger"

Adjon hozzá egy függvényt a projekthez a következő paranccsal, ahol az argumentum a függvény egyedi neve, az argumentum pedig a függvény --name --template eseményindítóját határozza meg. func newA létrehoz egy almappát, amely megegyezik a függvény nevével, amely egy nevű konfigurációsfunction.jstalálható.

func new --name HttpExample --template "HTTP trigger"

Egy szövegszerkesztőben hozzon létre egy fájlt a handler nevű projektmappában. R. Adja hozzá a következőt tartalomként.

library(httpuv)

PORTEnv <- Sys.getenv("FUNCTIONS_CUSTOMHANDLER_PORT")
PORT <- strtoi(PORTEnv , base = 0L)

http_not_found <- list(
  status=404,
  body='404 Not Found'
)

http_method_not_allowed <- list(
  status=405,
  body='405 Method Not Allowed'
)

hello_handler <- list(
  GET = function (request) {
    list(body=paste(
      "Hello,",
      if(substr(request$QUERY_STRING,1,6)=="?name=") 
        substr(request$QUERY_STRING,7,40) else "World",
      sep=" "))
  }
)

routes <- list(
  '/api/HttpExample' = hello_handler
)

router <- function (routes, request) {
  if (!request$PATH_INFO %in% names(routes)) {
    return(http_not_found)
  }
  path_handler <- routes[[request$PATH_INFO]]

  if (!request$REQUEST_METHOD %in% names(path_handler)) {
    return(http_method_not_allowed)
  }
  method_handler <- path_handler[[request$REQUEST_METHOD]]

  return(method_handler(request))
}

app <- list(
  call = function (request) {
    response <- router(routes, request)
    if (!'status' %in% names(response)) {
      response$status <- 200
    }
    if (!'headers' %in% names(response)) {
      response$headers <- list()
    }
    if (!'Content-Type' %in% names(response$headers)) {
      response$headers[['Content-Type']] <- 'text/plain'
    }

    return(response)
  }
)

cat(paste0("Server listening on :", PORT, "...\n"))
runServer("0.0.0.0", PORT, app)

A host.jsmódosítsa a szakaszt úgy, hogy konfigurálja az egyéni kezelő customHandler indítási parancsát.

"customHandler": {
  "description": {
      "defaultExecutablePath": "Rscript",
      "arguments": [
      "handler.R"
    ]
  },
  "enableForwardingHttpRequest": true
}

A függvény helyi teszteléséhez indítsa el a helyi Azure Functions a projektmappa gyökérkönyvtárában található runtime gazdagépen:

func start  
func start  
npm install
npm start
mvn clean package  
mvn azure-functions:run
R -e "install.packages('httpuv', repos='http://cran.rstudio.com/')"
func start

Ha a végpont HttpExample megjelenik a kimenetben, lépjen a következőre: http://localhost:7071/api/HttpExample?name=Functions . A böngészőnek egy "hello" üzenetet kell megjelenítenie, amely a értéket jeleníti meg a lekérdezési Functions name paraméterhez megadott értékkel.

Állítsa le a - gazdagépet a Ctrl C billentyűkombinációval.

A tároló rendszerképének összeállítása és helyi tesztelése

(Nem kötelező) Vizsgálja meg a dockerfile-t a projektmappa gyökerében. A Dockerfile leírja a függvényalkalmazás Linuxon való futtatásához szükséges környezetet. A támogatott alapként Azure Functions rendszerképek teljes listája az alapként Azure Functions oldalon található.

Vizsgálja meg a dockerfile-t a projektmappa gyökerében. A Dockerfile leírja a függvényalkalmazás Linuxon való futtatásához szükséges környezetet. Az egyéni kezelőalkalmazások a mcr.microsoft.com/azure-functions/dotnet:3.0-appservice rendszerképet használják alapként.

Módosítsa a Dockerfile-t az R telepítéséhez. Cserélje le a Dockerfile tartalmát a következőre.

FROM mcr.microsoft.com/azure-functions/dotnet:3.0-appservice 
ENV AzureWebJobsScriptRoot=/home/site/wwwroot \
    AzureFunctionsJobHost__Logging__Console__IsEnabled=true

RUN apt update && \
    apt install -y r-base && \
    R -e "install.packages('httpuv', repos='http://cran.rstudio.com/')"

COPY . /home/site/wwwroot

A projekt gyökérmappában futtassa a docker build parancsot, és adjon meg egy nevet () azurefunctionsimage és egy címkét v1.0.0 (). A <DOCKER_ID> helyére a Docker Hub-fiók azonosítóját írja. Ez a parancs létrehozza a tároló Docker-rendszerképét.

docker build --tag <DOCKER_ID>/azurefunctionsimage:v1.0.0 .

Amikor a parancs befejeződik, helyileg futtathatja az új tárolót.

A build tesztelése érdekében futtassa a rendszerképet egy helyi tárolóban a docker run paranccsal, és cserélje le újra a et a Docker-azonosítójára, és adja hozzá a <DOCKER_ID port -p 8080:80 argumentumot:

docker run -p 8080:80 -it <docker_id>/azurefunctionsimage:v1.0.0

Miután a kép egy helyi tárolóban fut, nyisson meg egy böngészőt a helyre, ahol meg kell jelenni az alább látható http://localhost:8080 helyőrző képnek. A rendszerkép ezen a ponton jelenik meg, mivel a függvény a helyi tárolóban fut, ahogyan az Azure-ban tenné, ami azt jelenti, hogy afunction.jsa tulajdonsággal meghatározott hozzáférési kulccsal van "authLevel": "function" védve. A tároló azonban még nem lett közzétéve egy függvényalkalmazásban az Azure-ban, ezért a kulcs még nem érhető el. Ha a helyi tárolón szeretne tesztelni, állítsa le a docker-t, módosítsa az engedélyezési tulajdonságot a következőre: , építse újra a rendszerképet, "authLevel": "anonymous" és indítsa újra a Docker-t. Ezután állítsa vissza "authLevel": "function" a function.jsa következőn:. További információ: engedélyezési kulcsok.

Helyőrző kép, amely azt jelzi, hogy a tároló helyileg fut

Miután a rendszerkép egy helyi tárolóban fut, lépjen a webhelyre, ahol a korábban is látható http://localhost:8080/api/HttpExample?name=Functions "hello" üzenetnek kell jelen lennie. Mivel a Maven-archetípus egy HTTP által aktivált függvényt hoz létre, amely névtelen engedélyezést használ, akkor is hívhatja a függvényt, ha az a tárolóban fut.

Miután ellenőrizte a függvényalkalmazást a tárolóban, állítsa le a Docker-t a Ctrl C + billentyűkombinációval.

A rendszerkép leküldése Docker Hub

Docker Hub egy tároló-beállításjegyzék, amely lemezképeket tartalmaz, valamint rendszerkép- és tárolószolgáltatásokat biztosít. A rendszerkép megosztásához , beleértve az Azure-beli üzembe helyezést is, le kell azt helyeznie egy regisztrációs adatbázisba.

  1. Ha még nem jelentkezett be a Dockerbe, tegye meg a docker login paranccsal, és cserélje le a adatokat <docker_id> a Docker-azonosítójára. Ez a parancs a felhasználónevét és jelszavát kéri. A "Bejelentkezés sikeres" üzenet megerősíti, hogy bejelentkezett.

    docker login
    
  2. Miután bejelentkezett, a docker push paranccsal Docker Hub le a rendszerképet a docker push paranccsal, és cserélje le a et a <docker_id> Docker-azonosítójára.

    docker push <docker_id>/azurefunctionsimage:v1.0.0
    
  3. A hálózati sebességtől függően az első alkalommal lekért rendszerkép lekért ideje eltarthat néhány percig (a későbbi módosítások leírása sokkal gyorsabb). Amíg várakozik, továbbléphet a következő szakaszra, és létrehozhat Azure-erőforrásokat egy másik terminálban.

Támogató Azure-erőforrások létrehozása a függvényhez

A függvénykód Azure-ban való üzembe helyezéséhez három erőforrást kell létrehoznia:

  • Egy erőforráscsoport, amely a kapcsolódó erőforrások logikai tárolója.
  • Egy Azure Storage-fiók, amely fenntartja a projektek állapotát és egyéb adatait.
  • Egy függvényalkalmazás, amely a függvénykód végrehozás környezetét biztosítja. A függvényalkalmazás a helyi függvényprojekthez van leképezve, és lehetővé teszi a függvények logikai egységként való csoportosítását az erőforrások egyszerűbb kezelése, üzembe helyezése és megosztása érdekében.

Ezeket az elemeket Azure CLI-parancsokkal hozhatja létre. Minden parancs JSON-kimenetet biztosít a befejezéskor.

  1. Jelentkezzen be az Azure-ba az az login paranccsal:

    az login
    
  2. Hozzon létre egy erőforráscsoportot az az group create paranccsal. Az alábbi példa egy nevű erőforráscsoportot hoz létre a AzureFunctionsContainers-rg westeurope régióban. (Az erőforráscsoportot és az erőforrásokat általában a közelében lévő régióban hozza létre, a parancsban elérhető régió az account list-locations használatával.)

    az group create --name AzureFunctionsContainers-rg --location westeurope
    

    Megjegyzés

    Linux- és Windows-alkalmazások nem használhatók ugyanabban az erőforráscsoportban. Ha rendelkezik egy nevű meglévő erőforráscsoporttal egy Windows-függvényalkalmazással vagy AzureFunctionsContainers-rg -webalkalmazással, másik erőforráscsoportot kell használnia.

  3. Hozzon létre egy általános célú tárfiókot az erőforráscsoportban és régióban az az storage account create paranccsal. A következő példában cserélje le a helyére az Önnek <storage_name> megfelelő globálisan egyedi nevet. A neveknek három–24 karakter hosszúságú számokat és csak kisbetűket tartalmazhatnak. Standard_LRS A egy tipikus általános célú fiókot ad meg.

    az storage account create --name <storage_name> --location westeurope --resource-group AzureFunctionsContainers-rg --sku Standard_LRS
    

    Ebben az oktatóanyagban a tárfiók csak néhány USD centet jelent.

  4. Az paranccsal hozzon létre egy Prémium szintű csomag Azure Functions nevű, az Elastic Premium 1 tarifacsomagban ( ), a nyugat-európai régióban ( , vagy használjon egy megfelelő régiót a közelében), valamint egy myPremiumPlan --sku EP1 -location westeurope Linux-tárolóban ( --is-linux ).

    az functionapp plan create --resource-group AzureFunctionsContainers-rg --name myPremiumPlan --location westeurope --number-of-workers 1 --sku EP1 --is-linux
    

    Itt a Premium-csomag van használatban, amely szükség szerint skálázhat. További információk az üzemeltetésről: Azure Functions szolgáltatási csomagok összehasonlítása. A költségek kiszámításához tekintse meg a Functions díjszabási oldalát.

    A parancs egy társított Azure Application Insights-példányt is kiad ugyanabban az erőforráscsoportban, amellyel figyelheti a függvényalkalmazást és megtekintheti a naplókat. További információ: Monitor Azure Functions. A példány nem jár költségekkel, amíg ön nem aktiválja.

Függvényalkalmazás létrehozása és konfigurálása az Azure-ban a rendszerkép használatával

Az Azure-beli függvényalkalmazások kezelik a függvények végrehajtását az üzemeltetési csomagban. Ebben a szakaszban az előző szakaszban található Azure-erőforrások használatával fog függvényalkalmazást létrehozni egy Docker Hub rendszerképből, és konfigurálni egy kapcsolati sztringet az Azure Storage-hoz.

  1. Hozza létre a Függvényalkalmazást az az functionapp create paranccsal. A következő példában cserélje le a helyére a tárfiók előző szakaszában <storage_name> használt nevet. Cserélje le a helyére az Önnek megfelelő globálisan egyedi nevet, a helyére pedig a <app_name> <docker_id> Docker-azonosítóját.

    az functionapp create --name <app_name> --storage-account <storage_name> --resource-group AzureFunctionsContainers-rg --plan myPremiumPlan --runtime <functions runtime stack> --deployment-container-image-name <docker_id>/azurefunctionsimage:v1.0.0
    
    az functionapp create --name <app_name> --storage-account <storage_name> --resource-group AzureFunctionsContainers-rg --plan myPremiumPlan --runtime custom --deployment-container-image-name <docker_id>/azurefunctionsimage:v1.0.0
    

    A deployment-container-image-name paraméter határozza meg a függvényalkalmazáshoz használni szükséges rendszerképet. Az az functionapp config container show paranccsal megtekintheti az üzembe helyezéshez használt rendszerkép információit. Az az functionapp config container set paranccsal másik rendszerképből is üzembe helyezheti az alkalmazást.

  2. Jelenítse meg a létrehozott tárfiók kapcsolati sztringét az az storage account show-connection-string paranccsal. Cserélje le a helyére a fent létrehozott <storage-name> tárfiók nevét:

    az storage account show-connection-string --resource-group AzureFunctionsContainers-rg --name <storage_name> --query connectionString --output tsv
    
  3. Adja hozzá ezt a beállítást a függvényalkalmazáshoz az az functionapp config appsettings set paranccsal. A következő parancsban cserélje le a helyére a függvényalkalmazás nevét, a helyére pedig az előző lépésből származó kapcsolati sztringet (egy hosszú kódolt sztringet, amely <app_name> <connection_string> a "DefaultEndpointProtocol=" karakterláncmal kezdődik):

    az functionapp config appsettings set --name <app_name> --resource-group AzureFunctionsContainers-rg --settings AzureWebJobsStorage=<connection_string>
    

    Tipp

    A Bashben héjváltozóval rögzítheti a kapcsolati sztringet a vágólap használata helyett. Először a következő paranccsal hozzon létre egy változót a kapcsolati sztring használatával:

    storageConnectionString=$(az storage account show-connection-string --resource-group AzureFunctionsContainers-rg --name <storage_name> --query connectionString --output tsv)
    

    Ezután tekintse meg a változót a második parancsban:

    az functionapp config appsettings set --name <app_name> --resource-group AzureFunctionsContainers-rg --settings AzureWebJobsStorage=$storageConnectionString
    
  4. A függvény most már használhatja ezt a kapcsolati sztringet a tárfiók eléréséhez.

Megjegyzés

Ha az egyéni rendszerképet egy privát tárolófiókban teszi közzé, használjon inkább környezeti változókat a Kapcsolati sztringhez a Docker-fájlban. További információ: ENV utasítás. A és a változót is be kell DOCKER_REGISTRY_SERVER_USERNAME DOCKER_REGISTRY_SERVER_PASSWORD állítania. Az értékek használatához újra létre kell hoznia a rendszerképet, le kell pusholnia a rendszerképet a regisztrációs adatbázisba, majd újra kell indítania a függvényalkalmazást az Azure-ban.

A függvények ellenőrzése az Azure-ban

Az Azure-beli függvényalkalmazásban üzembe helyezett rendszerkép most már HTTP-kérésekkel hívhatja meg a függvényt. Mivel a function.js tartalmazza a tulajdonságot, először be kell szereznie a hozzáférési kulcsot (más néven "függvénykulcsot"), és bele kell foglalnia azt URL-paraméterként a végpontra vonatkozó "authLevel": "function" kérésekbe.

  1. A függvény URL-címének lekérése a hozzáférési (function) kulccsal a Azure Portal vagy az Azure CLI használatával az az rest paranccsal.)

    1. Jelentkezzen be a Azure Portal, majd keresse meg és válassza a Függvényalkalmazás lehetőséget.

    2. Válassza ki az ellenőrizni kívánt függvényt.

    3. A bal oldali navigációs panelen válassza a Függvények lehetőséget, majd válassza ki az ellenőrizni kívánt függvényt.

      Válassza ki a függvényt a Azure Portal

    4. Válassza a Függvény URL-címének bekérte lehetőséget.

      A függvény URL-címének lekért Azure Portal

    5. Az előugró ablakban válassza az alapértelmezett (függvénykulcs) lehetőséget, majd másolja az URL-címet a vágólapra. A kulcs a következő sztringet ?code= követi: .

      Az alapértelmezett függvényelérési kulcs kiválasztása

    Megjegyzés

    Mivel a függvényalkalmazás tárolóként van üzembe telepítve, a függvénykód nem változtatható meg a portálon. Ehelyett frissítenie kell a projektet a helyi rendszerképben, újra le kell lekulpelnie a rendszerképet a regisztrációs adatbázisba, majd újra üzembe kell azt üzembe kellnie az Azure-ban. A folyamatos üzembe helyezést egy későbbi szakaszban állíthatja be.

  2. Illessze be a függvény URL-címét a böngésző címsorába, és adja hozzá a paramétert &name=Azure az URL-cím végéhez. A böngészőben meg kell jelenni a "Hello, Azure" szövegnek.

    A függvény által visszaadott válasz a böngészőben.

  3. Az engedélyezés teszteléséhez távolítsa el a paramétert az URL-címből, és ellenőrizze, hogy nem code= kap-e választ a függvénytől.

Az Azure-ba való folyamatos üzembe helyezés engedélyezése

Engedélyezheti, Azure Functions automatikusan frissítse a lemezkép üzembe helyezését, amikor frissíti a rendszerképet a beállításjegyzékben.

  1. Engedélyezze a folyamatos üzembe helyezést az az functionapp deployment container config paranccsal, és cserélje le a et <app_name> a függvényalkalmazás nevére:

    az functionapp deployment container config --enable-cd --query CI_CD_URL --output tsv --name <app_name> --resource-group AzureFunctionsContainers-rg
    

    Ez a parancs lehetővé teszi a folyamatos üzembe helyezést, és visszaadja az üzembe helyezési webhook URL-címét. (Ezt az URL-címet később bármikor lekérheti az az functionapp deployment container show-cd-url paranccsal.)

  2. Másolja az üzembe helyezési webhook URL-címét a vágólapra.

  3. Nyissa Docker Hub,jelentkezzen be, és válassza a tárház lehetőséget a navigációs sávon. Keresse meg és válassza ki a képet, válassza a Webhookok lapot, adjon meg egy webhooknevet, illessze be az URL-címét a Webhook URL-címbe, majd válassza a Létrehozás lehetőséget:

    A webhook hozzáadása a DockerHub-adattárban

  4. Ha a webhook be van állítva, Azure Functions a rendszerképet minden alkalommal újra üzembe Docker Hub.

SSH-kapcsolatok engedélyezése

Az SSH lehetővé teszi a tároló és az ügyfél közötti biztonságos kommunikációt. Ha az SSH engedélyezve van, a speciális eszközök (Kudu App Service használatával csatlakozhat a tárolóhoz. Annak érdekében, hogy SSH-kapcsolaton keresztül könnyedén kapcsolódhat a tárolóhoz, Azure Functions egy olyan alapként szolgáló rendszerképet biztosít, amely már engedélyezve van az SSH-hoz. Csak a Dockerfile-t kell szerkesztenie, majd újraépítenie és újra üzembe kell hoznia a rendszerképet. Ezután a Speciális eszközök (Kudu) használatával csatlakozhat a tárolóhoz

  1. A Docker-fájlban fűzheti hozzá a -appservice sztringet az alapként megadott rendszerképhez az FROM utasításban:

    FROM mcr.microsoft.com/azure-functions/dotnet:3.0-appservice
    
    FROM mcr.microsoft.com/azure-functions/node:2.0-appservice
    
    FROM mcr.microsoft.com/azure-functions/powershell:2.0-appservice
    
    FROM mcr.microsoft.com/azure-functions/python:2.0-python3.7-appservice
    
    FROM mcr.microsoft.com/azure-functions/node:2.0-appservice
    
  2. Építse újra a rendszerképet az paranccsal, és cserélje le a docker build <docker_id> et a Docker-azonosítójára:

    docker build --tag <docker_id>/azurefunctionsimage:v1.0.0 .
    
  3. A frissített rendszerképet a Docker Hub, amely jelentősen kevesebb időt fog venni, mint az első leküldés, csak a kép frissített szegmensei lesznek feltöltve.

    docker push <docker_id>/azurefunctionsimage:v1.0.0
    
  4. Azure Functions automatikusan újra üzembe üzembe a képet a függvényalkalmazásban; A folyamat kevesebb mint egy perc alatt le zajlik.

  5. Egy böngészőben nyissa meg a et, és cserélje le a https://<app_name>.scm.azurewebsites.net/ <app_name> et az egyedi nevére. Ez az URL-cím a függvényalkalmazás tárolójának Speciális eszközök (Kudu) végpontja.

  6. Jelentkezzen be az Azure-fiókjába, majd válassza ki az SSH-t, hogy kapcsolatot létesítsen a tárolóval. A csatlakozás néhány percig is eltelhet, ha az Azure még frissíti a tároló rendszerképét.

  7. Miután létrejött a kapcsolat a tárolóval, futtassa az top parancsot az aktuálisan futó folyamatok megtekintéséhez.

    SSH-munkamenetben futó legfelső szintű Linux-parancs

Írás Azure Storage-üzenetsorba

Azure Functions lehetővé teszi a függvények más Azure-szolgáltatásokhoz és -erőforrásokhoz való csatlakoztatását anélkül, hogy saját integrációs kódot kellene írnia. Ezek a kötések, amelyek a bemenetet és a kimenetet is képviselik, deklarálva vannak a függvénydefinícióban. A kötések adatai a függvények számára paraméterekként vannak megadva. Az eseményindítók speciális bemeneti kötések. Bár egy függvény csak egy eseményindítóval rendelkezik, több bemeneti és kimeneti kötéssel is rendelkezik. További információ: Azure Functions és kötési fogalmak.

Ez a szakasz bemutatja, hogyan integrálhatja a függvényt egy Azure Storage-üzenetsokkal. Az ehhez a függvényhez adott kimeneti kötés adatokat ír egy HTTP-kérésből az üzenetsorban lévő üzenetbe.

Az Azure Storage-beli kapcsolatok karakterláncának beolvasása

Korábban létrehozott egy Azure Storage-fiókot, amelyet a Function alkalmazás használ. A fiókhoz tartozó kapcsolatok karakterlánca biztonságosan tárolódik az Azure-beli alkalmazás beállításaiban. Ha letölti a beállítást a fájl local.settings.jsjában , akkor a függvény helyi futtatásakor ugyanazzal a fiókkal tud írni egy tárolási várólistára.

  1. A projekt gyökeréből futtassa a következő parancsot, és cserélje le a <app_name> függvényt az előző rövid útmutatóból származó Function alkalmazás nevére. Ez a parancs felülírja a fájlban lévő összes meglévő értéket.

    func azure functionapp fetch-app-settings <app_name>
    
  2. Nyissa meg a local.settings.jst , és keresse meg a nevű értéket AzureWebJobsStorage , amely a Storage-fiókhoz tartozó kapcsolatok karakterlánca. A AzureWebJobsStorage jelen cikk más részeiben a nevet és a kapcsolatok karakterláncát kell használnia.

Fontos

Mivel local.settings.jsaz Azure-ból letöltött titkokat tartalmaz, mindig kizárják ezt a fájlt a forrás vezérlőelemből. A helyi functions projekttel létrehozott . gitignore fájl alapértelmezés szerint kizárja a fájlt.

Kötési bővítmények regisztrálása

A HTTP-és időzítő-eseményindítók kivételével a kötések kiterjesztési csomagként vannak implementálva. Futtassa a következő DotNet-csomag hozzáadása parancsot a terminál ablakban a tárolási bővítmény csomagjának a projekthez való hozzáadásához.

dotnet add package Microsoft.Azure.WebJobs.Extensions.Storage --version 3.0.4

Most hozzáadhatja a tárolási kimeneti kötést a projekthez.

Kimeneti kötési definíció hozzáadása a függvényhez

Bár a függvények csak egy triggerrel rendelkezhetnek, több bemeneti és kimeneti kötéssel is rendelkezhet, amelyek lehetővé teszik más Azure-szolgáltatásokhoz és-erőforrásokhoz való csatlakozást az egyéni integrációs kód írása nélkül.

Ezeket a kötéseket a Function mappában található fájl function.js deklarálhatja. Az előző rövid útmutatóból a HttpExample mappában található fájl function.js két kötést tartalmaz a bindings gyűjteményben:

"bindings": [
    {
        "authLevel": "function",
        "type": "httpTrigger",
        "direction": "in",
        "name": "req",
        "methods": [
            "get",
            "post"
        ]
    },
    {
        "type": "http",
        "direction": "out",
        "name": "res"
    }
]
"scriptFile": "__init__.py",
"bindings": [
    {
        "authLevel": "function",
        "type": "httpTrigger",
        "direction": "in",
        "name": "req",
        "methods": [
            "get",
            "post"
        ]
    },
    {
        "type": "http",
        "direction": "out",
        "name": "$return"
    }
"bindings": [
  {
    "authLevel": "function",
    "type": "httpTrigger",
    "direction": "in",
    "name": "Request",
    "methods": [
      "get",
      "post"
    ]
  },
  {
    "type": "http",
    "direction": "out",
    "name": "Response"
  }
]

Minden kötéshez legalább egy típus, egy irány és egy név tartozik. A fenti példában az első kötés típusa az httpTrigger irány in . Az in iránynál name adja meg egy bemeneti paraméter nevét, amelyet a rendszer az eseményindító által meghívott függvénynek továbbít.

A gyűjtemény második kötésének neve res . Ez a http kötés egy kimeneti kötés ( out ), amely a http-válasz írására szolgál.

Ha a függvényből szeretne írni egy Azure Storage-várólistába, adjon hozzá egy out típusú kötést a következő queue msg kódban látható módon:

    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "res"
    },
    {
      "type": "queue",
      "direction": "out",
      "name": "msg",
      "queueName": "outqueue",
      "connection": "AzureWebJobsStorage"
    }
  ]
}

A gyűjtemény második kötése http az iránysal van out megadva, ebben az esetben a speciális name $return érték azt jelzi, hogy ez a kötés a függvény visszatérési értékét használja, nem pedig bemeneti paramétert.

Ha a függvényből szeretne írni egy Azure Storage-várólistába, adjon hozzá egy out típusú kötést a következő queue msg kódban látható módon:

"bindings": [
  {
    "authLevel": "anonymous",
    "type": "httpTrigger",
    "direction": "in",
    "name": "req",
    "methods": [
      "get",
      "post"
    ]
  },
  {
    "type": "http",
    "direction": "out",
    "name": "$return"
  },
  {
    "type": "queue",
    "direction": "out",
    "name": "msg",
    "queueName": "outqueue",
    "connection": "AzureWebJobsStorage"
  }
]

A gyűjtemény második kötésének neve res . Ez a http kötés egy kimeneti kötés ( out ), amely a http-válasz írására szolgál.

Ha a függvényből szeretne írni egy Azure Storage-várólistába, adjon hozzá egy out típusú kötést a következő queue msg kódban látható módon:

    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "Request",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "Response"
    },
    {
      "type": "queue",
      "direction": "out",
      "name": "msg",
      "queueName": "outqueue",
      "connection": "AzureWebJobsStorage"
    }
  ]
}

Ebben az esetben msg a függvény kimeneti argumentumként van megadva. A queue típushoz meg kell adnia a várólista nevét is, és meg kell queueName adnia az Azure Storage-kapcsolatok nevét ( local.settings.json) connection .

A C# Class Library-projektekben a kötések kötési attribútumokként vannak definiálva a Function metódusban. A függvények által igényelt fájl function.js automatikusan létrejön ezen attribútumok alapján.

Nyissa meg a HttpExample. cs projektfájlt, és adja hozzá a következő paramétert a Run metódus-definícióhoz:

[Queue("outqueue"),StorageAccount("AzureWebJobsStorage")] ICollector<string> msg,

A msg paraméter egy ICollector<T> típus, amely a függvény befejeződése után kimeneti kötésbe írt üzenetek gyűjteményét jelöli. Ebben az esetben a kimenet egy nevű tárolási várólista outqueue . A Storage-fiókhoz tartozó kapcsolatok karakterláncát a következő értékre állítja be: StorageAccountAttribute . Ez az attribútum azt a beállítást jelzi, amely a Storage-fiókhoz tartozó kapcsolatok sztringjét tartalmazza, és alkalmazható az osztály, a metódus vagy a paraméter szintjén. Ebben az esetben kihagyhatja, StorageAccountAttribute mert már használja az alapértelmezett Storage-fiókot.

A futtatási metódus definíciójának ekkor a következőhöz hasonlóan kell kinéznie:

[FunctionName("HttpExample")]
public static async Task<IActionResult> Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req, 
    [Queue("outqueue"),StorageAccount("AzureWebJobsStorage")] ICollector<string> msg, 
    ILogger log)

Egy Java-projektben a kötések kötési megjegyzésekként vannak definiálva a Function metódusban. A fájl function.js ezután automatikusan létrejön a jegyzetek alapján.

Keresse meg a függvény kódját a src/Main/Java területen, nyissa meg a function. Java projektfájlt, és adja hozzá a következő paramétert a run metódus-definícióhoz:

@QueueOutput(name = "msg", queueName = "outqueue", connection = "AzureWebJobsStorage") OutputBinding<String> msg

A msg paraméter egy OutputBinding<T> típus, amely a függvény befejeződése után üzenetként írt karakterláncok gyűjteményét jelöli. Ebben az esetben a kimenet egy nevű tárolási várólista outqueue . A Storage-fiókhoz tartozó kapcsolatok karakterláncát a metódus állítja be connection . A felhasználói karakterlánc helyett adja meg a Storage-fiók kapcsolatok sztringjét tartalmazó alkalmazásbeállítás értékét.

A run metódus definíciójának ekkor az alábbi példához hasonlóan kell kinéznie:

@FunctionName("HttpTrigger-Java")
public HttpResponseMessage run(
        @HttpTrigger(name = "req", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.FUNCTION)  
        HttpRequestMessage<Optional<String>> request, 
        @QueueOutput(name = "msg", queueName = "outqueue", connection = "AzureWebJobsStorage") 
        OutputBinding<String> msg, final ExecutionContext context) {
    ...
}

Kód hozzáadása a kimeneti kötéshez

Az üzenetsor kötésének definiálása után frissítheti a függvényt, hogy megkapja a kimeneti paramétert, és üzeneteket írjon msg az üzenetsorba.

Frissítse az \ _ _ init _ _ . HttpExample -t, hogy az megfeleljen a következő kódnak, adja hozzá a msg paramétert a függvény definíciójában és msg.set(name) az if name: utasításban.

import logging

import azure.functions as func


def main(req: func.HttpRequest, msg: func.Out[func.QueueMessage]) -> str:

    name = req.params.get('name')
    if not name:
        try:
            req_body = req.get_json()
        except ValueError:
            pass
        else:
            name = req_body.get('name')

    if name:
        msg.set(name)
        return func.HttpResponse(f"Hello {name}!")
    else:
        return func.HttpResponse(
            "Please pass a name on the query string or in the request body",
            status_code=400
        )

A paraméter a (z msg ) példánya azure.functions.InputStream class . A set metódus egy karakterlánc-üzenetet ír a várólistába, ebben az esetben az URL-lekérdezési karakterláncban szereplő függvénynek átadott nevet.

msgHozzon létre egy olyan kódot, amely a kimeneti kötési objektumot használja az üzenetsor context.bindings létrehozásához. Adja hozzá ezt a kódot az context.res utasítás előtt.

// Add a message to the Storage queue,
// which is the name passed to the function.
context.bindings.msg = (req.query.name || req.body.name);

Ezen a ponton a függvénynek a következőképpen kell kinéznie:

module.exports = async function (context, req) {
    context.log('JavaScript HTTP trigger function processed a request.');

    if (req.query.name || (req.body && req.body.name)) {
        // Add a message to the Storage queue,
        // which is the name passed to the function.
        context.bindings.msg = (req.query.name || req.body.name);
        context.res = {
            // status: 200, /* Defaults to 200 */
            body: "Hello " + (req.query.name || req.body.name)
        };
    }
    else {
        context.res = {
            status: 400,
            body: "Please pass a name on the query string or in the request body"
        };
    }
};

msgHozzon létre egy olyan kódot, amely a kimeneti kötési objektumot használja az üzenetsor context.bindings létrehozásához. Adja hozzá ezt a kódot az context.res utasítás előtt.

context.bindings.msg = name;

Ezen a ponton a függvénynek a következőképpen kell kinéznie:

import { AzureFunction, Context, HttpRequest } from "@azure/functions"

const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> {
    context.log('HTTP trigger function processed a request.');
    const name = (req.query.name || (req.body && req.body.name));

    if (name) {
        // Add a message to the storage queue, 
        // which is the name passed to the function.
        context.bindings.msg = name; 
        // Send a "hello" response.
        context.res = {
            // status: 200, /* Defaults to 200 */
            body: "Hello " + (req.query.name || req.body.name)
        };
    }
    else {
        context.res = {
            status: 400,
            body: "Please pass a name on the query string or in the request body"
        };
    }
};

export default httpTrigger;

Adja hozzá a parancsmagot használó kódot, amely a Push-OutputBinding kimeneti kötés használatával szöveget ír a várólistára msg . Adja hozzá ezt a kódot, mielőtt beállítja az OK állapotot az if utasításban.

$outputMsg = $name
Push-OutputBinding -name msg -Value $outputMsg

Ezen a ponton a függvénynek a következőképpen kell kinéznie:

using namespace System.Net

# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)

# Write to the Azure Functions log stream.
Write-Host "PowerShell HTTP trigger function processed a request."

# Interact with query parameters or the body of the request.
$name = $Request.Query.Name
if (-not $name) {
    $name = $Request.Body.Name
}

if ($name) {
    # Write the $name value to the queue, 
    # which is the name passed to the function.
    $outputMsg = $name
    Push-OutputBinding -name msg -Value $outputMsg

    $status = [HttpStatusCode]::OK
    $body = "Hello $name"
}
else {
    $status = [HttpStatusCode]::BadRequest
    $body = "Please pass a name on the query string or in the request body."
}

# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = $status
    Body = $body
})

Adjon hozzá egy olyan kódot, amely a msg kimeneti kötési objektumot használja üzenetsor-üzenet létrehozásához. Adja hozzá ezt a kódot a metódus visszaadása előtt.

if (!string.IsNullOrEmpty(name))
{
    // Add a message to the output collection.
    msg.Add(string.Format("Name passed to the function: {0}", name));
}

Ezen a ponton a függvénynek a következőképpen kell kinéznie:

[FunctionName("HttpExample")]
public static async Task<IActionResult> Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req, 
    [Queue("outqueue"),StorageAccount("AzureWebJobsStorage")] ICollector<string> msg, 
    ILogger log)
{
    log.LogInformation("C# HTTP trigger function processed a request.");

    string name = req.Query["name"];

    string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
    dynamic data = JsonConvert.DeserializeObject(requestBody);
    name = name ?? data?.name;

    if (!string.IsNullOrEmpty(name))
    {
        // Add a message to the output collection.
        msg.Add(string.Format("Name passed to the function: {0}", name));
    }
    return name != null
        ? (ActionResult)new OkObjectResult($"Hello, {name}")
        : new BadRequestObjectResult("Please pass a name on the query string or in the request body");
}

Most az új msg paraméter használatával írhatja a függvény kódjából a kimeneti kötést. Adja hozzá a következő kódrészletet a sikeres válaszként, hogy hozzáadja az értékét name a msg kimeneti kötéshez.

msg.setValue(name);

Ha kimeneti kötést használ, nem kell használnia az Azure Storage SDK kódját a hitelesítéshez, a várólista-hivatkozás beszerzéséhez vagy az adatíráshoz. A functions futtatókörnyezet és a várólista kimeneti kötése elvégzi ezeket a feladatokat.

A run metódusnak most az alábbi példához hasonlóan kell kinéznie:

public HttpResponseMessage run(
        @HttpTrigger(name = "req", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS) 
        HttpRequestMessage<Optional<String>> request, 
        @QueueOutput(name = "msg", queueName = "outqueue", 
        connection = "AzureWebJobsStorage") OutputBinding<String> msg, 
        final ExecutionContext context) {
    context.getLogger().info("Java HTTP trigger processed a request.");

    // Parse query parameter
    String query = request.getQueryParameters().get("name");
    String name = request.getBody().orElse(query);

    if (name == null) {
        return request.createResponseBuilder(HttpStatus.BAD_REQUEST)
        .body("Please pass a name on the query string or in the request body").build();
    } else {
        // Write the name to the message queue. 
        msg.setValue(name);

        return request.createResponseBuilder(HttpStatus.OK).body("Hello, " + name).build();
    }
}

A tesztek frissítése

Mivel az archetípus is létrehoz egy tesztet, frissítenie kell ezeket a teszteket az új paraméter a msg run metódus aláírásában való kezeléséhez.

Keresse meg a kód helyét az src/test/Java területen, nyissa meg a function. Java projektfájlt, és cserélje le a kód sorát a //Invoke következő kóddal.

@SuppressWarnings("unchecked")
final OutputBinding<String> msg = (OutputBinding<String>)mock(OutputBinding.class);
final HttpResponseMessage ret = new Function().run(req, msg, context);

A rendszerkép frissítése a beállításjegyzékben

  1. A gyökérmappában futtassa újra a parancsot, és ezúttal frissítse a címkében lévő docker build verziót a következőre: v1.0.1 . Ahogy korábban, cserélje <docker_id> le a helyére a Docker Hub-fiókjának azonosítóját:

    docker build --tag <docker_id>/azurefunctionsimage:v1.0.1 .
    
  2. A frissített rendszerkép visszaküldése az adattárba a docker push következővel:

    docker push <docker_id>/azurefunctionsimage:v1.0.1
    
  3. Mivel konfigurálta a folyamatos teljesítést, a regisztrációs adatbázisban a rendszerkép frissítése automatikusan frissíti a függvényalkalmazást az Azure-ban.

Az üzenet megtekintése az Azure Storage üzenetsorában

Egy böngészőben használja ugyanazt az URL-címet, mint korábban a függvény meghívásakor. A böngészőnek ugyanazt a választ kell megjelenítenie, mint korábban, mert nem módosítja a függvénykódnak ezt a részét. A hozzáadott kód azonban az URL-paraméter használatával írt üzenetet a name outqueue tárolási üzenetsorba.

Az üzenetsort megtekintheti a Azure Portal a következő Microsoft Azure Storage Explorer. Az üzenetsort az Azure CLI-ban is megtekintheti a következő lépésekben leírtak szerint:

  1. Nyissa meg a függvényprojekt local.setting.jsfájlban, és másolja a kapcsolati sztring értékét. Egy terminálban vagy parancsablakban futtassa a következő parancsot egy nevű környezeti változó létrehozásához, amely az adott kapcsolati sztringet a helyére AZURE_STORAGE_CONNECTION_STRING írja <MY_CONNECTION_STRING> be. (Ez a környezeti változó azt jelenti, hogy a argumentum használatával nem kell minden további parancshoz megszabadni a kapcsolati --connection-string sztringet.)

    export AZURE_STORAGE_CONNECTION_STRING="<MY_CONNECTION_STRING>"
    
  2. (Nem kötelező) Az az storage queue list paranccsal megtekintheti a fiókjában lévő Storage-üzenetsorokat. A parancs kimenetének tartalmaznia kell egy nevű üzenetsort, amely akkor jött létre, amikor a függvény az első üzenetét ebbe az outqueue üzenetsorba írta.

    az storage queue list --output tsv
    
  3. A paranccsal olvassa be az üzenetet ebből az üzenetsorból, amelynek a függvény korábbi tesztelése során az storage message get használt első nevének kell lennie. A parancs beolvassa és eltávolítja az első üzenetet az üzenetsorból.

    echo `echo $(az storage message get --queue-name outqueue -o tsv --query '[].{Message:content}') | base64 --decode`
    

    Mivel az üzenet törzse base64kódolású, az üzenetet a megjelenítés előtt dekódolni kell. A végrehajtása után az storage message get az üzenet el lesz távolítva az üzenetsorból. Ha csak egy üzenet volt a-ban, akkor a parancs második futtatásakor nem fog üzenetet lekérni, hanem outqueue hibaüzenetet kap.

Az erőforrások eltávolítása

Ha továbbra is használni szeretné az Azure-függvényt az oktatóanyagban létrehozott erőforrásokkal, ezeket az erőforrásokat a helyén hagyhatja. Mivel prémium szintű előfizetést hozott létre a Azure Functions, a folyamatos költségek napi egy-két USD-t fognak fizetni.

A folyamatos költségek elkerülése érdekében törölje az erőforráscsoportot a csoportban lévő összes erőforrás AzureFunctionsContainer-rg törléséhez:

az group delete --name AzureFunctionsContainer-rg

Következő lépések