مراقبة مجموعة Nexus Kubernetes

تتكون كل مجموعة Nexus Kubernetes من طبقات متعددة:

  • الأجهزة الظاهرية (VMs)
  • طبقة Kubernetes
  • جرابات التطبيق

Screenshot of Sample Nexus Kubernetes cluster.

الشكل: عينة نظام مجموعة Nexus Kubernetes

على مثيل، يتم تسليم مجموعات Nexus Kubernetes مع حل مراقبة Container Insights اختياري. يلتقط Container Insights السجلات والمقاييس من مجموعات وأحمال عمل Nexus Kubernetes. إنها لتقديرك فقط ما إذا كنت تريد تمكين هذه الأدوات أو توزيع مكدس بيانات تتبع الاستخدام الخاص بك.

يبدو نظام مجموعة Nexus Kubernetes مع أداة مراقبة Azure كما يلي:

Screenshot of Nexus Kubernetes cluster with Monitoring Tools.

الشكل: مجموعة Nexus Kubernetes مع أدوات المراقبة

إلحاق الملحق ب CLI باستخدام مصادقة الهوية المدارة

وثائق للبدء ب Azure CLI، وكيفية تثبيته عبر أنظمة تشغيل متعددة، وكيفية تثبيت ملحقات CLI.

تثبيت أحدث إصدار من ملحقات CLI الضرورية.

مراقبة مجموعة Nexus Kubernetes - طبقة الجهاز الظاهري

يوفر دليل الكيفية هذا الخطوات والبرامج النصية للأداة المساعدة إلى Arc لتوصيل الأجهزة الظاهرية لمجموعة Nexus Kubernetes ب Azure وتمكين وكلاء المراقبة لمجموعة سجلات النظام من هذه الأجهزة الظاهرية باستخدام عامل مراقبة Azure. تسجل الإرشادات المزيد من التفاصيل حول كيفية إعداد جمع بيانات السجل في مساحة عمل Log Analytics.

توفر لك الموارد التالية الدعم:

  • arc-connect.env: استخدم ملف القالب هذا لإنشاء متغيرات البيئة التي تحتاجها البرامج النصية المضمنة

export SUBSCRIPTION_ID=""
export SERVICE_PRINCIPAL_ID=""
export SERVICE_PRINCIPAL_SECRET=""
export RESOURCE_GROUP=""
export TENANT_ID=""
export LOCATION=""
export INSTALL_AZURE_MONITOR_AGENT="true"
export PROXY_URL=""
export NAMESPACE=""
export AZURE_MONITOR_AGENT_VERSION="1.24.2"
export CONNECTEDMACHINE_AZCLI_VERSION="0.6.0"
  • dcr.sh: استخدم هذا البرنامج النصي لإنشاء قاعدة تجميع البيانات (DCR) لتكوين مجموعة syslog

#!/bin/bash
set -e

SUBSCRIPTION_ID="${SUBSCRIPTION_ID:?SUBSCRIPTION_ID must be set}"
SERVICE_PRINCIPAL_ID="${SERVICE_PRINCIPAL_ID:?SERVICE_PRINCIPAL_ID must be set}"
SERVICE_PRINCIPAL_SECRET="${SERVICE_PRINCIPAL_SECRET:?SERVICE_PRINCIPAL_SECRET must be set}"
RESOURCE_GROUP="${RESOURCE_GROUP:?RESOURCE_GROUP must be set}"
TENANT_ID="${TENANT_ID:?TENANT_ID must be set}"
LOCATION="${LOCATION:?LOCATION must be set}"
LAW_RESOURCE_ID="${LAW_RESOURCE_ID:?LAW_RESOURCE_ID must be set}"
DCR_NAME=${DCR_NAME:-${RESOURCE_GROUP}-syslog-dcr}

az login --service-principal -u "${SERVICE_PRINCIPAL_ID}" -p "${SERVICE_PRINCIPAL_SECRET}" -t "${TENANT_ID}"

az account set -s "${SUBSCRIPTION_ID}"

az extension add --name monitor-control-service

RULEFILE=$(mktemp)
tee "${RULEFILE}" <<EOF
{
  "location": "${LOCATION}",
  "properties": {
    "dataSources": {
      "syslog": [
        {
          "name": "syslog",
          "streams": [
            "Microsoft-Syslog"
          ],
          "facilityNames": [
            "auth",
            "authpriv",
            "cron",
            "daemon",
            "mark",
            "kern",
            "local0",
            "local1",
            "local2",
            "local3",
            "local4",
            "local5",
            "local6",
            "local7",
            "lpr",
            "mail",
            "news",
            "syslog",
            "user",
            "uucp"
          ],
          "logLevels": [
            "Info",
            "Notice",
            "Warning",
            "Error",
            "Critical",
            "Alert",
            "Emergency"
          ]
        }
      ]
    },
    "destinations": {
      "logAnalytics": [
        {
          "workspaceResourceId": "${LAW_RESOURCE_ID}",
          "name": "centralWorkspace"
        }
      ]
    },
    "dataFlows": [
      {
        "streams": [
          "Microsoft-Syslog"
        ],
        "destinations": [
          "centralWorkspace"
        ]
      }
    ]
  }
}

EOF

az monitor data-collection rule create --name "${DCR_NAME}" --resource-group "${RESOURCE_GROUP}" --location "${LOCATION}" --rule-file "${RULEFILE}" -o tsv --query id

rm -rf "${RULEFILE}"
  • assign.sh: استخدم البرنامج النصي لإنشاء نهج لربط DCR بجميع الخوادم الممكنة بواسطة Arc في مجموعة موارد

