Dela via


Övervaka Nexus Kubernetes-kluster

Varje Nexus Kubernetes-kluster består av flera lager:

  • Virtuella datorer (VM)
  • Kubernetes-lager
  • Programpoddar

Skärmbild av Nexus Kubernetes-exempelklustret.

Bild: Exempel på Nexus Kubernetes-kluster

På en instans levereras Nexus Kubernetes-kluster med en valfri Container Insights-observerbarhetslösning . Container Insights samlar in loggar och mått från Nexus Kubernetes-kluster och arbetsbelastningar. Det är helt och hållet din bedömning om du vill aktivera den här verktygsstacken eller distribuera din egen telemetristack.

Nexus Kubernetes-klustret med Azure-övervakningsverktyget ser ut så här:

Skärmbild av Nexus Kubernetes-kluster med övervakningsverktyg.

Bild: Nexus Kubernetes-kluster med övervakningsverktyg

Tilläggsregistrering med CLI med hanterad identitetsautentisering

Dokumentation för att börja med Azure CLI, hur du installerar det i flera operativsystem och hur du installerar CLI-tillägg.

Installera den senaste versionen av de nödvändiga CLI-tilläggen.

Övervaka Nexus Kubernetes-kluster – VM-lager

Den här guiden innehåller steg och verktygsskript för att Ansluta Nexus Kubernetes-klustrets virtuella datorer till Azure och aktivera övervakningsagenter för insamling av systemloggar från dessa virtuella datorer med Hjälp av Azure Monitoring Agent. Anvisningarna innehåller ytterligare information om hur du konfigurerar insamling av loggdata till en Log Analytics-arbetsyta.

Följande resurser ger dig support:

  • arc-connect.env: Använd den här mallfilen för att skapa miljövariabler som krävs av inkluderade skript

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: Använd det här skriptet för att skapa en datainsamlingsregel (DCR) för att konfigurera syslog-samling

#!/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: Använd skriptet för att skapa en princip för att associera DCR med alla Arc-aktiverade servrar i en resursgrupp

#!/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: Installera Azure Monitoring Agent på varje virtuell dator för att samla in övervakningsdata från virtuella Azure-datorer.
#!/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

Förutsättningar–virtuell dator

  • Klusteradministratörsåtkomst till Nexus Kubernetes-klustret.

  • Om du vill använda Azure Arc-aktiverade servrar registrerar du följande Azure-resursprovidrar i din prenumeration:

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

Registrera dessa resursprovidrar om de inte har gjorts tidigare:

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'
  • Tilldela ett Azure-tjänsthuvudnamn till följande inbyggda Azure-roller efter behov. Tilldela tjänstens huvudnamn till den Azure-resursgrupp som har datorerna som ska anslutas:
Roll Behövs för att
Resursadministratör eller deltagare för Azure Connected Machine Ansluta Arc-aktiverad Vm-server för Nexus Kubernetes-kluster i resursgruppen och installera Azure Monitoring Agent (AMA)
Övervaka deltagare eller deltagare Skapa en datainsamlingsregel (DCR) i resursgruppen och associera Arc-aktiverade servrar till den
Administratör för användaråtkomst och resursprincipdeltagare eller deltagare Krävs om du vill använda Azure-principtilldelningar för att säkerställa att en DCR är associerad med Arc-aktiverade datorer
Kubernetes-tilläggsdeltagare Behövs för att distribuera K8s-tillägget för Container Insights

Miljöinställningar

Kopiera och kör de medföljande skripten. Du kan köra dem från ett Azure Cloud Shell i Azure-portalen. Du kan också köra dem från en Linux-kommandotolk där Kubernetes-kommandoradsverktyget (kubectl) och Azure CLI är installerade.

Innan du kör de inkluderade skripten definierar du följande miljövariabler:

Miljövariabel beskrivning
SUBSCRIPTION_ID ID för Azure-prenumerationen som innehåller resursgruppen
RESOURCE_GROUP Resursgruppens namn där Arc-aktiverad server och associerade resurser skapas
PLATS Den Azure-region där Arc-aktiverade servrar och associerade resurser skapas
SERVICE_PRINCIPAL_ID AppId för Azure-tjänstens huvudnamn med lämpliga rolltilldelningar
SERVICE_PRINCIPAL_SECRET Autentiseringslösenordet för Azure-tjänstens huvudnamn
TENANT_ID ID för klientkatalogen där tjänstens huvudnamn finns
PROXY_URL Proxy-URL:en som ska användas för att ansluta till Azure-tjänster
NAMNOMRÅDE Namnområdet där Kubernetes-artefakterna skapas

