Memantau kluster Nexus Kubernetes

Setiap kluster Nexus Kubernetes terdiri dari beberapa lapisan:

  • Komputer Virtual (VM)
  • Lapisan Kubernetes
  • Pod aplikasi

Screenshot of Sample Nexus Kubernetes cluster.

Gambar: Contoh kluster Nexus Kubernetes

Pada instans, kluster Nexus Kubernetes dikirimkan dengan solusi observabilitas Container Insights opsional. Container Insights mengambil log dan metrik dari kluster dan beban kerja Nexus Kubernetes. Ini hanya kebijaksanaan Anda apakah akan mengaktifkan alat ini atau menyebarkan tumpukan telemetri Anda sendiri.

Kluster Nexus Kubernetes dengan alat pemantauan Azure terlihat seperti:

Screenshot of Nexus Kubernetes cluster with Monitoring Tools.

Gambar: Kluster Nexus Kubernetes dengan Alat Pemantauan

Onboarding ekstensi dengan CLI menggunakan autentikasi identitas terkelola

Dokumentasi untuk dimulai dengan Azure CLI, cara menginstalnya di beberapa sistem operasi, dan cara menginstal ekstensi CLI.

Instal versi terbaru ekstensi CLI yang diperlukan.

Memantau kluster Nexus Kubernetes – Lapisan VM

Panduan cara ini menyediakan langkah-langkah dan skrip utilitas ke Arc menghubungkan Kluster Nexus Kubernetes Virtual Machines ke Azure dan memungkinkan agen pemantauan untuk pengumpulan log Sistem dari VM ini menggunakan Azure Monitoring Agent. Instruksi selanjutnya menangkap detail tentang cara menyiapkan pengumpulan data log ke ruang kerja Analitik Log.

Sumber daya berikut memberi Anda dukungan:

  • arc-connect.env: gunakan file templat ini untuk membuat variabel lingkungan yang diperlukan oleh skrip yang disertakan

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: gunakan skrip ini untuk membuat Aturan Pengumpulan Data (DCR) untuk mengonfigurasi pengumpulan 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: gunakan skrip untuk membuat kebijakan untuk mengaitkan DCR dengan semua server berkemampuan Arc dalam grup sumber daya

#!/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: Instal Azure Monitoring Agent pada setiap VM untuk mengumpulkan data pemantauan dari Azure Virtual Machines.
#!/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

Prasyarat-VM

  • Akses administrator kluster ke kluster Nexus Kubernetes.

  • Untuk menggunakan server dengan dukungan Azure Arc, daftarkan penyedia sumber daya Azure berikut ini di langganan Anda:

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

Daftarkan penyedia sumber daya ini, jika tidak dilakukan sebelumnya:

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'
  • Tetapkan perwakilan layanan Azure ke peran bawaan Azure berikut, sesuai kebutuhan. Tetapkan perwakilan layanan ke grup sumber daya Azure yang memiliki komputer yang akan disambungkan:
Peran Diperlukan untuk
Administrator atau Kontributor Sumber Daya Mesin yang Koneksi Azure Koneksi server VM kluster Nexus Kubernetes dengan dukungan Arc di grup sumber daya dan instal Azure Monitoring Agent (AMA)
Kontributor atau Kontributor Pemantauan Membuat Aturan Pengumpulan Data (DCR) di grup sumber daya dan mengaitkan server dengan dukungan Arc ke dalamnya
Administrator Akses Pengguna, dan Kontributor atau Kontributor Kebijakan Sumber Daya Diperlukan jika Anda ingin menggunakan penetapan kebijakan Azure untuk memastikan bahwa DCR dikaitkan dengan komputer berkemampuan Arc
Kontributor Ekstensi Kubernetes Diperlukan untuk menyebarkan ekstensi K8s untuk Container Insights

Penyiapan lingkungan

Salin dan jalankan skrip yang disertakan. Anda dapat menjalankannya dari Azure Cloud Shell, di portal Azure. Atau Anda dapat menjalankannya dari prompt perintah Linux tempat alat baris perintah Kubernetes (kubectl) dan Azure CLI diinstal.

Sebelum menjalankan skrip yang disertakan, tentukan variabel lingkungan berikut:

Variabel lingkungan Deskripsi
SUBSCRIPTION_ID ID langganan Azure yang berisi grup sumber daya
RESOURCE_GROUP Nama grup sumber daya tempat server yang didukung Arc dan sumber daya terkait dibuat
LOKASI Wilayah Azure tempat server yang diaktifkan Arc dan sumber daya terkait dibuat
SERVICE_PRINCIPAL_ID AppId dari perwakilan layanan Azure dengan penetapan peran yang sesuai
SERVICE_PRINCIPAL_SECRET Kata sandi autentikasi untuk perwakilan layanan Azure
TENANT_ID ID direktori penyewa tempat perwakilan layanan berada
PROXY_URL URL proksi yang digunakan untuk menyambungkan ke layanan Azure
NAMESPACE Namespace tempat artefak Kubernetes dibuat

Untuk kenyamanan, Anda dapat memodifikasi file templat, arc-connect.env, untuk mengatur nilai variabel lingkungan.

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