#!/bin/bash
set -e

SUBSCRIPTION_ID="${SUBSCRIPTION_ID:?SUBSCRIPTION_ID must be set}"
SERVICE_PRINCIPAL_ID="${SERVICE_PRINCIPAL_ID:?SERVICE_PRINCIPAL_ID must be set}"
SERVICE_PRINCIPAL_SECRET="${SERVICE_PRINCIPAL_SECRET:?SERVICE_PRINCIPAL_SECRET must be set}"
RESOURCE_GROUP="${RESOURCE_GROUP:?RESOURCE_GROUP must be set}"
TENANT_ID="${TENANT_ID:?TENANT_ID must be set}"
LOCATION="${LOCATION:?LOCATION must be set}"
DCR_NAME=${DCR_NAME:-${RESOURCE_GROUP}-syslog-dcr}
POLICY_NAME=${POLICY_NAME:-${DCR_NAME}-policy}

az login --service-principal -u "${SERVICE_PRINCIPAL_ID}" -p "${SERVICE_PRINCIPAL_SECRET}" -t "${TENANT_ID}"

az account set -s "${SUBSCRIPTION_ID}"

DCR=$(az monitor data-collection rule show --name "${DCR_NAME}" --resource-group "${RESOURCE_GROUP}" -o tsv --query id)

PRINCIPAL=$(az policy assignment create \
  --name "${POLICY_NAME}" \
  --display-name "${POLICY_NAME}" \
  --resource-group "${RESOURCE_GROUP}" \
  --location "${LOCATION}" \
  --policy "d5c37ce1-5f52-4523-b949-f19bf945b73a" \
  --assign-identity \
  -p "{\"dcrResourceId\":{\"value\":\"${DCR}\"}}" \
  -o tsv --query identity.principalId)

required_roles=$(az policy definition show -n "d5c37ce1-5f52-4523-b949-f19bf945b73a" --query policyRule.then.details.roleDefinitionIds -o tsv)
for roleId in $(echo "$required_roles"); do
  az role assignment create \
    --role "${roleId##*/}" \
    --assignee-object-id "${PRINCIPAL}" \
    --assignee-principal-type "ServicePrincipal" \
    --scope /subscriptions/"$SUBSCRIPTION_ID"/resourceGroups/"$RESOURCE_GROUP"
done
  • install.sh: تثبيت عامل مراقبة Azure على كل جهاز ظاهري لجمع بيانات المراقبة من أجهزة Azure الظاهرية.
#!/bin/bash
set -e

function create_secret() {
  kubectl apply -f - -n "${NAMESPACE}" <<EOF
apiVersion: v1
kind: Secret
metadata:
  name: naks-vm-telemetry
type: Opaque
stringData:
  SUBSCRIPTION_ID: "${SUBSCRIPTION_ID}"
  SERVICE_PRINCIPAL_ID: "${SERVICE_PRINCIPAL_ID}"
  SERVICE_PRINCIPAL_SECRET: "${SERVICE_PRINCIPAL_SECRET}"
  RESOURCE_GROUP: "${RESOURCE_GROUP}"
  TENANT_ID: "${TENANT_ID}"
  LOCATION: "${LOCATION}"
  PROXY_URL: "${PROXY_URL}"
  INSTALL_AZURE_MONITOR_AGENT: "${INSTALL_AZURE_MONITOR_AGENT}"
  VERSION: "${AZURE_MONITOR_AGENT_VERSION}"
  CONNECTEDMACHINE_AZCLI_VERSION: "${CONNECTEDMACHINE_AZCLI_VERSION}"
EOF
}

