是否可以重新启动运行函数脚本的azure kubernete pod?

问题描述 投票:0回答:1

我正在开发一个项目,每次我的应用程序调用我的azure函数时,我都需要这个函数以某种方式重新启动kubernetes中的pod,我不确定如何做到这一点,我正在考虑使用函数运行脚本重新启动这个 Pod,但我不知道如何设置我的函数来执行此操作,或者这是否可能。

我是天蓝色的新手,所以每个帮助都会持续。谢谢你

我尝试在函数中使用 SDK,但无法连接到 Closter,我得到了

 DefaultAzureCredential acquired a token from EnvironmentCredential

[2024-09-20T03:41:52.511Z] C:\Users\Andres_Sanchez1\AppData\Roaming\Python\Python311\site-packages\urllib3\connectionpool.py:1061: InsecureRequestWarning: Unverified HTTPS request is being made to host 'abccall-demo-lgq05iz2.hcp.eastus.azmk8s.io'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html#ssl-warnings
[2024-09-20T03:41:52.514Z]   warnings.warn(
[2024-09-20T03:42:04.837Z] Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<urllib3.connection.HTTPConnection object at 0x000002835461E050>: Failed to establish a new connection: [WinError 10061] No connection could be made because the target machine actively refused it')': /api/v1/namespaces/eks_demo/pods
[2024-09-20T03:42:08.923Z] 401
[2024-09-20T03:42:08.923Z] Unexpected error: HTTPConnectionPool(host='localhost', port=80): Max retries exceeded with url: /api/v1/namespaces/eks_demo/pods (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x000002835461E9D0>: Failed to establish a new connection: [WinError 10061] No connection could be made because the target machine actively refused it'))
[2024-09-20T03:42:08.928Z] {'kind': 'Status', 'apiVersion': 'v1', 'metadata': {}, 'status': 'Failure', 'message': 'Unauthorized', 'reason': 'Unauthorized', 'code': 401}

我能够从azure获取凭据,但我无法与集群通信,这是我的功能代码:

import logging
import os
import azure.functions as func
from kubernetes import client, config
from kubernetes.client.rest import ApiException
from azure.identity import DefaultAzureCredential
import requests
app = func.FunctionApp(http_auth_level=func.AuthLevel.FUNCTION)

@app.route(route="http_trigger")
def http_trigger(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Processing a request to restart a Kubernetes pod using managed identity.')

    # Get pod name and namespace from query parameters
    pod_name = req.params.get('pod_name')
    namespace = req.params.get('namespace', 'default')

    if not pod_name:
        return func.HttpResponse(
            "Please pass a pod_name in the query string.",
            status_code=400
        )

    try:
        # Use ManagedIdentityCredential for managed identity authentication
        credential = DefaultAzureCredential()

        # Get the AKS API server endpoint from environment variables
        aks_api_server = 'https://abccall-demo-lgq05iz2.hcp.eastus.azmk8s.io' # Set this in your Function App settings
        if not aks_api_server:
            return func.HttpResponse("AKS_API_SERVER environment variable is not set.", status_code=500)

        # Get the access token
        token = credential.get_token("https://management.azure.com/.default").token

        # Create a Kubernetes API client configuration
        configuration = client.Configuration()
        configuration.host = aks_api_server
        configuration.verify_ssl = False  # Consider enabling SSL verification in production
        configuration.api_key = {"authorization": f"Bearer {token}"}

        response = requests.get(f"{aks_api_server}/api/v1/namespaces/default/pods", verify=False)  # Change verify=True in production

        print(response.status_code)
        print(response.json())
        # Create the Kubernetes API client
        k8s_client = client.CoreV1Api(client.ApiClient(configuration))

        v1 = client.CoreV1Api()
        pods = v1.list_namespaced_pod(namespace)

        for pod in pods.items:
            print(f"Pod Name: {pod.metadata.name}")
        # Delete the pod to trigger a restart
        logging.info(f"Attempting to restart pod {pod_name} in namespace {namespace}.")
        k8s_client.delete_namespaced_pod(pod_name, namespace, body=client.V1DeleteOptions())

        return func.HttpResponse(
            f"Pod {pod_name} in namespace {namespace} has been restarted.",
            status_code=200
        )

    except ApiException as e:
        logging.error(f"Exception when calling CoreV1Api->delete_namespaced_pod: {e}")
        return func.HttpResponse(
            f"Error: {str(e)}",
            status_code=e.status
    )
    except Exception as e:
        logging.error(f"Unexpected error: {e}")
        return func.HttpResponse(
            f"Error: {str(e)}",
            status_code=500
    )

我希望能够连接到集群并重新启动我的 Pod

python azure function kubernetes
1个回答
0
投票

您需要将托管身份分配给AKS集群中具有足够权限的函数。由于您已经编写了一个 Python 函数来重新启动 pod,因此创建集群后,请为 Azure Function 创建系统分配的托管标识。

az storage account create --name arkofunctionstorage --resource-group arkorg --location eastus --sku Standard_LRS


az functionapp create \
    --resource-group arkorg \
    --consumption-plan-location eastus \
    --runtime python \
    --functions-version 4 \
    --name MyK8sFunctionApp \
    --storage-account arkofunctionstorage \
    --os-type Linux \
    --assign-identity

enter image description here

将必要的角色(Azure Kubernetes 服务 RBAC 集群管理员角色)分配给 Azure Function 的托管标识

az functionapp identity show --name MyK8sFunctionApp --resource-group arkorg --query principalId --output tsv

enter image description here

az role assignment create --assignee 1234-79f2-abcd-5678-54xyzc \
    --scope /subscriptions/abcd-efg-hijk-lmnop-uvwxyz/resourcegroups/arkorg/providers/Microsoft.ContainerService/managedClusters/myAKSCluster \
    --role "Azure Kubernetes Service RBAC Cluster Admin"

enter image description here

接下来,创建集群角色和角色绑定,以便托管身份具有与 Pod 交互所需的权限。

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: function-app-role
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "delete"]
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: function-app-binding
  namespace: default
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: function-app-role
subjects:
- kind: User
  name: 13f2b02a-79f2-47c5-9ad5-54f7a35e30fc
  apiGroup: rbac.authorization.k8s.io

enter image description here

enter image description here

现在使用 Azure Function 代码重新启动 Kubernetes pod。您共享的代码中的问题是身份验证部分并确保 AKS API 服务器通信的 SSL 验证。下面是更新的

import logging
import azure.functions as func
from azure.identity import DefaultAzureCredential
from kubernetes import client, config

def main(req: func.HttpRequest) -> func.HttpResponse:
    try:
        # Get pod name and namespace from query parameters
        pod_name = req.params.get('pod_name')
        namespace = req.params.get('namespace', 'default')

        if not pod_name:
            return func.HttpResponse(
                "Please pass a pod_name in the query string.",
                status_code=400
            )

        
        aks_api_server = 'https://myakscluster-dns-ieevn5ni.hcp.eastus.azmk8s.io'
        
        # Get token using managed identity
        credential = DefaultAzureCredential()
        token = credential.get_token("https://management.azure.com/.default").token

        
        configuration = client.Configuration()
        configuration.host = aks_api_server
        configuration.verify_ssl = True  
        configuration.api_key = {"authorization": f"Bearer {token}"}
        
        
        k8s_client = client.CoreV1Api(client.ApiClient(configuration))

        
        logging.info(f"Attempting to restart pod {pod_name} in namespace {namespace}.")

        # Restart pod by deleting it
        k8s_client.delete_namespaced_pod(pod_name, namespace, body=client.V1DeleteOptions())

        return func.HttpResponse(
            f"Pod {pod_name} in namespace {namespace} has been restarted.",
            status_code=200
        )
    except client.ApiException as e:
        logging.error(f"Exception when calling CoreV1Api->delete_namespaced_pod: {e}")
        return func.HttpResponse(
            f"Error: {str(e)}",
            status_code=e.status
        )
    except Exception as e:
        logging.error(f"Unexpected error: {e}")
        return func.HttpResponse(
            f"Error: {str(e)}",
            status_code=500
        )

构建并运行它

enter image description here

enter image description here

该函数删除指定的pod,会触发k8s重新创建pod

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.