Menambahkan aturan pengumpulan data (DCR)

Kaitkan server berkemampuan Arc dengan DCR untuk mengaktifkan pengumpulan data log ke ruang kerja Analitik Log. Anda dapat membuat DCR melalui portal Azure atau CLI. Informasi tentang membuat DCR untuk mengumpulkan data dari VM tersedia di sini.

Skrip yang disertakan dcr.sh membuat DCR, dalam grup sumber daya yang ditentukan, yang akan mengonfigurasi pengumpulan log.

  1. Pastikan pengaturan lingkungan dan prasyarat peran yang tepat untuk perwakilan layanan. DCR dibuat dalam grup sumber daya yang ditentukan.

  2. Membuat atau mengidentifikasi ruang kerja Analitik Log untuk penyerapan data log sesuai DCR. Atur variabel lingkungan, LAW_RESOURCE_ID ke ID sumber dayanya. Ambil ID sumber daya untuk nama ruang kerja Analitik Log yang diketahui:

export LAW_RESOURCE_ID=$(az monitor log-analytics workspace show -g "${RESOURCE_GROUP}" -n <law name> --query id -o tsv)
  1. Jalankan skrip dcr.sh. Ini membuat DCR dalam grup sumber daya yang ditentukan dengan nama ${RESOURCE_GROUP}-syslog-dcr
./dcr.sh

Lihat/kelola DCR dari portal Azure atau CLI. Secara default, tingkat log Linux Syslog diatur ke "INFO". Anda dapat mengubah tingkat log sesuai kebutuhan.

Catatan

Secara manual, atau melalui kebijakan, mengaitkan server yang dibuat sebelum pembuatan DCR. Lihat tugas remediasi.

Mengaitkan sumber daya server dengan dukungan Arc ke DCR

Kaitkan sumber daya server dengan dukungan Arc ke DCR yang dibuat agar log mengalir ke ruang kerja Analitik Log. Ada opsi untuk mengaitkan server dengan DCR.

Gunakan portal Azure atau CLI untuk mengaitkan server berkemampuan Arc yang dipilih ke DCR

Di portal Azure, tambahkan sumber daya server dengan dukungan Arc ke DCR menggunakan bagian Sumber Dayanya.

Gunakan tautan ini untuk informasi tentang mengaitkan sumber daya melalui Azure CLI.

Menggunakan kebijakan Azure untuk mengelola asosiasi DCR

Tetapkan kebijakan ke grup sumber daya untuk memberlakukan asosiasi. Ada definisi kebijakan bawaan, untuk mengaitkan Linux Arc Machines dengan DCR. Tetapkan kebijakan ke grup sumber daya dengan DCR sebagai parameter. Ini memastikan asosiasi semua server berkemampuan Arc, dalam grup sumber daya, dengan DCR yang sama.

Di portal Azure, pilih tombol Assign dari halaman definisi kebijakan.

Untuk kenyamanan, skrip yang disediakan assign.sh menetapkan kebijakan bawaan ke grup sumber daya yang ditentukan dan DCR yang dibuat dengan dcr.sh skrip.

  1. Pastikan pengaturan lingkungan dan prasyarat peran yang tepat bagi perwakilan layanan untuk melakukan kebijakan dan penetapan peran.
  2. Buat DCR, di grup sumber daya, menggunakan dcr.sh skrip seperti yang dijelaskan di bagian Menambahkan Aturan Pengumpulan Data.
  3. Jalankan assign.sh skrip. Ini membuat penetapan kebijakan dan penetapan peran yang diperlukan.
./assign.sh

Menginstal agen pemantauan Azure

Gunakan yang disertakan install.sh yang membuat daemonSet Kubernetes pada kluster Nexus Kubernetes. Ini menyebarkan pod ke setiap node kluster dan menginstal Azure Monitoring Agent (AMA). Juga daemonSet termasuk pemeriksaan keaktifan yang memantau koneksi server dan proses AMA.

Catatan