function create_daemonset() {
  kubectl apply -f - -n "${NAMESPACE}" <<EOF
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: naks-vm-telemetry
  labels:
    k8s-app: naks-vm-telemetry
spec:
  selector:
    matchLabels:
      name: naks-vm-telemetry
  template:
    metadata:
      labels:
        name: naks-vm-telemetry
    spec:
      hostNetwork: true
      hostPID: true
      containers:
        - name: naks-vm-telemetry
          image: mcr.microsoft.com/oss/mirror/docker.io/library/ubuntu:20.04
          env:
            - name: SUBSCRIPTION_ID
              valueFrom:
                secretKeyRef:
                  name: naks-vm-telemetry
                  key: SUBSCRIPTION_ID
            - name: SERVICE_PRINCIPAL_ID
              valueFrom:
                secretKeyRef:
                  name: naks-vm-telemetry
                  key: SERVICE_PRINCIPAL_ID
            - name: SERVICE_PRINCIPAL_SECRET
              valueFrom:
                secretKeyRef:
                  name: naks-vm-telemetry
                  key: SERVICE_PRINCIPAL_SECRET
            - name: RESOURCE_GROUP
              valueFrom:
                secretKeyRef:
                  name: naks-vm-telemetry
                  key: RESOURCE_GROUP
            - name: TENANT_ID
              valueFrom:
                secretKeyRef:
                  name: naks-vm-telemetry
                  key: TENANT_ID
            - name: LOCATION
              valueFrom:
                secretKeyRef:
                  name: naks-vm-telemetry
                  key: LOCATION
            - name: PROXY_URL
              valueFrom:
                secretKeyRef:
                  name: naks-vm-telemetry
                  key: PROXY_URL
            - name: INSTALL_AZURE_MONITOR_AGENT
              valueFrom:
                secretKeyRef:
                  name: naks-vm-telemetry
                  key: INSTALL_AZURE_MONITOR_AGENT
            - name: VERSION
              valueFrom:
                secretKeyRef:
                  name: naks-vm-telemetry
                  key: VERSION
            - name: CONNECTEDMACHINE_AZCLI_VERSION
              valueFrom:
                secretKeyRef:
                  name: naks-vm-telemetry
                  key: CONNECTEDMACHINE_AZCLI_VERSION
          securityContext:
            privileged: true
          command:
            - /bin/bash
            - -c
            - |
              set -e
              WORKDIR=\$(nsenter -t1 -m -u -n -i mktemp -d)
              trap 'nsenter -t1 -m -u -n -i rm -rf "\${WORKDIR}"; echo "Azure Monitor Configuration Failed"' ERR
              nsenter -t1 -m -u -n -i mkdir -p "\${WORKDIR}"/telemetry

              nsenter -t1 -m -u -n -i tee "\${WORKDIR}"/telemetry/telemetry_common.py > /dev/null <<EOF
              #!/usr/bin/python3
              import json
              import logging
              import os
              import socket
              import subprocess
              import sys

              arc_config_file = "\${WORKDIR}/telemetry/arc-connect.json"


              class AgentryResult:
                  CONNECTED = "Connected"
                  CREATING = "Creating"
                  DISCONNECTED = "Disconnected"
                  FAILED = "Failed"
                  SUCCEEDED = "Succeeded"


              class OnboardingMessage:
                  COMPLETED = "Onboarding completed"
                  STILL_CREATING = "Azure still creating"
                  STILL_TRYING = "Service still trying"


              def get_logger(logger_name):
                  logger = logging.getLogger(logger_name)
                  logger.setLevel(logging.DEBUG)
                  handler = logging.StreamHandler(stream=sys.stdout)
                  format = logging.Formatter(fmt="%(name)s - %(levelname)s - %(message)s")
                  handler.setFormatter(format)
                  logger.addHandler(handler)
                  return logger


              def az_cli_cm_ext_install(logger, config):
                  logger.info("Install az CLI connectedmachine extension")
                  proxy_url = config.get("PROXY_URL")
                  if proxy_url is not None:
                      os.environ["HTTP_PROXY"] = proxy_url
                      os.environ["HTTPS_PROXY"] = proxy_url
                  cm_azcli_version = config.get("CONNECTEDMACHINE_AZCLI_VERSION")
                  logger.info("Install az CLI connectedmachine extension: {cm_azcli_version}")
                  ext_cmd = f'/usr/bin/az extension add --name connectedmachine --version "{cm_azcli_version}" --yes'
                  run_cmd(logger, ext_cmd)


              def get_cm_properties(logger, config):
                  hostname = socket.gethostname()
                  resource_group = config.get("RESOURCE_GROUP")

                  logger.info(f"Getting arc enrollment properties for {hostname}...")

                  az_login(logger, config)

                  property_cmd = f'/usr/bin/az connectedmachine show --machine-name "{hostname}" --resource-group "{resource_group}"'

                  try:
                      raw_property = run_cmd(logger, property_cmd)
                      cm_json = json.loads(raw_property.stdout)
                      provisioning_state = cm_json["provisioningState"]
                      status = cm_json["status"]
                  except:
                      logger.warning("Connectedmachine not yet present")
                      provisioning_state = "NOT_PROVISIONED"
                      status = "NOT_CONNECTED"
                  finally:
                      az_logout(logger)

                  logger.info(
                      f'Connected machine "{hostname}" provisioningState is "{provisioning_state}" and status is "{status}"'
                  )

                  return provisioning_state, status


              def get_cm_extension_state(logger, config, extension_name):
                  resource_group = config.get("RESOURCE_GROUP")
                  hostname = socket.gethostname()

                  logger.info(f"Getting {extension_name} state for {hostname}...")

                  az_login(logger, config)

                  state_cmd = f'/usr/bin/az connectedmachine extension show --name "{extension_name}" --machine-name "{hostname}" --resource-group "{resource_group}"'

                  try:
                      raw_state = run_cmd(logger, state_cmd)
                      cme_json = json.loads(raw_state.stdout)
                      provisioning_state = cme_json["provisioningState"]
                  except:
                      logger.warning("Connectedmachine extension not yet present")
                      provisioning_state = "NOT_PROVISIONED"
                  finally:
                      az_logout(logger)

                  logger.info(
                      f'Connected machine "{hostname}" extenstion "{extension_name}" provisioningState is "{provisioning_state}"'
                  )

                  return provisioning_state


              def run_cmd(logger, cmd, check_result=True, echo_output=True):
                  res = subprocess.run(
                      cmd,
                      shell=True,
                      stdout=subprocess.PIPE,
                      stderr=subprocess.PIPE,
                      universal_newlines=True,
                  )

                  if res.stdout:
                      if echo_output:
                          logger.info(f"[OUT] {res.stdout}")

                  if res.stderr:
                      if echo_output:
                          logger.info(f"[ERR] {res.stderr}")

                  if check_result:
                      res.check_returncode()

                  return res  # can parse out res.stdout and res.returncode


              def az_login(logger, config):
                  logger.info("Login to Azure account...")
                  proxy_url = config.get("PROXY_URL")
                  if proxy_url is not None:
                      os.environ["HTTP_PROXY"] = proxy_url
                      os.environ["HTTPS_PROXY"] = proxy_url

                  service_principal_id = config.get("SERVICE_PRINCIPAL_ID")
                  service_principal_secret = config.get("SERVICE_PRINCIPAL_SECRET")
                  tenant_id = config.get("TENANT_ID")
                  subscription_id = config.get("SUBSCRIPTION_ID")
                  cmd = f'/usr/bin/az login --service-principal --username "{service_principal_id}" --password "{service_principal_secret}" --tenant "{tenant_id}"'
                  run_cmd(logger, cmd)
                  logger.info(f"Set Subscription...{subscription_id}")
                  set_sub = f'/usr/bin/az account set --subscription "{subscription_id}"'
                  run_cmd(logger, set_sub)


              def az_logout(logger):
                  logger.info("Logout of Azure account...")
                  run_cmd(logger, "/usr/bin/az logout --verbose", check_result=False)

              EOF

              nsenter -t1 -m -u -n -i tee "\${WORKDIR}"/telemetry/setup_azure_monitor_agent.py > /dev/null <<EOF
              #!/usr/bin/python3
              import json
              import os
              import socket
              import time

              import telemetry_common


              def run_install(logger, ama_config):
                  logger.info("Install Azure Monitor agent...")
                  resource_group = ama_config.get("RESOURCE_GROUP")
                  location = ama_config.get("LOCATION")
                  proxy_url = ama_config.get("PROXY_URL")
                  hostname = socket.gethostname()
                  if proxy_url is not None:
                      os.environ["HTTP_PROXY"] = proxy_url
                      os.environ["HTTPS_PROXY"] = proxy_url
                      settings = (
                          '{"proxy":{"mode":"application","address":"'
                          + proxy_url
                          + '","auth": "false"}}'
                      )
                      cmd = f'/usr/bin/az connectedmachine extension create --no-wait --name "AzureMonitorLinuxAgent" --publisher "Microsoft.Azure.Monitor" --type "AzureMonitorLinuxAgent" --machine-name "{hostname}" --resource-group "{resource_group}" --location "{location}" --verbose --settings \'{settings}\''
                  else:
                      cmd = f'/usr/bin/az connectedmachine extension create --no-wait --name "AzureMonitorLinuxAgent" --publisher "Microsoft.Azure.Monitor" --type "AzureMonitorLinuxAgent" --machine-name "{hostname}" --resource-group "{resource_group}" --location "{location}" --verbose'

                  version = ama_config.get("VERSION")
                  if version is not None:
                      cmd += f' --type-handler-version "{version}"'

                  logger.info("Installing Azure Monitor agent...")
                  telemetry_common.az_login(logger, ama_config)

                  try:
                      telemetry_common.run_cmd(logger, cmd)
                  except:
                      logger.info("Trying to install Azure Monitor agent...")
                  finally:
                      telemetry_common.az_logout(logger)


              def run_uninstall(logger, ama_config):
                  logger.info("Uninstall Azure Monitor agent...")
                  resource_group = ama_config.get("RESOURCE_GROUP")
                  hostname = socket.gethostname()
                  cmd = f'/usr/bin/az connectedmachine extension delete --name "AzureMonitorLinuxAgent" --machine-name "{hostname}" --resource-group "{resource_group}" --yes --verbose'

                  telemetry_common.az_login(logger, ama_config)
                  logger.info("Uninstalling Azure Monitor agent...")

                  try:
                      telemetry_common.run_cmd(logger, cmd)
                  except:
                      print("Trying to uninstall Azure Monitor agent...")
                  finally:
                      telemetry_common.az_logout(logger)


              def ama_installation(logger, ama_config):
                  logger.info("Executing AMA extenstion installation...")
                  telemetry_common.az_cli_cm_ext_install(logger, ama_config)

                  # Get connected machine properties
                  cm_provisioning_state, cm_status = telemetry_common.get_cm_properties(
                    logger, ama_config
                  )

                  if (
                    cm_provisioning_state == telemetry_common.AgentryResult.SUCCEEDED
                    and cm_status == telemetry_common.AgentryResult.CONNECTED
                  ):
                    # Get AzureMonitorLinuxAgent extension status
                    ext_provisioning_state = telemetry_common.get_cm_extension_state(
                      logger, ama_config, "AzureMonitorLinuxAgent"
                    )
  
                    if ext_provisioning_state == telemetry_common.AgentryResult.SUCCEEDED:
                      logger.info(telemetry_common.OnboardingMessage.COMPLETED)
                      return True
                    elif ext_provisioning_state == telemetry_common.AgentryResult.FAILED:
                      run_uninstall(logger, ama_config)
                      logger.warning(telemetry_common.OnboardingMessage.STILL_TRYING)
                      return False
                    elif ext_provisioning_state == telemetry_common.AgentryResult.CREATING:
                      logger.warning(telemetry_common.OnboardingMessage.STILL_CREATING)
                      return False
                    else:
                      run_install(logger, ama_config)
                      logger.warning(telemetry_common.OnboardingMessage.STILL_TRYING)
                      return False
                  else:
                    logger.error("Server not arc enrolled, enroll the server and retry")
                    return False


              def main():
                  timeout = 60  # TODO: increase when executed via systemd unit
                  start_time = time.time()
                  end_time = start_time + timeout

                  config_file = telemetry_common.arc_config_file

                  logger = telemetry_common.get_logger(__name__)

                  logger.info("Running setup_azure_monitor_agent.py...")

                  if config_file is None:
                      raise Exception("config file is expected")

                  ama_config = {}

                  with open(config_file, "r") as file:
                      ama_config = json.load(file)

                  ama_installed = False

                  while time.time() < end_time:
                      logger.info("Installing AMA extension...")
                      try:
                          ama_installed = ama_installation(logger, ama_config)
                      except Exception as e:
                          logger.error(f"Could not install AMA extension: {e}")
                      if ama_installed:
                          break
                      logger.info("Sleeping 30s...")  # retry for Azure info
                      time.sleep(30)


              if __name__ == "__main__":
                  main()

              EOF


              nsenter -t1 -m -u -n -i tee "\${WORKDIR}"/arc-connect.sh > /dev/null <<EOF
              #!/bin/bash
              set -e

              echo "{\"VERSION\": \"\${VERSION}\", \"SUBSCRIPTION_ID\": \"\${SUBSCRIPTION_ID}\", \"SERVICE_PRINCIPAL_ID\": \"\${SERVICE_PRINCIPAL_ID}\", \"SERVICE_PRINCIPAL_SECRET\": \"\${SERVICE_PRINCIPAL_SECRET}\", \"RESOURCE_GROUP\": \"\${RESOURCE_GROUP}\", \"TENANT_ID\": \"\${TENANT_ID}\", \"LOCATION\": \"\${LOCATION}\", \"PROXY_URL\": \"\${PROXY_URL}\", \"CONNECTEDMACHINE_AZCLI_VERSION\": \"\${CONNECTEDMACHINE_AZCLI_VERSION}\"}" > "\${WORKDIR}"/telemetry/arc-connect.json

              if [ "\${INSTALL_AZURE_MONITOR_AGENT}" = "true" ]; then
                echo "Installing Azure Monitor agent..."
                /usr/bin/python3 "\${WORKDIR}"/telemetry/setup_azure_monitor_agent.py > "\${WORKDIR}"/setup_azure_monitor_agent.out
                cat "\${WORKDIR}"/setup_azure_monitor_agent.out
                if grep "Could not install AMA extension" "\${WORKDIR}"/setup_azure_monitor_agent.out > /dev/null; then
                  exit 1
                fi
              fi
              EOF

              nsenter -t1 -m -u -n -i sh "\${WORKDIR}"/arc-connect.sh
              nsenter -t1 -m -u -n -i rm -rf "\${WORKDIR}"
              echo "Server monitoring configured successfully"
              tail -f /dev/null
          livenessProbe:
            initialDelaySeconds: 600
            periodSeconds: 60
            timeoutSeconds: 30
            exec:
              command:
                - /bin/bash
                - -c
                - |
                  set -e
                  WORKDIR=\$(nsenter -t1 -m -u -n -i mktemp -d)
                  trap 'nsenter -t1 -m -u -n -i rm -rf "\${WORKDIR}"' ERR EXIT
                  nsenter -t1 -m -u -n -i tee "\${WORKDIR}"/liveness.sh > /dev/null <<EOF
                  #!/bin/bash
                  set -e

                  # Check AMA processes
                  ps -ef | grep "\\\s/opt/microsoft/azuremonitoragent/bin/agentlauncher\\\s"
                  ps -ef | grep "\\\s/opt/microsoft/azuremonitoragent/bin/mdsd\\\s"
                  ps -ef | grep "\\\s/opt/microsoft/azuremonitoragent/bin/amacoreagent\\\s"

                  # Check Arc server agent is Connected
                  AGENTSTATUS="\\\$(azcmagent show -j)"
                  if [[ \\\$(echo "\\\${AGENTSTATUS}" | jq -r .status) != "Connected" ]]; then
                    echo "azcmagent is not connected"
                    echo "\\\${AGENTSTATUS}"
                    exit 1
                  fi

                  # Verify dependent services are running
                  while IFS= read -r status; do
                    if [[ "\\\${status}" != "active" ]]; then
                      echo "one or more azcmagent services not active"
                      echo "\\\${AGENTSTATUS}"
                      exit 1
                    fi
                  done < <(jq -r '.services[] | (.status)' <<<\\\${AGENTSTATUS})

                  # Run connectivity tests
                  RESULT="\\\$(azcmagent check -j)"
                  while IFS= read -r reachable; do
                    if [[ ! \\\${reachable} ]]; then
                      echo "one or more connectivity tests failed"
                      echo "\\\${RESULT}"
                      exit 1
                    fi
                  done < <(jq -r '.[] | (.reachable)' <<<\\\${RESULT})

                  EOF

                  nsenter -t1 -m -u -n -i sh "\${WORKDIR}"/liveness.sh
                  nsenter -t1 -m -u -n -i rm -rf "\${WORKDIR}"
                  echo "Liveness check succeeded"

      tolerations:
        - operator: "Exists"
          effect: "NoSchedule"

EOF
}