För enkelhetens skull kan du ändra mallfilen, arc-connect.env, för att ange miljövariabelvärdena.

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

Lägga till en datainsamlingsregel (DCR)

Associera Arc-aktiverade servrar med en DCR för att aktivera insamling av loggdata till en Log Analytics-arbetsyta. Du kan skapa DCR via Azure-portalen eller CLI. Information om hur du skapar en DCR för att samla in data från de virtuella datorerna finns här.

Det inkluderade dcr.sh skriptet skapar en DCR i den angivna resursgruppen som konfigurerar loggsamlingen.

  1. Se till att miljökonfigurationen och rollkraven är uppfyllda för tjänstens huvudnamn. DCR skapas i den angivna resursgruppen.

  2. Skapa eller identifiera en Log Analytics-arbetsyta för loggdatainmatning enligt DCR. Ange en miljövariabel LAW_RESOURCE_ID till dess resurs-ID. Hämta resurs-ID:t för ett känt Log Analytics-arbetsytenamn:

export LAW_RESOURCE_ID=$(az monitor log-analytics workspace show -g "${RESOURCE_GROUP}" -n <law name> --query id -o tsv)
  1. Kör skriptet dcr.sh. Den skapar en DCR i den angivna resursgruppen med namnet ${RESOURCE_GROUP}-syslog-dcr
./dcr.sh

Visa/hantera domänkontrollanten från Azure-portalen eller CLI. Som standard är Linux Syslog-loggnivån inställd på "INFO". Du kan ändra loggnivån efter behov.

Kommentar

Manuellt, eller via en princip, associerar servrar som skapats innan DCR skapas. Se reparationsuppgift.

Associera Arc-aktiverade serverresurser med DCR

Associera Arc-aktiverade serverresurser till den skapade domänkontrollanten för loggar som ska flöda till Log Analytics-arbetsytan. Det finns alternativ för att associera servrar med domänkontrollanter.

Använda Azure-portalen eller CLI för att associera valda Arc-aktiverade servrar med DCR

I Azure-portalen lägger du till Arc-aktiverad serverresurs i DCR med hjälp av avsnittet Resurser.

Använd den här länken om du vill ha information om hur du associerar resurserna via Azure CLI.

Använda Azure-princip för att hantera DCR-associationer

Tilldela en princip till resursgruppen för att framtvinga associationen. Det finns en inbyggd principdefinition för att associera Linux Arc Machines med en DCR. Tilldela principen till resursgruppen med DCR som parameter. Det säkerställer association av alla Arc-aktiverade servrar i resursgruppen med samma DCR.

I Azure-portalen väljer du Assign knappen på principdefinitionssidan.

För enkelhetens skull tilldelar det angivna assign.sh skriptet den inbyggda principen till den angivna resursgruppen och DCR som skapats med skriptet dcr.sh .

  1. Se till att miljökonfigurationen och rollkraven är uppfyllda för att tjänstens huvudnamn ska kunna utföra princip- och rolltilldelningar.
  2. Skapa DCR i resursgruppen med hjälp av dcr.sh skriptet enligt beskrivningen i avsnittet Lägga till en datainsamlingsregel .
  3. Kör skriptet assign.sh. Den skapar principtilldelningen och nödvändiga rolltilldelningar.
./assign.sh

Installera Azure Monitoring Agent

Använd den inkluderade install.sh som skapar en Kubernetes-daemonSet på Nexus Kubernetes-klustret. Den distribuerar en podd till varje klusternod och installerar Azure Monitoring Agent (AMA). Innehåller daemonSet även en liveness-avsökning som övervakar serveranslutningen och AMA-processerna.

Kommentar