Untuk menginstal Azure Monitoring Agent, Anda harus terlebih dahulu menghubungkan VM kluster Nexus Kubernetes. Proses ini diotomatisasi jika Anda menggunakan bundel versi terbaru. Namun, jika bundel versi yang Anda gunakan tidak mendukung pendaftaran Arc VM kluster secara default, Anda harus meningkatkan kluster Anda ke bundel versi terbaru. Untuk informasi lebih lanjut tentang bundel versi, silakan lihat versi yang didukung kluster Nexus Kubernetes

  1. Atur lingkungan seperti yang ditentukan dalam Penyiapan Lingkungan. Atur konteks saat ini kubeconfig untuk VM kluster Nexus Kubernetes.
  2. Izinkan Kubectl akses ke kluster Nexus Kubernetes.

    Catatan

    Saat Anda membuat kluster Nexus Kubernetes, Nexus secara otomatis membuat grup sumber daya terkelola yang didedikasikan untuk menyimpan sumber daya kluster, dalam grup ini, sumber daya kluster yang terhubung dengan Arc dibuat.

    Untuk mengakses kluster, Anda perlu menyiapkan koneksi kubeconfigkluster . Setelah masuk ke Azure CLI dengan entitas Microsoft Entra yang relevan, Anda dapat memperoleh yang kubeconfig diperlukan untuk berkomunikasi dengan kluster dari mana saja, bahkan di luar firewall yang mengelilinginya.
    1. Atur CLUSTER_NAMEvariabel , RESOURCE_GROUP dan SUBSCRIPTION_ID .

      CLUSTER_NAME="myNexusK8sCluster"
      RESOURCE_GROUP="myResourceGroup"
      SUBSCRIPTION_ID=<set the correct subscription_id>
      
    2. Mengkueri grup sumber daya terkelola dengan az dan menyimpan di 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. Perintah berikut memulai proksi connectedk8s yang memungkinkan Anda terhubung ke server API Kubernetes untuk kluster Nexus Kubernetes yang ditentukan.

      az connectedk8s proxy -n $CLUSTER_NAME  -g $MANAGED_RESOURCE_GROUP &
      
    4. Gunakan kubectl untuk mengirim permintaan ke kluster:

      kubectl get pods -A
      

      Anda sekarang akan melihat respons dari kluster yang berisi daftar semua simpul.

    Catatan

    Jika Anda melihat pesan kesalahan "Gagal memposting token akses ke proxy KlienFailed untuk terhubung ke MSI", Anda mungkin perlu melakukan autentikasi az login ulang dengan Azure.

  3. Jalankan install.sh skrip dari prompt perintah dengan akses kubectl ke kluster Nexus Kubernetes.

Skrip menyebarkan daemonSet ke kluster. Pantau kemajuannya sebagai berikut:

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

Setelah selesai, sistem mencatat pesan "Pemantauan server berhasil dikonfigurasi".

Catatan

Kaitkan server yang terhubung ini ke DCR. Setelah Anda mengonfigurasi kebijakan, mungkin ada beberapa penundaan untuk mengamati log di Ruang Kerja Azure Log Analytics

Memantau kluster Nexus Kubernetes – Lapisan K8s

Prasyarat-Kubernetes

Ada prasyarat tertentu yang harus dipastikan operator untuk mengonfigurasi alat pemantauan pada Kluster Kubernetes Nexus.

Container Insights menyimpan datanya di ruang kerja Analitik Log. Data log mengalir ke ruang kerja yang ID Sumber Dayanya Anda berikan selama skrip awal yang tercakup di bagian "Tambahkan aturan pengumpulan data (DCR)" . Jika tidak, corong data ke ruang kerja default di grup Sumber Daya yang terkait dengan langganan Anda (berdasarkan lokasi Azure).

Contoh untuk US Timur mungkin terlihat seperti berikut:

  • Nama ruang kerja Analitik Log: DefaultWorkspace-GUID-EUS<>
  • Nama grup sumber daya: DefaultResourceGroup-EUS

Jalankan perintah berikut untuk mendapatkan ID Sumber Daya ruang kerja Analitik Log yang sudah ada sebelumnya:

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

Untuk menyebarkan Wawasan Kontainer dan melihat data di ruang kerja Analitik Log yang berlaku memerlukan penetapan peran tertentu di akun Anda. Misalnya, penetapan peran "Kontributor". Lihat instruksi untuk menetapkan peran yang diperlukan:

  • Peran Kontributor Analitik Log: izin yang diperlukan untuk mengaktifkan pemantauan kontainer pada kluster CNF (disediakan).
  • Peran Pembaca Analitik Log: non-anggota peran Kontributor Analitik Log, menerima izin untuk melihat data di ruang kerja Analitik Log setelah Anda mengaktifkan pemantauan kontainer.

Menginstal ekstensi kluster

Masuk ke Azure Cloud Shell untuk mengakses kluster:

az login

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

Sekarang, sebarkan ekstensi Container Insights pada kluster Nexus Kubernetes yang disediakan menggunakan salah satu dari dua perintah berikutnya:

Dengan ruang kerja Analitik log yang telah dibuat sebelumnya kepada pelanggan

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

Menggunakan ruang kerja analitik Log default

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

Memvalidasi ekstensi Kluster

Validasi keberhasilan penyebaran pengaktifan agen pemantauan pada Kluster Kubernetes Nexus menggunakan perintah berikut:

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

Cari Status Provisi "Berhasil" untuk ekstensi. Perintah "k8s-extension create" mungkin juga mengembalikan status.

Menyesuaikan pengumpulan log & metrik

Container Insights menyediakan fungsionalitas pengguna akhir untuk menyempurnakan pengumpulan log dan metrik dari Kluster Nexus Kubernetes--Mengonfigurasi pengumpulan data agen wawasan Kontainer.

Sumber daya ekstra

  • Tinjau dokumentasi buku kerja lalu Anda dapat menggunakan sampel telemetri Operator Nexus Operator buku kerja Nexus.
  • Tinjau Pemberitahuan Azure Monitor, cara membuat aturan Pemberitahuan Azure Monitor, dan menggunakan contoh templat Pemberitahuan Nexus Operator.