SUBSCRIPTION_ID="${SUBSCRIPTION_ID:?SUBSCRIPTION_ID must be set}"
SERVICE_PRINCIPAL_ID="${SERVICE_PRINCIPAL_ID:?SERVICE_PRINCIPAL_ID must be set}"
SERVICE_PRINCIPAL_SECRET="${SERVICE_PRINCIPAL_SECRET:?SERVICE_PRINCIPAL_SECRET must be set}"
RESOURCE_GROUP="${RESOURCE_GROUP:?RESOURCE_GROUP must be set}"
TENANT_ID="${TENANT_ID:?TENANT_ID must be set}"
LOCATION="${LOCATION:?LOCATION must be set}"
PROXY_URL="${PROXY_URL:?PROXY_URL must be set}"
INSTALL_AZURE_MONITOR_AGENT="${INSTALL_AZURE_MONITOR_AGENT:?INSTALL_AZURE_MONITOR_AGENT must be true/false}"
NAMESPACE="${NAMESPACE:?NAMESPACE must be set}"
AZURE_MONITOR_AGENT_VERSION="${AZURE_MONITOR_AGENT_VERSION:-"1.24.2"}"
CONNECTEDMACHINE_AZCLI_VERSION="${CONNECTEDMACHINE_AZCLI_VERSION:-"0.6.0"}"