Om du vill installera Azure Monitoring Agent måste du först ansluta de virtuella datorerna i Nexus Kubernetes-klustret. Den här processen automatiseras om du använder det senaste versionspaketet. Men om versionspaketet som du använder inte stöder kluster-VM Arc-registrering som standard måste du uppgradera klustret till det senaste versionspaketet. Mer information om versionspaketet finns i Nexus Kubernetes-kluster som stöds

  1. Ange miljön enligt beskrivningen i Miljökonfiguration. Ange den aktuella kubeconfig kontexten för virtuella Nexus Kubernetes-klusterdatorer.
  2. Tillåt Kubectl åtkomst till Nexus Kubernetes-klustret.

    Kommentar

    När du skapar ett Nexus Kubernetes-kluster skapar Nexus automatiskt en hanterad resursgrupp som är dedikerad till att lagra klusterresurserna. Inom den här gruppen upprättas den Arc-anslutna klusterresursen.

    För att få åtkomst till klustret måste du konfigurera klustret att ansluta kubeconfig. När du har loggat in på Azure CLI med relevant Microsoft Entra-entitet kan du få de kubeconfig nödvändiga för att kommunicera med klustret var som helst, även utanför brandväggen som omger det.
    1. Ange CLUSTER_NAMEoch RESOURCE_GROUP SUBSCRIPTION_ID variabler.

      CLUSTER_NAME="myNexusK8sCluster"
      RESOURCE_GROUP="myResourceGroup"
      SUBSCRIPTION_ID=<set the correct subscription_id>
      
    2. Fråga hanterad resursgrupp med az och lagra i 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. Följande kommando startar en connectedk8s-proxy som gör att du kan ansluta till Kubernetes API-servern för det angivna Nexus Kubernetes-klustret.

      az connectedk8s proxy -n $CLUSTER_NAME  -g $MANAGED_RESOURCE_GROUP &
      
    4. Använd kubectl för att skicka begäranden till klustret:

      kubectl get pods -A
      

      Nu bör du se ett svar från klustret som innehåller listan över alla noder.

    Kommentar

    Om du ser felmeddelandet "Det gick inte att publicera åtkomsttoken till klientproxyFailed för att ansluta till MSI" kan du behöva utföra en az login för att autentisera igen med Azure.

  3. Kör skriptet install.sh från kommandotolken med kubectl-åtkomst till Nexus Kubernetes-klustret.

Skriptet distribuerar daemonSet till klustret. Övervaka förloppet enligt följande:

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

När det är klart loggar systemet meddelandet "Serverövervakning har konfigurerats".

Kommentar

Associera dessa anslutna servrar med DCR. När du har konfigurerat en princip kan det uppstå en viss fördröjning för att observera loggarna på Azure Log Analytics-arbetsytan

Övervaka Nexus Kubernetes-kluster – K8s-lager

Krav –Kubernetes

Det finns vissa krav som operatorn bör se till att konfigurera övervakningsverktygen på Nexus Kubernetes-kluster.

Container Insights lagrar sina data på en Log Analytics-arbetsyta. Logga dataflöden till arbetsytan vars resurs-ID du angav under de första skripten som beskrivs i avsnittet "Lägg till en datainsamlingsregel (DCR)." Annars trattar data till en standardarbetsyta i resursgruppen som är associerad med din prenumeration (baserat på Azure-plats).

Ett exempel för USA, östra kan se ut så här:

  • Log Analytics-arbetsytans namn: DefaultWorkspace-GUID-EUS<>
  • Namn på resursgrupp: DefaultResourceGroup-EUS

Kör följande kommando för att hämta ett befintligt Resurs-ID för Log Analytics-arbetsytan:

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

För att distribuera Container Insights och visa data på den tillämpliga Log Analytics-arbetsytan krävs vissa rolltilldelningar i ditt konto. Till exempel rolltilldelningen Deltagare. Se anvisningarna för att tilldela nödvändiga roller:

  • Log Analytics-deltagarroll : nödvändiga behörigheter för att aktivera containerövervakning i ett CNF-kluster (etablerat).
  • Log Analytics-läsarroll : Icke-medlemmar i Rollen Log Analytics-deltagare får behörighet att visa data på Log Analytics-arbetsytan när du aktiverar containerövervakning.

Installera klustertillägget

Logga in på Azure Cloud Shell för att få åtkomst till klustret:

az login

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

Distribuera nu Container Insights-tillägget i ett etablerat Nexus Kubernetes-kluster med något av följande två kommandon:

Med kundens i förväg skapade Log Analytics-arbetsyta

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

Använd standardarbetsytan för 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

Validera klustertillägg

Verifiera den lyckade distributionen av övervakningsagenternas aktivering på Nexus Kubernetes-kluster med hjälp av följande kommando:

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

Leta efter etableringstillståndet "Lyckades" för tillägget. Kommandot "k8s-extension create" kan också ha returnerat statusen.

Anpassa logg- och måttsamling

Container Insights tillhandahåller slutanvändarfunktioner för att finjustera insamlingen av loggar och mått från Nexus Kubernetes-kluster – Konfigurera containerinsiktsagentens datainsamling.

Extra resurser