create_secret
create_daemonset

المتطلبات الأساسية-الجهاز الظاهري

  • وصول مسؤول نظام المجموعة إلى مجموعة Nexus Kubernetes.

  • لاستخدام خوادم Azure Arc الممكنة، سجل موفري موارد Azure التاليين في اشتراكك:

    • Microsoft.HybridCompute
    • Microsoft.GuestConfiguration
    • Microsoft.HybridConnectivity

سجل موفري الموارد هؤلاء، إذا لم يتم ذلك مسبقا:

az account set --subscription "{the Subscription Name}"
az provider register --namespace 'Microsoft.HybridCompute'
az provider register --namespace 'Microsoft.GuestConfiguration'
az provider register --namespace 'Microsoft.HybridConnectivity'
  • تعيين كيان خدمة Azure للأدوار المضمنة التالية في Azure، حسب الحاجة. تعيين كيان الخدمة إلى مجموعة موارد Azure التي تحتوي على الأجهزة المراد توصيلها:
الدور مطلوب ل
azure الاتصال ed Machine Resource مسؤول istrator أو Contributor الاتصال خادم الجهاز الظاهري لنظام مجموعة Nexus Kubernetes الممكن بواسطة Arc في مجموعة الموارد وتثبيت عامل مراقبة Azure (AMA)
مراقبة المساهم أو المساهم إنشاء قاعدة تجميع البيانات (DCR) في مجموعة الموارد وإقران الخوادم الممكنة بواسطة Arc بها
المستخدم الوصول مسؤول istrator، والمساهم أو المساهم في نهج الموارد مطلوب إذا كنت تريد استخدام تعيين (تعيينات) نهج Azure للتأكد من أن DCR مقترن بالأجهزة التي تدعم Arc
مساهم ملحق Kubernetes مطلوب لنشر ملحق K8s ل Container Insights

إعداد بيئة

نسخ البرامج النصية المضمنة وتشغيلها. يمكنك تشغيلها من Azure Cloud Shell، في مدخل Microsoft Azure. أو يمكنك تشغيلها من موجه أوامر Linux حيث يتم تثبيت أداة سطر الأوامر Kubernetes (kubectl) وAzure CLI.

قبل تشغيل البرامج النصية المضمنة، حدد متغيرات البيئة التالية:

متغير بيئة ‏‏الوصف
SUBSCRIPTION_ID معرف اشتراك Azure الذي يحتوي على مجموعة الموارد
RESOURCE_GROUP اسم مجموعة الموارد حيث يتم إنشاء خادم Arc الممكن والموارد المقترنة
الموقع منطقة Azure حيث يتم إنشاء الخوادم الممكنة بواسطة Arc والموارد المرتبطة بها
SERVICE_PRINCIPAL_ID معرف التطبيق الخاص بكيان خدمة Azure مع تعيين (تعيينات) دور مناسب
SERVICE_PRINCIPAL_SECRET كلمة مرور المصادقة لمدير خدمة Azure
TENANT_ID معرف دليل المستأجر حيث يوجد كيان الخدمة
PROXY_URL عنوان URL للوكيل لاستخدامه للاتصال بخدمات Azure
مساحه الاسم مساحة الاسم حيث يتم إنشاء بيانات Kubernetes الاصطناعية

للراحة، يمكنك تعديل ملف القالب، arc-connect.env، لتعيين قيم متغير البيئة.

# Apply the modified values to the environment
 ./arc-connect.env

إضافة قاعدة تجميع بيانات (DCR)

إقران الخوادم الممكنة بواسطة Arc مع DCR لتمكين جمع بيانات السجل في مساحة عمل Log Analytics. يمكنك إنشاء DCR عبر مدخل Azure أو CLI. تتوفر هنا معلومات حول إنشاء DCR لجمع البيانات من الأجهزة الظاهرية.

يقوم البرنامج النصي المضمن dcr.sh بإنشاء DCR، في مجموعة الموارد المحددة، التي ستقوم بتكوين مجموعة السجل.

  1. تأكد من إعداد البيئة المناسبة والمتطلبات الأساسية للدور لمدير الخدمة. يتم إنشاء DCR في مجموعة الموارد المحددة.

  2. إنشاء أو تحديد مساحة عمل Log Analytics لاستيعاب بيانات السجل وفقا ل DCR. تعيين متغير بيئة، LAW_RESOURCE_ID إلى معرف المورد الخاص به. استرداد معرف المورد لاسم مساحة عمل Log Analytics معروف:

export LAW_RESOURCE_ID=$(az monitor log-analytics workspace show -g "${RESOURCE_GROUP}" -n <law name> --query id -o tsv)
  1. تشغيل البرنامج النصي dcr.sh. يقوم بإنشاء DCR في مجموعة الموارد المحددة بالاسم ${RESOURCE_GROUP}-syslog-dcr
./dcr.sh

عرض/إدارة DCR من مدخل Microsoft Azure أو CLI. بشكل افتراضي، يتم تعيين مستوى سجل Linux Syslog إلى "INFO". يمكنك تغيير مستوى السجل حسب الحاجة.

إشعار

يدويا، أو عبر نهج، قم بإقران الخوادم التي تم إنشاؤها قبل إنشاء DCR. راجع مهمة المعالجة.

إقران موارد الخادم الممكنة بواسطة Arc ب DCR

إقران موارد الخادم الممكنة بواسطة Arc ب DCR الذي تم إنشاؤه للسجلات للتدفق إلى مساحة عمل Log Analytics. هناك خيارات لربط الخوادم ب DCRs.

استخدام مدخل Microsoft Azure أو CLI لربط الخوادم المحددة الممكنة بواسطة Arc ب DCR

في مدخل Microsoft Azure، أضف مورد خادم ممكن بواسطة Arc إلى DCR باستخدام قسم الموارد الخاص به.

استخدم هذا الارتباط للحصول على معلومات حول إقران الموارد عبر Azure CLI.

استخدام نهج Azure لإدارة اقترانات DCR

تعيين نهج لمجموعة الموارد لفرض الاقتران. هناك تعريف نهج مضمن، لربط أجهزة Linux Arc ب DCR. تعيين النهج إلى مجموعة الموارد باستخدام DCR كمعلمة. يضمن اقتران جميع الخوادم الممكنة بواسطة Arc، ضمن مجموعة الموارد، بنفس DCR.

في مدخل Microsoft Azure، حدد Assign الزر من صفحة تعريف النهج.

للراحة، يقوم البرنامج النصي المقدم assign.sh بتعيين النهج المضمن إلى مجموعة الموارد المحددة وDCR التي تم إنشاؤها dcr.sh باستخدام البرنامج النصي.

  1. تأكد من إعداد البيئة المناسبة والمتطلبات الأساسية للدور لكيان الخدمة للقيام بتعيينات النهج والدور.
  2. إنشاء DCR، في مجموعة الموارد، باستخدام dcr.sh البرنامج النصي كما هو موضح في قسم إضافة قاعدة تجميع البيانات.
  3. assign.sh تشغيل البرنامج النصي. يقوم بإنشاء تعيين النهج وتعيينات الأدوار الضرورية.
./assign.sh

تثبيت عامل مراقبة Azure

استخدم المضمن install.sh الذي ينشئ Kubernetes daemonSet على مجموعة Nexus Kubernetes. يقوم بنشر جراب لكل عقدة نظام مجموعة وتثبيت عامل مراقبة Azure (AMA). daemonSet يتضمن أيضا فحصا للحيوية يراقب اتصال الخادم وعمليات AMA.

إشعار

لتثبيت Azure Monitoring Agent، يجب أولا توصيل Arc بالأجهزة الظاهرية لنظام مجموعة Nexus Kubernetes. يتم أتمتة هذه العملية إذا كنت تستخدم أحدث حزمة إصدار. ومع ذلك، إذا كانت حزمة الإصدار التي تستخدمها لا تدعم تسجيل نظام المجموعة VM Arc بشكل افتراضي، فستحتاج إلى ترقية مجموعتك إلى أحدث حزمة إصدار. لمزيد من المعلومات حول حزمة الإصدار، يرجى الرجوع إلى الإصدارات المدعومة من مجموعة Nexus Kubernetes

  1. تعيين البيئة كما هو محدد في إعداد البيئة. تعيين السياق الحالي kubeconfig للأجهزة الظاهرية لمجموعة Nexus Kubernetes.
  2. السماح بالوصول Kubectl إلى مجموعة Nexus Kubernetes.

    إشعار

    عند إنشاء مجموعة Nexus Kubernetes، تقوم Nexus تلقائيا بإنشاء مجموعة موارد مدارة مخصصة لتخزين موارد نظام المجموعة، داخل هذه المجموعة، يتم إنشاء مورد نظام المجموعة المتصل ب Arc.

    للوصول إلى نظام المجموعة الخاص بك، تحتاج إلى إعداد اتصال kubeconfigنظام المجموعة . بعد تسجيل الدخول إلى Azure CLI باستخدام كيان Microsoft Entra ذي الصلة، يمكنك الحصول على kubeconfig ما يلزم للاتصال بالمجموعة من أي مكان، حتى خارج جدار الحماية الذي يحيط به.
    1. تعيين CLUSTER_NAMEالمتغيرات RESOURCE_GROUP و SUBSCRIPTION_ID .

      CLUSTER_NAME="myNexusK8sCluster"
      RESOURCE_GROUP="myResourceGroup"
      SUBSCRIPTION_ID=<set the correct subscription_id>
      
    2. الاستعلام عن مجموعة الموارد المدارة مع az وتخزينها في MANAGED_RESOURCE_GROUP

       az account set -s $SUBSCRIPTION_ID
       MANAGED_RESOURCE_GROUP=$(az networkcloud kubernetescluster show -n $CLUSTER_NAME -g $RESOURCE_GROUP --output tsv --query managedResourceGroupConfiguration.name)
      
    3. يبدأ الأمر التالي وكيل connectedk8s الذي يسمح لك بالاتصال بخادم Kubernetes API لمجموعة Nexus Kubernetes المحددة.

      az connectedk8s proxy -n $CLUSTER_NAME  -g $MANAGED_RESOURCE_GROUP &
      
    4. استخدم kubectl لإرسال الطلبات إلى نظام المجموعة:

      kubectl get pods -A
      

      يجب أن تشاهد الآن استجابة من المجموعة التي تحتوي على قائمة بجميع العقد.

    إشعار

    إذا رأيت رسالة الخطأ "فشل نشر الرمز المميز للوصول إلى وكيل العميلFailed للاتصال ب MSI"، فقد تحتاج إلى إجراء az login لإعادة المصادقة باستخدام Azure.

  3. install.sh قم بتشغيل البرنامج النصي من موجه الأوامر مع وصول kubectl إلى مجموعة Nexus Kubernetes.

ينشر daemonSet البرنامج النصي إلى نظام المجموعة. راقب التقدم كما يلي:

# Run the install script and observe results
./install.sh
kubectl get pod --selector='name=naks-vm-telemetry'
kubectl logs <podname>

عند الانتهاء، يسجل النظام الرسالة "تم تكوين مراقبة الخادم بنجاح".

إشعار

إقران هذه الخوادم المتصلة ب DCR. بعد تكوين نهج، قد يكون هناك بعض التأخير لمراقبة السجلات في مساحة عمل Azure Log Analytics

مراقبة مجموعة Nexus Kubernetes - طبقة K8s

المتطلبات الأساسية - Kubernetes

هناك متطلبات أساسية معينة يجب أن يضمنها المشغل لتكوين أدوات المراقبة على مجموعات Nexus Kubernetes.

تخزن Container Insights بياناتها في مساحة عمل Log Analytics. تتدفق بيانات السجل إلى مساحة العمل التي قمت بتوفير معرف المورد الخاص بها أثناء البرامج النصية الأولية المغطاة في قسم "Add a data collection rule (DCR)". وإلا، يتم تحويل البيانات إلى مساحة عمل افتراضية في مجموعة الموارد المقترنة باشتراكك (استنادا إلى موقع Azure).

قد يبدو مثال شرق الولايات المتحدة كما يلي:

  • اسم مساحة عمل Log Analytics: DefaultWorkspace-GUID-EUS<>
  • اسم مجموعة الموارد: DefaultResourceGroup-EUS

قم بتشغيل الأمر التالي للحصول على معرف مورد مساحة عمل Log Analytics موجود مسبقا:

az login

az account set --subscription "<Subscription Name or ID the Log Analytics workspace is in>"

az monitor log-analytics workspace show --workspace-name "<Log Analytics workspace Name>" \
  --resource-group "<Log Analytics workspace Resource Group>" \
  -o tsv --query id

لنشر Container Insights وعرض البيانات في مساحة عمل Log Analytics القابلة للتطبيق يتطلب تعيينات أدوار معينة في حسابك. على سبيل المثال، تعيين دور "المساهم". راجع إرشادات تعيين الأدوار المطلوبة:

  • دور مساهم Log Analytics: الأذونات الضرورية لتمكين مراقبة الحاوية على مجموعة CNF (المقدمة).
  • دور قارئ Log Analytics: يتلقى غير الأعضاء في دور مساهم Log Analytics أذونات لعرض البيانات في مساحة عمل Log Analytics بمجرد تمكين مراقبة الحاوية.

تثبيت ملحق نظام المجموعة

تسجيل الدخول إلى Azure Cloud Shell للوصول إلى نظام المجموعة:

az login

az account set --subscription "<Subscription Name or ID the Provisioned Cluster is in>"

الآن، انشر ملحق Container Insights على مجموعة Nexus Kubernetes المتوفرة باستخدام أي من الأمرين التاليين:

مع مساحة عمل تحليلات السجل المنشأة مسبقا من قبل العميل

az k8s-extension create --name azuremonitor-containers \
  --cluster-name "<Nexus Kubernetes cluster Name>" \
  --resource-group "<Nexus Kubernetes cluster Resource Group>" \
  --cluster-type connectedClusters \
  --extension-type Microsoft.AzureMonitor.Containers \
  --release-train preview \
  --configuration-settings logAnalyticsWorkspaceResourceID="<Log Analytics workspace Resource ID>" \
  amalogsagent.useAADAuth=true

استخدام مساحة عمل Log analytics الافتراضية

az k8s-extension create --name azuremonitor-containers \
  --cluster-name "<Nexus Kubernetes cluster Name>" \
  --resource-group "<Nexus Kubernetes cluster Resource Group>" \
  --cluster-type connectedClusters \
  --extension-type Microsoft.AzureMonitor.Containers \
  --release-train preview \
  --configuration-settings amalogsagent.useAADAuth=true

التحقق من صحة ملحق نظام المجموعة

التحقق من صحة النشر الناجح لتمكين عوامل المراقبة على مجموعات Nexus Kubernetes باستخدام الأمر التالي:

az k8s-extension show --name azuremonitor-containers \
  --cluster-name "<Nexus Kubernetes cluster Name>" \
  --resource-group "<Nexus Kubernetes cluster Resource Group>" \
  --cluster-type connectedClusters

ابحث عن حالة توفير "Succeeded" للملحق. قد يكون الأمر "k8s-extension create" قد أرجع الحالة أيضا.

تخصيص مجموعة السجلات والمقاييس

توفر Container Insights وظائف المستخدمين النهائيين لضبط مجموعة السجلات والمقاييس من مجموعات Nexus Kubernetes --تكوين جمع بيانات عامل نتائج تحليلات الحاوية.

موارد إضافية

  • راجع وثائق المصنفات ثم يمكنك استخدام نماذج بيانات تتبع الاستخدام لعامل التشغيل Nexus مصنفات Operator Nexus.
  • راجع تنبيهات Azure Monitor، وكيفية إنشاء قواعد تنبيه Azure Monitor، واستخدام نموذج قوالب تنبيه Operator Nexus.