k8s和deepflow部署与测试

Ubuntu-22-LTS部署k8s和deepflow

环境详情:
Static hostname: k8smaster.example.net
Icon name: computer-vm
Chassis: vm
Machine ID: 22349ac6f9ba406293d0541bcba7c05d
Boot ID: 605a74a509724a88940bbbb69cde77f2
Virtualization: vmware
Operating System: Ubuntu 22.04.4 LTS
Kernel: Linux 5.15.0-106-generic
Architecture: x86-64
Hardware Vendor: VMware, Inc.
Hardware Model: VMware Virtual Platform

当您在 Ubuntu 22.04 上安装 Kubernetes 集群时,您可以遵循以下步骤:

  1. 设置主机名并在 hosts 文件中添加条目

    • 登录到主节点并使用 hostnamectl 命令设置主机名:

      hostnamectl set-hostname "k8smaster.example.net"
      
    • 在工作节点上,运行以下命令设置主机名(分别对应第一个和第二个工作节点):

      hostnamectl set-hostname "k8sworker1.example.net"  # 第一个工作节点
      hostnamectl set-hostname "k8sworker2.example.net"  # 第二个工作节点
      
    • 在每个节点的 /etc/hosts 文件中添加以下条目:

      10.1.1.70 k8smaster.example.net k8smaster
      10.1.1.71 k8sworker1.example.net k8sworker1
      
  2. 禁用 swap 并添加内核设置

    • 在所有节点上执行以下命令以禁用交换功能:

      swapoff -a
      sed -i '/swap/ s/^\(.*\)$/#\1/g' /etc/fstab
      
    • 加载以下内核模块:

      tee /etc/modules-load.d/containerd.conf <<EOF
      overlay
      br_netfilter
      EOF
      modprobe overlay
      modprobe br_netfilter
      
    • 为 Kubernetes 设置以下内核参数:

      tee /etc/sysctl.d/kubernetes.conf <<EOF
      net.bridge.bridge-nf-call-ip6tables = 1
      net.bridge.bridge-nf-call-iptables = 1
      net.ipv4.ip_forward = 1
      EOF
      sysctl --system
      
  3. 安装 containerd 运行时

    • 首先安装 containerd 的依赖项:

      apt install -y curl gnupg2 software-properties-common apt-transport-https ca-certificates
      
    • 启用 Docker 存储库:

      curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
      add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
      
    • 安装 containerd:

      apt update
      apt install -y containerd.io
      
    • 配置 containerd 使用 systemd 作为 cgroup:

      containerd config default | tee /etc/containerd/config.toml > /dev/null 2>&1
      sed -i 's/SystemdCgroup\\=false/SystemdCgroup\\=true/g' /etc/containerd/config.toml
      

      部分配置手动修改

      disabled_plugins = []
      imports = []
      oom_score = 0
      plugin_dir = ""
      required_plugins = []
      root = "/var/lib/containerd"
      state = "/run/containerd"
      temp = ""
      version = 2[cgroup]
      path = ""[debug]
      address = ""
      format = ""
      gid = 0
      level = ""
      uid = 0[grpc]
      address = "/run/containerd/containerd.sock"
      gid = 0
      max_recv_message_size = 16777216
      max_send_message_size = 16777216
      tcp_address = ""
      tcp_tls_ca = ""
      tcp_tls_cert = ""
      tcp_tls_key = ""
      uid = 0[metrics]
      address = ""
      grpc_histogram = false[plugins][plugins."io.containerd.gc.v1.scheduler"]deletion_threshold = 0mutation_threshold = 100pause_threshold = 0.02schedule_delay = "0s"startup_delay = "100ms"[plugins."io.containerd.grpc.v1.cri"]device_ownership_from_security_context = falsedisable_apparmor = falsedisable_cgroup = falsedisable_hugetlb_controller = truedisable_proc_mount = falsedisable_tcp_service = truedrain_exec_sync_io_timeout = "0s"enable_selinux = falseenable_tls_streaming = falseenable_unprivileged_icmp = falseenable_unprivileged_ports = falseignore_deprecation_warnings = []ignore_image_defined_volumes = falsemax_concurrent_downloads = 3max_container_log_line_size = 16384netns_mounts_under_state_dir = falserestrict_oom_score_adj = false# 修改以下这行sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.8"selinux_category_range = 1024stats_collect_period = 10stream_idle_timeout = "4h0m0s"stream_server_address = "127.0.0.1"stream_server_port = "0"systemd_cgroup = falsetolerate_missing_hugetlb_controller = trueunset_seccomp_profile = ""[plugins."io.containerd.grpc.v1.cri".cni]bin_dir = "/opt/cni/bin"conf_dir = "/etc/cni/net.d"conf_template = ""ip_pref = ""max_conf_num = 1[plugins."io.containerd.grpc.v1.cri".containerd]default_runtime_name = "runc"disable_snapshot_annotations = truediscard_unpacked_layers = falseignore_rdt_not_enabled_errors = falseno_pivot = falsesnapshotter = "overlayfs"[plugins."io.containerd.grpc.v1.cri".containerd.default_runtime]base_runtime_spec = ""cni_conf_dir = ""cni_max_conf_num = 0container_annotations = []pod_annotations = []privileged_without_host_devices = falseruntime_engine = ""runtime_path = ""runtime_root = ""runtime_type = ""[plugins."io.containerd.grpc.v1.cri".containerd.default_runtime.options][plugins."io.containerd.grpc.v1.cri".containerd.runtimes][plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]base_runtime_spec = ""cni_conf_dir = ""cni_max_conf_num = 0container_annotations = []pod_annotations = []privileged_without_host_devices = falseruntime_engine = ""runtime_path = ""runtime_root = ""runtime_type = "io.containerd.runc.v2"[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]BinaryName = ""CriuImagePath = ""CriuPath = ""CriuWorkPath = ""IoGid = 0IoUid = 0NoNewKeyring = falseNoPivotRoot = falseRoot = ""ShimCgroup = ""SystemdCgroup = true[plugins."io.containerd.grpc.v1.cri".containerd.untrusted_workload_runtime]base_runtime_spec = ""cni_conf_dir = ""cni_max_conf_num = 0container_annotations = []pod_annotations = []privileged_without_host_devices = falseruntime_engine = ""runtime_path = ""runtime_root = ""runtime_type = ""[plugins."io.containerd.grpc.v1.cri".containerd.untrusted_workload_runtime.options][plugins."io.containerd.grpc.v1.cri".image_decryption]key_model = "node"[plugins."io.containerd.grpc.v1.cri".registry]config_path = ""[plugins."io.containerd.grpc.v1.cri".registry.auths][plugins."io.containerd.grpc.v1.cri".registry.configs][plugins."io.containerd.grpc.v1.cri".registry.headers][plugins."io.containerd.grpc.v1.cri".registry.mirrors]# 添加如下4行[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]endpoint = ["https://docker.mirrors.ustc.edu.cn"][plugins."io.containerd.grpc.v1.cri".registry.mirrors."k8s.gcr.io"]endpoint = ["https://registry.aliyuncs.com/google_containers"][plugins."io.containerd.grpc.v1.cri".x509_key_pair_streaming]tls_cert_file = ""tls_key_file = ""[plugins."io.containerd.internal.v1.opt"]path = "/opt/containerd"[plugins."io.containerd.internal.v1.restart"]interval = "10s"[plugins."io.containerd.internal.v1.tracing"]sampling_ratio = 1.0service_name = "containerd"[plugins."io.containerd.metadata.v1.bolt"]content_sharing_policy = "shared"[plugins."io.containerd.monitor.v1.cgroups"]no_prometheus = false[plugins."io.containerd.runtime.v1.linux"]no_shim = falseruntime = "runc"runtime_root = ""shim = "containerd-shim"shim_debug = false[plugins."io.containerd.runtime.v2.task"]platforms = ["linux/amd64"]sched_core = false[plugins."io.containerd.service.v1.diff-service"]default = ["walking"][plugins."io.containerd.service.v1.tasks-service"]rdt_config_file = ""[plugins."io.containerd.snapshotter.v1.aufs"]root_path = ""[plugins."io.containerd.snapshotter.v1.btrfs"]root_path = ""[plugins."io.containerd.snapshotter.v1.devmapper"]async_remove = falsebase_image_size = ""discard_blocks = falsefs_options = ""fs_type = ""pool_name = ""root_path = ""[plugins."io.containerd.snapshotter.v1.native"]root_path = ""[plugins."io.containerd.snapshotter.v1.overlayfs"]mount_options = []root_path = ""sync_remove = falseupperdir_label = false[plugins."io.containerd.snapshotter.v1.zfs"]root_path = ""[plugins."io.containerd.tracing.processor.v1.otlp"]endpoint = ""insecure = falseprotocol = ""[proxy_plugins][stream_processors][stream_processors."io.containerd.ocicrypt.decoder.v1.tar"]accepts = ["application/vnd.oci.image.layer.v1.tar+encrypted"]args = ["--decryption-keys-path", "/etc/containerd/ocicrypt/keys"]env = ["OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf"]path = "ctd-decoder"returns = "application/vnd.oci.image.layer.v1.tar"[stream_processors."io.containerd.ocicrypt.decoder.v1.tar.gzip"]accepts = ["application/vnd.oci.image.layer.v1.tar+gzip+encrypted"]args = ["--decryption-keys-path", "/etc/containerd/ocicrypt/keys"]env = ["OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf"]path = "ctd-decoder"returns = "application/vnd.oci.image.layer.v1.tar+gzip"[timeouts]
      "io.containerd.timeout.bolt.open" = "0s"
      "io.containerd.timeout.shim.cleanup" = "5s"
      "io.containerd.timeout.shim.load" = "5s"
      "io.containerd.timeout.shim.shutdown" = "3s"
      "io.containerd.timeout.task.state" = "2s"[ttrpc]
      address = ""
      gid = 0
      uid = 0
      
    • 重启并启用容器服务:

      systemctl restart containerd
      systemctl enable containerd
      
    • 设置crictl

      cat > /etc/crictl.yaml <<EOF
      runtime-endpoint: unix:///var/run/containerd/containerd.sock
      image-endpoint: unix:///var/run/containerd/containerd.sock
      timeout: 10
      debug: false
      pull-image-on-create: false
      EOF
      
  4. 添加阿里云的 Kubernetes 源

    • 首先,导入阿里云的 GPG 密钥:

      curl -fsSL https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
      
    • 然后,添加阿里云的 Kubernetes 源:

      tee /etc/apt/sources.list.d/kubernetes.list <<EOF
      deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
      EOF
      
  5. 安装 Kubernetes 组件

    • 更新软件包索引并安装 kubelet、kubeadm 和 kubectl:

      apt-get update
      apt-get install -y kubelet kubeadm kubectl
      
    • 设置 kubelet 使用 systemd 作为 cgroup 驱动:

      # 可忽略
      # sed -i 's/cgroup-driver=systemd/cgroup-driver=cgroupfs/g' /var/lib/kubelet/kubeadm-flags.env
      # systemctl daemon-reload
      # systemctl restart kubelet
      
  6. 初始化 Kubernetes 集群

    • 使用 kubeadm 初始化集群,并指定阿里云的镜像仓库:

      # kubeadm init --image-repository registry.aliyuncs.com/google_containers
      I0513 14:16:59.740096   17563 version.go:256] remote version is much newer: v1.30.0; falling back to: stable-1.28
      [init] Using Kubernetes version: v1.28.9
      [preflight] Running pre-flight checks
      [preflight] Pulling images required for setting up a Kubernetes cluster
      [preflight] This might take a minute or two, depending on the speed of your internet connection
      [preflight] You can also perform this action in beforehand using 'kubeadm config images pull'
      W0513 14:17:01.440936   17563 checks.go:835] detected that the sandbox image "registry.aliyuncs.com/google_containers/pause:3.8" of the container runtime         is inconsistent with that used by kubeadm. It is recommended that using "registry.aliyuncs.com/google_containers/pause:3.9" as the CRI sandbox image.
      [certs] Using certificateDir folder "/etc/kubernetes/pki"
      [certs] Generating "ca" certificate and key
      [certs] Generating "apiserver" certificate and key
      [certs] apiserver serving cert is signed for DNS names [k8smaster.example.net kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.        cluster.local] and IPs [10.96.0.1 10.1.1.70]
      [certs] Generating "apiserver-kubelet-client" certificate and key
      [certs] Generating "front-proxy-ca" certificate and key
      [certs] Generating "front-proxy-client" certificate and key
      [certs] Generating "etcd/ca" certificate and key
      [certs] Generating "etcd/server" certificate and key
      [certs] etcd/server serving cert is signed for DNS names [k8smaster.example.net localhost] and IPs [10.1.1.70 127.0.0.1 ::1]
      [certs] Generating "etcd/peer" certificate and key
      [certs] etcd/peer serving cert is signed for DNS names [k8smaster.example.net localhost] and IPs [10.1.1.70 127.0.0.1 ::1]
      [certs] Generating "etcd/healthcheck-client" certificate and key
      [certs] Generating "apiserver-etcd-client" certificate and key
      [certs] Generating "sa" key and public key
      [kubeconfig] Using kubeconfig folder "/etc/kubernetes"
      [kubeconfig] Writing "admin.conf" kubeconfig file
      [kubeconfig] Writing "kubelet.conf" kubeconfig file
      [kubeconfig] Writing "controller-manager.conf" kubeconfig file
      [kubeconfig] Writing "scheduler.conf" kubeconfig file
      [etcd] Creating static Pod manifest for local etcd in "/etc/kubernetes/manifests"
      [control-plane] Using manifest folder "/etc/kubernetes/manifests"
      [control-plane] Creating static Pod manifest for "kube-apiserver"
      [control-plane] Creating static Pod manifest for "kube-controller-manager"
      [control-plane] Creating static Pod manifest for "kube-scheduler"
      [kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
      [kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
      [kubelet-start] Starting the kubelet
      [wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory "/etc/kubernetes/manifests". This can take up to         4m0s
      [apiclient] All control plane components are healthy after 4.002079 seconds
      [upload-config] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
      [kubelet] Creating a ConfigMap "kubelet-config" in namespace kube-system with the configuration for the kubelets in the cluster
      [upload-certs] Skipping phase. Please see --upload-certs
      [mark-control-plane] Marking the node k8smaster.example.net as control-plane by adding the labels: [node-role.kubernetes.io/control-plane node.kubernetes.        io/exclude-from-external-load-balancers]
      [mark-control-plane] Marking the node k8smaster.example.net as control-plane by adding the taints [node-role.kubernetes.io/control-plane:NoSchedule]
      [bootstrap-token] Using token: m9z4yq.dok89ro6yt23wykr
      [bootstrap-token] Configuring bootstrap tokens, cluster-info ConfigMap, RBAC Roles
      [bootstrap-token] Configured RBAC rules to allow Node Bootstrap tokens to get nodes
      [bootstrap-token] Configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials
      [bootstrap-token] Configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
      [bootstrap-token] Configured RBAC rules to allow certificate rotation for all node client certificates in the cluster
      [bootstrap-token] Creating the "cluster-info" ConfigMap in the "kube-public" namespace
      [kubelet-finalize] Updating "/etc/kubernetes/kubelet.conf" to point to a rotatable kubelet client certificate and key
      [addons] Applied essential addon: CoreDNS
      [addons] Applied essential addon: kube-proxyYour Kubernetes control-plane has initialized successfully!To start using your cluster, you need to run the following as a regular user:mkdir -p $HOME/.kubesudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/configsudo chown $(id -u):$(id -g) $HOME/.kube/configAlternatively, if you are the root user, you can run:export KUBECONFIG=/etc/kubernetes/admin.confYou should now deploy a pod network to the cluster.
      Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:https://kubernetes.io/docs/concepts/cluster-administration/addons/Then you can join any number of worker nodes by running the following on each as root:kubeadm join 10.1.1.70:6443 --token m9z4yq.dok89ro6yt23wykr \--discovery-token-ca-cert-hash sha256:17c3f29bd276592e668e9e6a7a187140a887254b4555cf7d293c3313d7c8a178 
      
  7. 配置 kubectl

    • 为当前用户设置 kubectl 访问:

      mkdir -p $HOME/.kube
      cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
      chown $(id -u):$(id -g) $HOME/.kube/config
      
  8. 安装网络插件

    • 安装一个 Pod 网络插件,例如 Calico 或 Flannel。例如,使用 Calico:

      kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
      # 网络插件初始化完毕之后,coredns容器就正常了
      kubectl logs -n kube-system -l k8s-app=kube-dns
      
  9. 验证集群

    • 启动一个nginx pod:

      # vim nginx_pod.yml
      apiVersion: v1
      kind: Pod
      metadata:name: test-nginx-podnamespace: testlabels:app: nginx
      spec:containers:- name: test-nginx-containerimage: nginx:latestports:- containerPort: 80tolerations:- key: "node-role.kubernetes.io/control-plane"operator: "Exists"effect: "NoSchedule"
      ---apiVersion: v1
      kind: Service
      # service和pod必须位于同一个namespace
      metadata:name: nginx-servicenamespace: test
      spec:type: NodePort# selector应该匹配pod的labelsselector:app: nginxports:- protocol: TCPport: 80nodePort: 30007targetPort: 80
      

      启动

      kubectl apply -f nginx_pod.yml
      

部署opentelemetry-collector测试

otel-collector和otel-agent需要程序集成API,发送到以DaemonSet运行在每个节点的otel-agent,otel-agent再将数据发送给otel-collector汇总,然后发往可以处理otlp trace数据的后端,如zipkin、jaeger等。

自定义测试yaml文件

apiVersion: v1
kind: ConfigMap
metadata:name: otel-collector-confnamespace: default
data:# 你的配置数据config.yaml: |receivers:otlp:protocols:grpc:http:processors:batch:exporters:logging:loglevel: debugservice:pipelines:traces:receivers: [otlp]processors: [batch]exporters: [logging]---
apiVersion: v1
kind: Service
metadata:name: otel-collectorlabels:app: opentelemetry
spec:type: NodePortports:- port: 4317targetPort: 4317nodePort: 30080name: otlp-grpc- port: 8888targetPort: 8888name: metricsselector:component: otel-collector---
apiVersion: apps/v1
kind: Deployment
metadata:name: otel-collectorlabels:app: opentelemetry
spec:replicas: 1selector:matchLabels:component: otel-collectortemplate:metadata:labels:component: otel-collectorspec:tolerations:- key: node-role.kubernetes.io/control-planeoperator: Existseffect: NoSchedulecontainers:- name: otel-collectorimage: otel/opentelemetry-collector:latestports:- containerPort: 4317- containerPort: 8888env:- name: MY_POD_IPvalueFrom:fieldRef:fieldPath: status.podIPvolumeMounts:- name: otel-collector-config-volmountPath: /confvolumes:- configMap:name: otel-collector-confname: otel-collector-config-vol

启动

mkdir /conf
kubectl apply -f otel-collector.yaml
kubectl get -f otel-collector.yaml

删除

kubectl delete -f otel-collector.yaml

使用官方提供示例

kubectl apply -f https://raw.githubusercontent.com/open-telemetry/opentelemetry-collector/main/examples/k8s/otel-config.yaml

根据需要修改文件

otel-config.yaml

---
apiVersion: v1
kind: ConfigMap
metadata:name: otel-agent-conflabels:app: opentelemetrycomponent: otel-agent-conf
data:otel-agent-config: |receivers:otlp:protocols:grpc:endpoint: ${env:MY_POD_IP}:4317http:endpoint: ${env:MY_POD_IP}:4318exporters:otlp:endpoint: "otel-collector.default:4317"tls:insecure: truesending_queue:num_consumers: 4queue_size: 100retry_on_failure:enabled: trueprocessors:batch:memory_limiter:# 80% of maximum memory up to 2Glimit_mib: 400# 25% of limit up to 2Gspike_limit_mib: 100check_interval: 5sextensions:zpages: {}service:extensions: [zpages]pipelines:traces:receivers: [otlp]processors: [memory_limiter, batch]exporters: [otlp]
---
apiVersion: apps/v1
kind: DaemonSet
metadata:name: otel-agentlabels:app: opentelemetrycomponent: otel-agent
spec:selector:matchLabels:app: opentelemetrycomponent: otel-agenttemplate:metadata:labels:app: opentelemetrycomponent: otel-agentspec:tolerations:- key: node-role.kubernetes.io/control-planeoperator: Existseffect: NoSchedulecontainers:- command:- "/otelcol"- "--config=/conf/otel-agent-config.yaml"image: otel/opentelemetry-collector:0.94.0name: otel-agentresources:limits:cpu: 500mmemory: 500Mirequests:cpu: 100mmemory: 100Miports:- containerPort: 55679 # ZPages endpoint.- containerPort: 4317 # Default OpenTelemetry receiver port.- containerPort: 8888  # Metrics.env:- name: MY_POD_IPvalueFrom:fieldRef:apiVersion: v1fieldPath: status.podIP- name: GOMEMLIMITvalue: 400MiBvolumeMounts:- name: otel-agent-config-volmountPath: /confvolumes:- configMap:name: otel-agent-confitems:- key: otel-agent-configpath: otel-agent-config.yamlname: otel-agent-config-vol
---
apiVersion: v1
kind: ConfigMap
metadata:name: otel-collector-conflabels:app: opentelemetrycomponent: otel-collector-conf
data:otel-collector-config: |receivers:otlp:protocols:grpc:endpoint: ${env:MY_POD_IP}:4317http:endpoint: ${env:MY_POD_IP}:4318processors:batch:memory_limiter:# 80% of maximum memory up to 2Glimit_mib: 1500# 25% of limit up to 2Gspike_limit_mib: 512check_interval: 5sextensions:zpages: {}exporters:otlp:endpoint: "http://someotlp.target.com:4317" # Replace with a real endpoint.tls:insecure: truezipkin:endpoint: "http://10.1.1.10:9411/api/v2/spans"format: "proto"service:extensions: [zpages]pipelines:traces/1:receivers: [otlp]processors: [memory_limiter, batch]exporters: [zipkin]
---
apiVersion: v1
kind: Service
metadata:name: otel-collectorlabels:app: opentelemetrycomponent: otel-collector
spec:ports:- name: otlp-grpc # Default endpoint for OpenTelemetry gRPC receiver.port: 4317protocol: TCPtargetPort: 4317- name: otlp-http # Default endpoint for OpenTelemetry HTTP receiver.port: 4318protocol: TCPtargetPort: 4318- name: metrics # Default endpoint for querying metrics.port: 8888selector:component: otel-collector
---
apiVersion: apps/v1
kind: Deployment
metadata:name: otel-collectorlabels:app: opentelemetrycomponent: otel-collector
spec:selector:matchLabels:app: opentelemetrycomponent: otel-collectorminReadySeconds: 5progressDeadlineSeconds: 120replicas: 1 #TODO - adjust this to your own requirementstemplate:metadata:labels:app: opentelemetrycomponent: otel-collectorspec:tolerations:- key: node-role.kubernetes.io/control-planeoperator: Existseffect: NoSchedulecontainers:- command:- "/otelcol"- "--config=/conf/otel-collector-config.yaml"image: otel/opentelemetry-collector:0.94.0name: otel-collectorresources:limits:cpu: 1memory: 2Girequests:cpu: 200mmemory: 400Miports:- containerPort: 55679 # Default endpoint for ZPages.- containerPort: 4317 # Default endpoint for OpenTelemetry receiver.- containerPort: 14250 # Default endpoint for Jaeger gRPC receiver.- containerPort: 14268 # Default endpoint for Jaeger HTTP receiver.- containerPort: 9411 # Default endpoint for Zipkin receiver.- containerPort: 8888  # Default endpoint for querying metrics.env:- name: MY_POD_IPvalueFrom:fieldRef:apiVersion: v1fieldPath: status.podIP- name: GOMEMLIMITvalue: 1600MiBvolumeMounts:- name: otel-collector-config-volmountPath: /conf
#        - name: otel-collector-secrets
#          mountPath: /secretsvolumes:- configMap:name: otel-collector-confitems:- key: otel-collector-configpath: otel-collector-config.yamlname: otel-collector-config-vol
#        - secret:
#            name: otel-collector-secrets
#            items:
#              - key: cert.pem
#                path: cert.pem
#              - key: key.pem
#                path: key.pem

部署deepflow监控单个k8s集群

官方文档
官方demo

安装helm

snap install helm --classic

设置pv

kubectl apply -f https://openebs.github.io/charts/openebs-operator.yaml
## config default storage class
kubectl patch storageclass openebs-hostpath  -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'

部署deepflow

helm repo add deepflow https://deepflowio.github.io/deepflow
helm repo update deepflow # use `helm repo update` when helm < 3.7.0
helm install deepflow -n deepflow deepflow/deepflow --create-namespace
# 显示如下
NAME: deepflow
LAST DEPLOYED: Tue May 14 14:13:50 2024
NAMESPACE: deepflow
STATUS: deployed
REVISION: 1
NOTES:
██████╗ ███████╗███████╗██████╗ ███████╗██╗      ██████╗ ██╗    ██╗
██╔══██╗██╔════╝██╔════╝██╔══██╗██╔════╝██║     ██╔═══██╗██║    ██║
██║  ██║█████╗  █████╗  ██████╔╝█████╗  ██║     ██║   ██║██║ █╗ ██║
██║  ██║██╔══╝  ██╔══╝  ██╔═══╝ ██╔══╝  ██║     ██║   ██║██║███╗██║
██████╔╝███████╗███████╗██║     ██║     ███████╗╚██████╔╝╚███╔███╔╝
╚═════╝ ╚══════╝╚══════╝╚═╝     ╚═╝     ╚══════╝ ╚═════╝  ╚══╝╚══╝ An automated observability platform for cloud-native developers.# deepflow-agent Port for receiving trace, metrics, and logdeepflow-agent service: deepflow-agent.deepflow
deepflow-agent Host listening port: 38086# Get the Grafana URL to visit by running these commands in the same shellNODE_PORT=$(kubectl get --namespace deepflow -o jsonpath="{.spec.ports[0].nodePort}" services deepflow-grafana)
NODE_IP=$(kubectl get nodes -o jsonpath="{.items[0].status.addresses[0].address}")
echo -e "Grafana URL: http://$NODE_IP:$NODE_PORT  \nGrafana auth: admin:deepflow"

节点安装deepflow-ctl

curl -o /usr/bin/deepflow-ctl https://deepflow-ce.oss-cn-beijing.aliyuncs.com/bin/ctl/stable/linux/$(arch | sed 's|x86_64|amd64|' | sed 's|aarch64|arm64|')/deepflow-ctl
chmod a+x /usr/bin/deepflow-ctl

访问grafana页面

NODE_PORT=$(kubectl get --namespace deepflow -o jsonpath="{.spec.ports[0].nodePort}" services deepflow-grafana)
NODE_IP=$(kubectl get nodes -o jsonpath="{.items[0].status.addresses[0].address}")
echo -e "Grafana URL: http://$NODE_IP:$NODE_PORT  \nGrafana auth: admin:deepflow"

Ubuntu-22-LTS部署k8s和deepflow

环境详情:
Static hostname: k8smaster.example.net
Icon name: computer-vm
Chassis: vm
Machine ID: 22349ac6f9ba406293d0541bcba7c05d
Boot ID: 605a74a509724a88940bbbb69cde77f2
Virtualization: vmware
Operating System: Ubuntu 22.04.4 LTS
Kernel: Linux 5.15.0-106-generic
Architecture: x86-64
Hardware Vendor: VMware, Inc.
Hardware Model: VMware Virtual Platform

当您在 Ubuntu 22.04 上安装 Kubernetes 集群时,您可以遵循以下步骤:

  1. 设置主机名并在 hosts 文件中添加条目

    • 登录到主节点并使用 hostnamectl 命令设置主机名:

      hostnamectl set-hostname "k8smaster.example.net"
      
    • 在工作节点上,运行以下命令设置主机名(分别对应第一个和第二个工作节点):

      hostnamectl set-hostname "k8sworker1.example.net"  # 第一个工作节点
      hostnamectl set-hostname "k8sworker2.example.net"  # 第二个工作节点
      
    • 在每个节点的 /etc/hosts 文件中添加以下条目:

      10.1.1.70 k8smaster.example.net k8smaster
      10.1.1.71 k8sworker1.example.net k8sworker1
      
  2. 禁用 swap 并添加内核设置

    • 在所有节点上执行以下命令以禁用交换功能:

      swapoff -a
      sed -i '/swap/ s/^\(.*\)$/#\1/g' /etc/fstab
      
    • 加载以下内核模块:

      tee /etc/modules-load.d/containerd.conf <<EOF
      overlay
      br_netfilter
      EOF
      modprobe overlay
      modprobe br_netfilter
      
    • 为 Kubernetes 设置以下内核参数:

      tee /etc/sysctl.d/kubernetes.conf <<EOF
      net.bridge.bridge-nf-call-ip6tables = 1
      net.bridge.bridge-nf-call-iptables = 1
      net.ipv4.ip_forward = 1
      EOF
      sysctl --system
      
  3. 安装 containerd 运行时

    • 首先安装 containerd 的依赖项:

      apt install -y curl gnupg2 software-properties-common apt-transport-https ca-certificates
      
    • 启用 Docker 存储库:

      curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
      add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
      
    • 安装 containerd:

      apt update
      apt install -y containerd.io
      
    • 配置 containerd 使用 systemd 作为 cgroup:

      containerd config default | tee /etc/containerd/config.toml > /dev/null 2>&1
      sed -i 's/SystemdCgroup\\=false/SystemdCgroup\\=true/g' /etc/containerd/config.toml
      

      部分配置手动修改

      disabled_plugins = []
      imports = []
      oom_score = 0
      plugin_dir = ""
      required_plugins = []
      root = "/var/lib/containerd"
      state = "/run/containerd"
      temp = ""
      version = 2[cgroup]
      path = ""[debug]
      address = ""
      format = ""
      gid = 0
      level = ""
      uid = 0[grpc]
      address = "/run/containerd/containerd.sock"
      gid = 0
      max_recv_message_size = 16777216
      max_send_message_size = 16777216
      tcp_address = ""
      tcp_tls_ca = ""
      tcp_tls_cert = ""
      tcp_tls_key = ""
      uid = 0[metrics]
      address = ""
      grpc_histogram = false[plugins][plugins."io.containerd.gc.v1.scheduler"]deletion_threshold = 0mutation_threshold = 100pause_threshold = 0.02schedule_delay = "0s"startup_delay = "100ms"[plugins."io.containerd.grpc.v1.cri"]device_ownership_from_security_context = falsedisable_apparmor = falsedisable_cgroup = falsedisable_hugetlb_controller = truedisable_proc_mount = falsedisable_tcp_service = truedrain_exec_sync_io_timeout = "0s"enable_selinux = falseenable_tls_streaming = falseenable_unprivileged_icmp = falseenable_unprivileged_ports = falseignore_deprecation_warnings = []ignore_image_defined_volumes = falsemax_concurrent_downloads = 3max_container_log_line_size = 16384netns_mounts_under_state_dir = falserestrict_oom_score_adj = false# 修改以下这行sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.8"selinux_category_range = 1024stats_collect_period = 10stream_idle_timeout = "4h0m0s"stream_server_address = "127.0.0.1"stream_server_port = "0"systemd_cgroup = falsetolerate_missing_hugetlb_controller = trueunset_seccomp_profile = ""[plugins."io.containerd.grpc.v1.cri".cni]bin_dir = "/opt/cni/bin"conf_dir = "/etc/cni/net.d"conf_template = ""ip_pref = ""max_conf_num = 1[plugins."io.containerd.grpc.v1.cri".containerd]default_runtime_name = "runc"disable_snapshot_annotations = truediscard_unpacked_layers = falseignore_rdt_not_enabled_errors = falseno_pivot = falsesnapshotter = "overlayfs"[plugins."io.containerd.grpc.v1.cri".containerd.default_runtime]base_runtime_spec = ""cni_conf_dir = ""cni_max_conf_num = 0container_annotations = []pod_annotations = []privileged_without_host_devices = falseruntime_engine = ""runtime_path = ""runtime_root = ""runtime_type = ""[plugins."io.containerd.grpc.v1.cri".containerd.default_runtime.options][plugins."io.containerd.grpc.v1.cri".containerd.runtimes][plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]base_runtime_spec = ""cni_conf_dir = ""cni_max_conf_num = 0container_annotations = []pod_annotations = []privileged_without_host_devices = falseruntime_engine = ""runtime_path = ""runtime_root = ""runtime_type = "io.containerd.runc.v2"[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]BinaryName = ""CriuImagePath = ""CriuPath = ""CriuWorkPath = ""IoGid = 0IoUid = 0NoNewKeyring = falseNoPivotRoot = falseRoot = ""ShimCgroup = ""SystemdCgroup = true[plugins."io.containerd.grpc.v1.cri".containerd.untrusted_workload_runtime]base_runtime_spec = ""cni_conf_dir = ""cni_max_conf_num = 0container_annotations = []pod_annotations = []privileged_without_host_devices = falseruntime_engine = ""runtime_path = ""runtime_root = ""runtime_type = ""[plugins."io.containerd.grpc.v1.cri".containerd.untrusted_workload_runtime.options][plugins."io.containerd.grpc.v1.cri".image_decryption]key_model = "node"[plugins."io.containerd.grpc.v1.cri".registry]config_path = ""[plugins."io.containerd.grpc.v1.cri".registry.auths][plugins."io.containerd.grpc.v1.cri".registry.configs][plugins."io.containerd.grpc.v1.cri".registry.headers][plugins."io.containerd.grpc.v1.cri".registry.mirrors]# 添加如下4行[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]endpoint = ["https://docker.mirrors.ustc.edu.cn"][plugins."io.containerd.grpc.v1.cri".registry.mirrors."k8s.gcr.io"]endpoint = ["https://registry.aliyuncs.com/google_containers"][plugins."io.containerd.grpc.v1.cri".x509_key_pair_streaming]tls_cert_file = ""tls_key_file = ""[plugins."io.containerd.internal.v1.opt"]path = "/opt/containerd"[plugins."io.containerd.internal.v1.restart"]interval = "10s"[plugins."io.containerd.internal.v1.tracing"]sampling_ratio = 1.0service_name = "containerd"[plugins."io.containerd.metadata.v1.bolt"]content_sharing_policy = "shared"[plugins."io.containerd.monitor.v1.cgroups"]no_prometheus = false[plugins."io.containerd.runtime.v1.linux"]no_shim = falseruntime = "runc"runtime_root = ""shim = "containerd-shim"shim_debug = false[plugins."io.containerd.runtime.v2.task"]platforms = ["linux/amd64"]sched_core = false[plugins."io.containerd.service.v1.diff-service"]default = ["walking"][plugins."io.containerd.service.v1.tasks-service"]rdt_config_file = ""[plugins."io.containerd.snapshotter.v1.aufs"]root_path = ""[plugins."io.containerd.snapshotter.v1.btrfs"]root_path = ""[plugins."io.containerd.snapshotter.v1.devmapper"]async_remove = falsebase_image_size = ""discard_blocks = falsefs_options = ""fs_type = ""pool_name = ""root_path = ""[plugins."io.containerd.snapshotter.v1.native"]root_path = ""[plugins."io.containerd.snapshotter.v1.overlayfs"]mount_options = []root_path = ""sync_remove = falseupperdir_label = false[plugins."io.containerd.snapshotter.v1.zfs"]root_path = ""[plugins."io.containerd.tracing.processor.v1.otlp"]endpoint = ""insecure = falseprotocol = ""[proxy_plugins][stream_processors][stream_processors."io.containerd.ocicrypt.decoder.v1.tar"]accepts = ["application/vnd.oci.image.layer.v1.tar+encrypted"]args = ["--decryption-keys-path", "/etc/containerd/ocicrypt/keys"]env = ["OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf"]path = "ctd-decoder"returns = "application/vnd.oci.image.layer.v1.tar"[stream_processors."io.containerd.ocicrypt.decoder.v1.tar.gzip"]accepts = ["application/vnd.oci.image.layer.v1.tar+gzip+encrypted"]args = ["--decryption-keys-path", "/etc/containerd/ocicrypt/keys"]env = ["OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf"]path = "ctd-decoder"returns = "application/vnd.oci.image.layer.v1.tar+gzip"[timeouts]
      "io.containerd.timeout.bolt.open" = "0s"
      "io.containerd.timeout.shim.cleanup" = "5s"
      "io.containerd.timeout.shim.load" = "5s"
      "io.containerd.timeout.shim.shutdown" = "3s"
      "io.containerd.timeout.task.state" = "2s"[ttrpc]
      address = ""
      gid = 0
      uid = 0
      
    • 重启并启用容器服务:

      systemctl restart containerd
      systemctl enable containerd
      
    • 设置crictl

      cat > /etc/crictl.yaml <<EOF
      runtime-endpoint: unix:///var/run/containerd/containerd.sock
      image-endpoint: unix:///var/run/containerd/containerd.sock
      timeout: 10
      debug: false
      pull-image-on-create: false
      EOF
      
  4. 添加阿里云的 Kubernetes 源

    • 首先,导入阿里云的 GPG 密钥:

      curl -fsSL https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
      
    • 然后,添加阿里云的 Kubernetes 源:

      tee /etc/apt/sources.list.d/kubernetes.list <<EOF
      deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
      EOF
      
  5. 安装 Kubernetes 组件

    • 更新软件包索引并安装 kubelet、kubeadm 和 kubectl:

      apt-get update
      apt-get install -y kubelet kubeadm kubectl
      
    • 设置 kubelet 使用 systemd 作为 cgroup 驱动:

      # 可忽略
      # sed -i 's/cgroup-driver=systemd/cgroup-driver=cgroupfs/g' /var/lib/kubelet/kubeadm-flags.env
      # systemctl daemon-reload
      # systemctl restart kubelet
      
  6. 初始化 Kubernetes 集群

    • 使用 kubeadm 初始化集群,并指定阿里云的镜像仓库:

      # kubeadm init --image-repository registry.aliyuncs.com/google_containers
      I0513 14:16:59.740096   17563 version.go:256] remote version is much newer: v1.30.0; falling back to: stable-1.28
      [init] Using Kubernetes version: v1.28.9
      [preflight] Running pre-flight checks
      [preflight] Pulling images required for setting up a Kubernetes cluster
      [preflight] This might take a minute or two, depending on the speed of your internet connection
      [preflight] You can also perform this action in beforehand using 'kubeadm config images pull'
      W0513 14:17:01.440936   17563 checks.go:835] detected that the sandbox image "registry.aliyuncs.com/google_containers/pause:3.8" of the container runtime         is inconsistent with that used by kubeadm. It is recommended that using "registry.aliyuncs.com/google_containers/pause:3.9" as the CRI sandbox image.
      [certs] Using certificateDir folder "/etc/kubernetes/pki"
      [certs] Generating "ca" certificate and key
      [certs] Generating "apiserver" certificate and key
      [certs] apiserver serving cert is signed for DNS names [k8smaster.example.net kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.        cluster.local] and IPs [10.96.0.1 10.1.1.70]
      [certs] Generating "apiserver-kubelet-client" certificate and key
      [certs] Generating "front-proxy-ca" certificate and key
      [certs] Generating "front-proxy-client" certificate and key
      [certs] Generating "etcd/ca" certificate and key
      [certs] Generating "etcd/server" certificate and key
      [certs] etcd/server serving cert is signed for DNS names [k8smaster.example.net localhost] and IPs [10.1.1.70 127.0.0.1 ::1]
      [certs] Generating "etcd/peer" certificate and key
      [certs] etcd/peer serving cert is signed for DNS names [k8smaster.example.net localhost] and IPs [10.1.1.70 127.0.0.1 ::1]
      [certs] Generating "etcd/healthcheck-client" certificate and key
      [certs] Generating "apiserver-etcd-client" certificate and key
      [certs] Generating "sa" key and public key
      [kubeconfig] Using kubeconfig folder "/etc/kubernetes"
      [kubeconfig] Writing "admin.conf" kubeconfig file
      [kubeconfig] Writing "kubelet.conf" kubeconfig file
      [kubeconfig] Writing "controller-manager.conf" kubeconfig file
      [kubeconfig] Writing "scheduler.conf" kubeconfig file
      [etcd] Creating static Pod manifest for local etcd in "/etc/kubernetes/manifests"
      [control-plane] Using manifest folder "/etc/kubernetes/manifests"
      [control-plane] Creating static Pod manifest for "kube-apiserver"
      [control-plane] Creating static Pod manifest for "kube-controller-manager"
      [control-plane] Creating static Pod manifest for "kube-scheduler"
      [kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
      [kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
      [kubelet-start] Starting the kubelet
      [wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory "/etc/kubernetes/manifests". This can take up to         4m0s
      [apiclient] All control plane components are healthy after 4.002079 seconds
      [upload-config] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
      [kubelet] Creating a ConfigMap "kubelet-config" in namespace kube-system with the configuration for the kubelets in the cluster
      [upload-certs] Skipping phase. Please see --upload-certs
      [mark-control-plane] Marking the node k8smaster.example.net as control-plane by adding the labels: [node-role.kubernetes.io/control-plane node.kubernetes.        io/exclude-from-external-load-balancers]
      [mark-control-plane] Marking the node k8smaster.example.net as control-plane by adding the taints [node-role.kubernetes.io/control-plane:NoSchedule]
      [bootstrap-token] Using token: m9z4yq.dok89ro6yt23wykr
      [bootstrap-token] Configuring bootstrap tokens, cluster-info ConfigMap, RBAC Roles
      [bootstrap-token] Configured RBAC rules to allow Node Bootstrap tokens to get nodes
      [bootstrap-token] Configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials
      [bootstrap-token] Configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
      [bootstrap-token] Configured RBAC rules to allow certificate rotation for all node client certificates in the cluster
      [bootstrap-token] Creating the "cluster-info" ConfigMap in the "kube-public" namespace
      [kubelet-finalize] Updating "/etc/kubernetes/kubelet.conf" to point to a rotatable kubelet client certificate and key
      [addons] Applied essential addon: CoreDNS
      [addons] Applied essential addon: kube-proxyYour Kubernetes control-plane has initialized successfully!To start using your cluster, you need to run the following as a regular user:mkdir -p $HOME/.kubesudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/configsudo chown $(id -u):$(id -g) $HOME/.kube/configAlternatively, if you are the root user, you can run:export KUBECONFIG=/etc/kubernetes/admin.confYou should now deploy a pod network to the cluster.
      Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:https://kubernetes.io/docs/concepts/cluster-administration/addons/Then you can join any number of worker nodes by running the following on each as root:kubeadm join 10.1.1.70:6443 --token m9z4yq.dok89ro6yt23wykr \--discovery-token-ca-cert-hash sha256:17c3f29bd276592e668e9e6a7a187140a887254b4555cf7d293c3313d7c8a178 
      
  7. 配置 kubectl

    • 为当前用户设置 kubectl 访问:

      mkdir -p $HOME/.kube
      cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
      chown $(id -u):$(id -g) $HOME/.kube/config
      
  8. 安装网络插件

    • 安装一个 Pod 网络插件,例如 Calico 或 Flannel。例如,使用 Calico:

      kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
      # 网络插件初始化完毕之后,coredns容器就正常了
      kubectl logs -n kube-system -l k8s-app=kube-dns
      
  9. 验证集群

    • 启动一个nginx pod:

      # vim nginx_pod.yml
      apiVersion: v1
      kind: Pod
      metadata:name: test-nginx-podnamespace: testlabels:app: nginx
      spec:containers:- name: test-nginx-containerimage: nginx:latestports:- containerPort: 80tolerations:- key: "node-role.kubernetes.io/control-plane"operator: "Exists"effect: "NoSchedule"
      ---apiVersion: v1
      kind: Service
      # service和pod必须位于同一个namespace
      metadata:name: nginx-servicenamespace: test
      spec:type: NodePort# selector应该匹配pod的labelsselector:app: nginxports:- protocol: TCPport: 80nodePort: 30007targetPort: 80
      

      启动

      kubectl apply -f nginx_pod.yml
      

部署opentelemetry-collector测试

otel-collector和otel-agent需要程序集成API,发送到以DaemonSet运行在每个节点的otel-agent,otel-agent再将数据发送给otel-collector汇总,然后发往可以处理otlp trace数据的后端,如zipkin、jaeger等。

自定义测试yaml文件

apiVersion: v1
kind: ConfigMap
metadata:name: otel-collector-confnamespace: default
data:# 你的配置数据config.yaml: |receivers:otlp:protocols:grpc:http:processors:batch:exporters:logging:loglevel: debugservice:pipelines:traces:receivers: [otlp]processors: [batch]exporters: [logging]---
apiVersion: v1
kind: Service
metadata:name: otel-collectorlabels:app: opentelemetry
spec:type: NodePortports:- port: 4317targetPort: 4317nodePort: 30080name: otlp-grpc- port: 8888targetPort: 8888name: metricsselector:component: otel-collector---
apiVersion: apps/v1
kind: Deployment
metadata:name: otel-collectorlabels:app: opentelemetry
spec:replicas: 1selector:matchLabels:component: otel-collectortemplate:metadata:labels:component: otel-collectorspec:tolerations:- key: node-role.kubernetes.io/control-planeoperator: Existseffect: NoSchedulecontainers:- name: otel-collectorimage: otel/opentelemetry-collector:latestports:- containerPort: 4317- containerPort: 8888env:- name: MY_POD_IPvalueFrom:fieldRef:fieldPath: status.podIPvolumeMounts:- name: otel-collector-config-volmountPath: /confvolumes:- configMap:name: otel-collector-confname: otel-collector-config-vol

启动

mkdir /conf
kubectl apply -f otel-collector.yaml
kubectl get -f otel-collector.yaml

删除

kubectl delete -f otel-collector.yaml

使用官方提供示例

kubectl apply -f https://raw.githubusercontent.com/open-telemetry/opentelemetry-collector/main/examples/k8s/otel-config.yaml

根据需要修改文件

otel-config.yaml

---
apiVersion: v1
kind: ConfigMap
metadata:name: otel-agent-conflabels:app: opentelemetrycomponent: otel-agent-conf
data:otel-agent-config: |receivers:otlp:protocols:grpc:endpoint: ${env:MY_POD_IP}:4317http:endpoint: ${env:MY_POD_IP}:4318exporters:otlp:endpoint: "otel-collector.default:4317"tls:insecure: truesending_queue:num_consumers: 4queue_size: 100retry_on_failure:enabled: trueprocessors:batch:memory_limiter:# 80% of maximum memory up to 2Glimit_mib: 400# 25% of limit up to 2Gspike_limit_mib: 100check_interval: 5sextensions:zpages: {}service:extensions: [zpages]pipelines:traces:receivers: [otlp]processors: [memory_limiter, batch]exporters: [otlp]
---
apiVersion: apps/v1
kind: DaemonSet
metadata:name: otel-agentlabels:app: opentelemetrycomponent: otel-agent
spec:selector:matchLabels:app: opentelemetrycomponent: otel-agenttemplate:metadata:labels:app: opentelemetrycomponent: otel-agentspec:tolerations:- key: node-role.kubernetes.io/control-planeoperator: Existseffect: NoSchedulecontainers:- command:- "/otelcol"- "--config=/conf/otel-agent-config.yaml"image: otel/opentelemetry-collector:0.94.0name: otel-agentresources:limits:cpu: 500mmemory: 500Mirequests:cpu: 100mmemory: 100Miports:- containerPort: 55679 # ZPages endpoint.- containerPort: 4317 # Default OpenTelemetry receiver port.- containerPort: 8888  # Metrics.env:- name: MY_POD_IPvalueFrom:fieldRef:apiVersion: v1fieldPath: status.podIP- name: GOMEMLIMITvalue: 400MiBvolumeMounts:- name: otel-agent-config-volmountPath: /confvolumes:- configMap:name: otel-agent-confitems:- key: otel-agent-configpath: otel-agent-config.yamlname: otel-agent-config-vol
---
apiVersion: v1
kind: ConfigMap
metadata:name: otel-collector-conflabels:app: opentelemetrycomponent: otel-collector-conf
data:otel-collector-config: |receivers:otlp:protocols:grpc:endpoint: ${env:MY_POD_IP}:4317http:endpoint: ${env:MY_POD_IP}:4318processors:batch:memory_limiter:# 80% of maximum memory up to 2Glimit_mib: 1500# 25% of limit up to 2Gspike_limit_mib: 512check_interval: 5sextensions:zpages: {}exporters:otlp:endpoint: "http://someotlp.target.com:4317" # Replace with a real endpoint.tls:insecure: truezipkin:endpoint: "http://10.1.1.10:9411/api/v2/spans"format: "proto"service:extensions: [zpages]pipelines:traces/1:receivers: [otlp]processors: [memory_limiter, batch]exporters: [zipkin]
---
apiVersion: v1
kind: Service
metadata:name: otel-collectorlabels:app: opentelemetrycomponent: otel-collector
spec:ports:- name: otlp-grpc # Default endpoint for OpenTelemetry gRPC receiver.port: 4317protocol: TCPtargetPort: 4317- name: otlp-http # Default endpoint for OpenTelemetry HTTP receiver.port: 4318protocol: TCPtargetPort: 4318- name: metrics # Default endpoint for querying metrics.port: 8888selector:component: otel-collector
---
apiVersion: apps/v1
kind: Deployment
metadata:name: otel-collectorlabels:app: opentelemetrycomponent: otel-collector
spec:selector:matchLabels:app: opentelemetrycomponent: otel-collectorminReadySeconds: 5progressDeadlineSeconds: 120replicas: 1 #TODO - adjust this to your own requirementstemplate:metadata:labels:app: opentelemetrycomponent: otel-collectorspec:tolerations:- key: node-role.kubernetes.io/control-planeoperator: Existseffect: NoSchedulecontainers:- command:- "/otelcol"- "--config=/conf/otel-collector-config.yaml"image: otel/opentelemetry-collector:0.94.0name: otel-collectorresources:limits:cpu: 1memory: 2Girequests:cpu: 200mmemory: 400Miports:- containerPort: 55679 # Default endpoint for ZPages.- containerPort: 4317 # Default endpoint for OpenTelemetry receiver.- containerPort: 14250 # Default endpoint for Jaeger gRPC receiver.- containerPort: 14268 # Default endpoint for Jaeger HTTP receiver.- containerPort: 9411 # Default endpoint for Zipkin receiver.- containerPort: 8888  # Default endpoint for querying metrics.env:- name: MY_POD_IPvalueFrom:fieldRef:apiVersion: v1fieldPath: status.podIP- name: GOMEMLIMITvalue: 1600MiBvolumeMounts:- name: otel-collector-config-volmountPath: /conf
#        - name: otel-collector-secrets
#          mountPath: /secretsvolumes:- configMap:name: otel-collector-confitems:- key: otel-collector-configpath: otel-collector-config.yamlname: otel-collector-config-vol
#        - secret:
#            name: otel-collector-secrets
#            items:
#              - key: cert.pem
#                path: cert.pem
#              - key: key.pem
#                path: key.pem

部署deepflow监控单个k8s集群

官方文档
官方demo

安装helm

snap install helm --classic

设置pv

kubectl apply -f https://openebs.github.io/charts/openebs-operator.yaml
## config default storage class
kubectl patch storageclass openebs-hostpath  -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'

部署deepflow

helm repo add deepflow https://deepflowio.github.io/deepflow
helm repo update deepflow # use `helm repo update` when helm < 3.7.0
helm install deepflow -n deepflow deepflow/deepflow --create-namespace
# 显示如下
NAME: deepflow
LAST DEPLOYED: Tue May 14 14:13:50 2024
NAMESPACE: deepflow
STATUS: deployed
REVISION: 1
NOTES:
██████╗ ███████╗███████╗██████╗ ███████╗██╗      ██████╗ ██╗    ██╗
██╔══██╗██╔════╝██╔════╝██╔══██╗██╔════╝██║     ██╔═══██╗██║    ██║
██║  ██║█████╗  █████╗  ██████╔╝█████╗  ██║     ██║   ██║██║ █╗ ██║
██║  ██║██╔══╝  ██╔══╝  ██╔═══╝ ██╔══╝  ██║     ██║   ██║██║███╗██║
██████╔╝███████╗███████╗██║     ██║     ███████╗╚██████╔╝╚███╔███╔╝
╚═════╝ ╚══════╝╚══════╝╚═╝     ╚═╝     ╚══════╝ ╚═════╝  ╚══╝╚══╝ An automated observability platform for cloud-native developers.# deepflow-agent Port for receiving trace, metrics, and logdeepflow-agent service: deepflow-agent.deepflow
deepflow-agent Host listening port: 38086# Get the Grafana URL to visit by running these commands in the same shellNODE_PORT=$(kubectl get --namespace deepflow -o jsonpath="{.spec.ports[0].nodePort}" services deepflow-grafana)
NODE_IP=$(kubectl get nodes -o jsonpath="{.items[0].status.addresses[0].address}")
echo -e "Grafana URL: http://$NODE_IP:$NODE_PORT  \nGrafana auth: admin:deepflow"

节点安装deepflow-ctl

curl -o /usr/bin/deepflow-ctl https://deepflow-ce.oss-cn-beijing.aliyuncs.com/bin/ctl/stable/linux/$(arch | sed 's|x86_64|amd64|' | sed 's|aarch64|arm64|')/deepflow-ctl
chmod a+x /usr/bin/deepflow-ctl

访问grafana页面

NODE_PORT=$(kubectl get --namespace deepflow -o jsonpath="{.spec.ports[0].nodePort}" services deepflow-grafana)
NODE_IP=$(kubectl get nodes -o jsonpath="{.items[0].status.addresses[0].address}")
echo -e "Grafana URL: http://$NODE_IP:$NODE_PORT  \nGrafana auth: admin:deepflow"

Ubuntu-22-LTS部署k8s和deepflow

环境详情:
Static hostname: k8smaster.example.net
Icon name: computer-vm
Chassis: vm
Machine ID: 22349ac6f9ba406293d0541bcba7c05d
Boot ID: 605a74a509724a88940bbbb69cde77f2
Virtualization: vmware
Operating System: Ubuntu 22.04.4 LTS
Kernel: Linux 5.15.0-106-generic
Architecture: x86-64
Hardware Vendor: VMware, Inc.
Hardware Model: VMware Virtual Platform

当您在 Ubuntu 22.04 上安装 Kubernetes 集群时,您可以遵循以下步骤:

  1. 设置主机名并在 hosts 文件中添加条目

    • 登录到主节点并使用 hostnamectl 命令设置主机名:

      hostnamectl set-hostname "k8smaster.example.net"
      
    • 在工作节点上,运行以下命令设置主机名(分别对应第一个和第二个工作节点):

      hostnamectl set-hostname "k8sworker1.example.net"  # 第一个工作节点
      hostnamectl set-hostname "k8sworker2.example.net"  # 第二个工作节点
      
    • 在每个节点的 /etc/hosts 文件中添加以下条目:

      10.1.1.70 k8smaster.example.net k8smaster
      10.1.1.71 k8sworker1.example.net k8sworker1
      
  2. 禁用 swap 并添加内核设置

    • 在所有节点上执行以下命令以禁用交换功能:

      swapoff -a
      sed -i '/swap/ s/^\(.*\)$/#\1/g' /etc/fstab
      
    • 加载以下内核模块:

      tee /etc/modules-load.d/containerd.conf <<EOF
      overlay
      br_netfilter
      EOF
      modprobe overlay
      modprobe br_netfilter
      
    • 为 Kubernetes 设置以下内核参数:

      tee /etc/sysctl.d/kubernetes.conf <<EOF
      net.bridge.bridge-nf-call-ip6tables = 1
      net.bridge.bridge-nf-call-iptables = 1
      net.ipv4.ip_forward = 1
      EOF
      sysctl --system
      
  3. 安装 containerd 运行时

    • 首先安装 containerd 的依赖项:

      apt install -y curl gnupg2 software-properties-common apt-transport-https ca-certificates
      
    • 启用 Docker 存储库:

      curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
      add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
      
    • 安装 containerd:

      apt update
      apt install -y containerd.io
      
    • 配置 containerd 使用 systemd 作为 cgroup:

      containerd config default | tee /etc/containerd/config.toml > /dev/null 2>&1
      sed -i 's/SystemdCgroup\\=false/SystemdCgroup\\=true/g' /etc/containerd/config.toml
      

      部分配置手动修改

      disabled_plugins = []
      imports = []
      oom_score = 0
      plugin_dir = ""
      required_plugins = []
      root = "/var/lib/containerd"
      state = "/run/containerd"
      temp = ""
      version = 2[cgroup]
      path = ""[debug]
      address = ""
      format = ""
      gid = 0
      level = ""
      uid = 0[grpc]
      address = "/run/containerd/containerd.sock"
      gid = 0
      max_recv_message_size = 16777216
      max_send_message_size = 16777216
      tcp_address = ""
      tcp_tls_ca = ""
      tcp_tls_cert = ""
      tcp_tls_key = ""
      uid = 0[metrics]
      address = ""
      grpc_histogram = false[plugins][plugins."io.containerd.gc.v1.scheduler"]deletion_threshold = 0mutation_threshold = 100pause_threshold = 0.02schedule_delay = "0s"startup_delay = "100ms"[plugins."io.containerd.grpc.v1.cri"]device_ownership_from_security_context = falsedisable_apparmor = falsedisable_cgroup = falsedisable_hugetlb_controller = truedisable_proc_mount = falsedisable_tcp_service = truedrain_exec_sync_io_timeout = "0s"enable_selinux = falseenable_tls_streaming = falseenable_unprivileged_icmp = falseenable_unprivileged_ports = falseignore_deprecation_warnings = []ignore_image_defined_volumes = falsemax_concurrent_downloads = 3max_container_log_line_size = 16384netns_mounts_under_state_dir = falserestrict_oom_score_adj = false# 修改以下这行sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.8"selinux_category_range = 1024stats_collect_period = 10stream_idle_timeout = "4h0m0s"stream_server_address = "127.0.0.1"stream_server_port = "0"systemd_cgroup = falsetolerate_missing_hugetlb_controller = trueunset_seccomp_profile = ""[plugins."io.containerd.grpc.v1.cri".cni]bin_dir = "/opt/cni/bin"conf_dir = "/etc/cni/net.d"conf_template = ""ip_pref = ""max_conf_num = 1[plugins."io.containerd.grpc.v1.cri".containerd]default_runtime_name = "runc"disable_snapshot_annotations = truediscard_unpacked_layers = falseignore_rdt_not_enabled_errors = falseno_pivot = falsesnapshotter = "overlayfs"[plugins."io.containerd.grpc.v1.cri".containerd.default_runtime]base_runtime_spec = ""cni_conf_dir = ""cni_max_conf_num = 0container_annotations = []pod_annotations = []privileged_without_host_devices = falseruntime_engine = ""runtime_path = ""runtime_root = ""runtime_type = ""[plugins."io.containerd.grpc.v1.cri".containerd.default_runtime.options][plugins."io.containerd.grpc.v1.cri".containerd.runtimes][plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]base_runtime_spec = ""cni_conf_dir = ""cni_max_conf_num = 0container_annotations = []pod_annotations = []privileged_without_host_devices = falseruntime_engine = ""runtime_path = ""runtime_root = ""runtime_type = "io.containerd.runc.v2"[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]BinaryName = ""CriuImagePath = ""CriuPath = ""CriuWorkPath = ""IoGid = 0IoUid = 0NoNewKeyring = falseNoPivotRoot = falseRoot = ""ShimCgroup = ""SystemdCgroup = true[plugins."io.containerd.grpc.v1.cri".containerd.untrusted_workload_runtime]base_runtime_spec = ""cni_conf_dir = ""cni_max_conf_num = 0container_annotations = []pod_annotations = []privileged_without_host_devices = falseruntime_engine = ""runtime_path = ""runtime_root = ""runtime_type = ""[plugins."io.containerd.grpc.v1.cri".containerd.untrusted_workload_runtime.options][plugins."io.containerd.grpc.v1.cri".image_decryption]key_model = "node"[plugins."io.containerd.grpc.v1.cri".registry]config_path = ""[plugins."io.containerd.grpc.v1.cri".registry.auths][plugins."io.containerd.grpc.v1.cri".registry.configs][plugins."io.containerd.grpc.v1.cri".registry.headers][plugins."io.containerd.grpc.v1.cri".registry.mirrors]# 添加如下4行[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]endpoint = ["https://docker.mirrors.ustc.edu.cn"][plugins."io.containerd.grpc.v1.cri".registry.mirrors."k8s.gcr.io"]endpoint = ["https://registry.aliyuncs.com/google_containers"][plugins."io.containerd.grpc.v1.cri".x509_key_pair_streaming]tls_cert_file = ""tls_key_file = ""[plugins."io.containerd.internal.v1.opt"]path = "/opt/containerd"[plugins."io.containerd.internal.v1.restart"]interval = "10s"[plugins."io.containerd.internal.v1.tracing"]sampling_ratio = 1.0service_name = "containerd"[plugins."io.containerd.metadata.v1.bolt"]content_sharing_policy = "shared"[plugins."io.containerd.monitor.v1.cgroups"]no_prometheus = false[plugins."io.containerd.runtime.v1.linux"]no_shim = falseruntime = "runc"runtime_root = ""shim = "containerd-shim"shim_debug = false[plugins."io.containerd.runtime.v2.task"]platforms = ["linux/amd64"]sched_core = false[plugins."io.containerd.service.v1.diff-service"]default = ["walking"][plugins."io.containerd.service.v1.tasks-service"]rdt_config_file = ""[plugins."io.containerd.snapshotter.v1.aufs"]root_path = ""[plugins."io.containerd.snapshotter.v1.btrfs"]root_path = ""[plugins."io.containerd.snapshotter.v1.devmapper"]async_remove = falsebase_image_size = ""discard_blocks = falsefs_options = ""fs_type = ""pool_name = ""root_path = ""[plugins."io.containerd.snapshotter.v1.native"]root_path = ""[plugins."io.containerd.snapshotter.v1.overlayfs"]mount_options = []root_path = ""sync_remove = falseupperdir_label = false[plugins."io.containerd.snapshotter.v1.zfs"]root_path = ""[plugins."io.containerd.tracing.processor.v1.otlp"]endpoint = ""insecure = falseprotocol = ""[proxy_plugins][stream_processors][stream_processors."io.containerd.ocicrypt.decoder.v1.tar"]accepts = ["application/vnd.oci.image.layer.v1.tar+encrypted"]args = ["--decryption-keys-path", "/etc/containerd/ocicrypt/keys"]env = ["OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf"]path = "ctd-decoder"returns = "application/vnd.oci.image.layer.v1.tar"[stream_processors."io.containerd.ocicrypt.decoder.v1.tar.gzip"]accepts = ["application/vnd.oci.image.layer.v1.tar+gzip+encrypted"]args = ["--decryption-keys-path", "/etc/containerd/ocicrypt/keys"]env = ["OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf"]path = "ctd-decoder"returns = "application/vnd.oci.image.layer.v1.tar+gzip"[timeouts]
      "io.containerd.timeout.bolt.open" = "0s"
      "io.containerd.timeout.shim.cleanup" = "5s"
      "io.containerd.timeout.shim.load" = "5s"
      "io.containerd.timeout.shim.shutdown" = "3s"
      "io.containerd.timeout.task.state" = "2s"[ttrpc]
      address = ""
      gid = 0
      uid = 0
      
    • 重启并启用容器服务:

      systemctl restart containerd
      systemctl enable containerd
      
    • 设置crictl

      cat > /etc/crictl.yaml <<EOF
      runtime-endpoint: unix:///var/run/containerd/containerd.sock
      image-endpoint: unix:///var/run/containerd/containerd.sock
      timeout: 10
      debug: false
      pull-image-on-create: false
      EOF
      
  4. 添加阿里云的 Kubernetes 源

    • 首先,导入阿里云的 GPG 密钥:

      curl -fsSL https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
      
    • 然后,添加阿里云的 Kubernetes 源:

      tee /etc/apt/sources.list.d/kubernetes.list <<EOF
      deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
      EOF
      
  5. 安装 Kubernetes 组件

    • 更新软件包索引并安装 kubelet、kubeadm 和 kubectl:

      apt-get update
      apt-get install -y kubelet kubeadm kubectl
      
    • 设置 kubelet 使用 systemd 作为 cgroup 驱动:

      # 可忽略
      # sed -i 's/cgroup-driver=systemd/cgroup-driver=cgroupfs/g' /var/lib/kubelet/kubeadm-flags.env
      # systemctl daemon-reload
      # systemctl restart kubelet
      
  6. 初始化 Kubernetes 集群

    • 使用 kubeadm 初始化集群,并指定阿里云的镜像仓库:

      # kubeadm init --image-repository registry.aliyuncs.com/google_containers
      I0513 14:16:59.740096   17563 version.go:256] remote version is much newer: v1.30.0; falling back to: stable-1.28
      [init] Using Kubernetes version: v1.28.9
      [preflight] Running pre-flight checks
      [preflight] Pulling images required for setting up a Kubernetes cluster
      [preflight] This might take a minute or two, depending on the speed of your internet connection
      [preflight] You can also perform this action in beforehand using 'kubeadm config images pull'
      W0513 14:17:01.440936   17563 checks.go:835] detected that the sandbox image "registry.aliyuncs.com/google_containers/pause:3.8" of the container runtime         is inconsistent with that used by kubeadm. It is recommended that using "registry.aliyuncs.com/google_containers/pause:3.9" as the CRI sandbox image.
      [certs] Using certificateDir folder "/etc/kubernetes/pki"
      [certs] Generating "ca" certificate and key
      [certs] Generating "apiserver" certificate and key
      [certs] apiserver serving cert is signed for DNS names [k8smaster.example.net kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.        cluster.local] and IPs [10.96.0.1 10.1.1.70]
      [certs] Generating "apiserver-kubelet-client" certificate and key
      [certs] Generating "front-proxy-ca" certificate and key
      [certs] Generating "front-proxy-client" certificate and key
      [certs] Generating "etcd/ca" certificate and key
      [certs] Generating "etcd/server" certificate and key
      [certs] etcd/server serving cert is signed for DNS names [k8smaster.example.net localhost] and IPs [10.1.1.70 127.0.0.1 ::1]
      [certs] Generating "etcd/peer" certificate and key
      [certs] etcd/peer serving cert is signed for DNS names [k8smaster.example.net localhost] and IPs [10.1.1.70 127.0.0.1 ::1]
      [certs] Generating "etcd/healthcheck-client" certificate and key
      [certs] Generating "apiserver-etcd-client" certificate and key
      [certs] Generating "sa" key and public key
      [kubeconfig] Using kubeconfig folder "/etc/kubernetes"
      [kubeconfig] Writing "admin.conf" kubeconfig file
      [kubeconfig] Writing "kubelet.conf" kubeconfig file
      [kubeconfig] Writing "controller-manager.conf" kubeconfig file
      [kubeconfig] Writing "scheduler.conf" kubeconfig file
      [etcd] Creating static Pod manifest for local etcd in "/etc/kubernetes/manifests"
      [control-plane] Using manifest folder "/etc/kubernetes/manifests"
      [control-plane] Creating static Pod manifest for "kube-apiserver"
      [control-plane] Creating static Pod manifest for "kube-controller-manager"
      [control-plane] Creating static Pod manifest for "kube-scheduler"
      [kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
      [kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
      [kubelet-start] Starting the kubelet
      [wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory "/etc/kubernetes/manifests". This can take up to         4m0s
      [apiclient] All control plane components are healthy after 4.002079 seconds
      [upload-config] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
      [kubelet] Creating a ConfigMap "kubelet-config" in namespace kube-system with the configuration for the kubelets in the cluster
      [upload-certs] Skipping phase. Please see --upload-certs
      [mark-control-plane] Marking the node k8smaster.example.net as control-plane by adding the labels: [node-role.kubernetes.io/control-plane node.kubernetes.        io/exclude-from-external-load-balancers]
      [mark-control-plane] Marking the node k8smaster.example.net as control-plane by adding the taints [node-role.kubernetes.io/control-plane:NoSchedule]
      [bootstrap-token] Using token: m9z4yq.dok89ro6yt23wykr
      [bootstrap-token] Configuring bootstrap tokens, cluster-info ConfigMap, RBAC Roles
      [bootstrap-token] Configured RBAC rules to allow Node Bootstrap tokens to get nodes
      [bootstrap-token] Configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials
      [bootstrap-token] Configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
      [bootstrap-token] Configured RBAC rules to allow certificate rotation for all node client certificates in the cluster
      [bootstrap-token] Creating the "cluster-info" ConfigMap in the "kube-public" namespace
      [kubelet-finalize] Updating "/etc/kubernetes/kubelet.conf" to point to a rotatable kubelet client certificate and key
      [addons] Applied essential addon: CoreDNS
      [addons] Applied essential addon: kube-proxyYour Kubernetes control-plane has initialized successfully!To start using your cluster, you need to run the following as a regular user:mkdir -p $HOME/.kubesudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/configsudo chown $(id -u):$(id -g) $HOME/.kube/configAlternatively, if you are the root user, you can run:export KUBECONFIG=/etc/kubernetes/admin.confYou should now deploy a pod network to the cluster.
      Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:https://kubernetes.io/docs/concepts/cluster-administration/addons/Then you can join any number of worker nodes by running the following on each as root:kubeadm join 10.1.1.70:6443 --token m9z4yq.dok89ro6yt23wykr \--discovery-token-ca-cert-hash sha256:17c3f29bd276592e668e9e6a7a187140a887254b4555cf7d293c3313d7c8a178 
      
  7. 配置 kubectl

    • 为当前用户设置 kubectl 访问:

      mkdir -p $HOME/.kube
      cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
      chown $(id -u):$(id -g) $HOME/.kube/config
      
  8. 安装网络插件

    • 安装一个 Pod 网络插件,例如 Calico 或 Flannel。例如,使用 Calico:

      kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
      # 网络插件初始化完毕之后,coredns容器就正常了
      kubectl logs -n kube-system -l k8s-app=kube-dns
      
  9. 验证集群

    • 启动一个nginx pod:

      # vim nginx_pod.yml
      apiVersion: v1
      kind: Pod
      metadata:name: test-nginx-podnamespace: testlabels:app: nginx
      spec:containers:- name: test-nginx-containerimage: nginx:latestports:- containerPort: 80tolerations:- key: "node-role.kubernetes.io/control-plane"operator: "Exists"effect: "NoSchedule"
      ---apiVersion: v1
      kind: Service
      # service和pod必须位于同一个namespace
      metadata:name: nginx-servicenamespace: test
      spec:type: NodePort# selector应该匹配pod的labelsselector:app: nginxports:- protocol: TCPport: 80nodePort: 30007targetPort: 80
      

      启动

      kubectl apply -f nginx_pod.yml
      

部署opentelemetry-collector测试

otel-collector和otel-agent需要程序集成API,发送到以DaemonSet运行在每个节点的otel-agent,otel-agent再将数据发送给otel-collector汇总,然后发往可以处理otlp trace数据的后端,如zipkin、jaeger等。

自定义测试yaml文件

apiVersion: v1
kind: ConfigMap
metadata:name: otel-collector-confnamespace: default
data:# 你的配置数据config.yaml: |receivers:otlp:protocols:grpc:http:processors:batch:exporters:logging:loglevel: debugservice:pipelines:traces:receivers: [otlp]processors: [batch]exporters: [logging]---
apiVersion: v1
kind: Service
metadata:name: otel-collectorlabels:app: opentelemetry
spec:type: NodePortports:- port: 4317targetPort: 4317nodePort: 30080name: otlp-grpc- port: 8888targetPort: 8888name: metricsselector:component: otel-collector---
apiVersion: apps/v1
kind: Deployment
metadata:name: otel-collectorlabels:app: opentelemetry
spec:replicas: 1selector:matchLabels:component: otel-collectortemplate:metadata:labels:component: otel-collectorspec:tolerations:- key: node-role.kubernetes.io/control-planeoperator: Existseffect: NoSchedulecontainers:- name: otel-collectorimage: otel/opentelemetry-collector:latestports:- containerPort: 4317- containerPort: 8888env:- name: MY_POD_IPvalueFrom:fieldRef:fieldPath: status.podIPvolumeMounts:- name: otel-collector-config-volmountPath: /confvolumes:- configMap:name: otel-collector-confname: otel-collector-config-vol

启动

mkdir /conf
kubectl apply -f otel-collector.yaml
kubectl get -f otel-collector.yaml

删除

kubectl delete -f otel-collector.yaml

使用官方提供示例

kubectl apply -f https://raw.githubusercontent.com/open-telemetry/opentelemetry-collector/main/examples/k8s/otel-config.yaml

根据需要修改文件

otel-config.yaml

---
apiVersion: v1
kind: ConfigMap
metadata:name: otel-agent-conflabels:app: opentelemetrycomponent: otel-agent-conf
data:otel-agent-config: |receivers:otlp:protocols:grpc:endpoint: ${env:MY_POD_IP}:4317http:endpoint: ${env:MY_POD_IP}:4318exporters:otlp:endpoint: "otel-collector.default:4317"tls:insecure: truesending_queue:num_consumers: 4queue_size: 100retry_on_failure:enabled: trueprocessors:batch:memory_limiter:# 80% of maximum memory up to 2Glimit_mib: 400# 25% of limit up to 2Gspike_limit_mib: 100check_interval: 5sextensions:zpages: {}service:extensions: [zpages]pipelines:traces:receivers: [otlp]processors: [memory_limiter, batch]exporters: [otlp]
---
apiVersion: apps/v1
kind: DaemonSet
metadata:name: otel-agentlabels:app: opentelemetrycomponent: otel-agent
spec:selector:matchLabels:app: opentelemetrycomponent: otel-agenttemplate:metadata:labels:app: opentelemetrycomponent: otel-agentspec:tolerations:- key: node-role.kubernetes.io/control-planeoperator: Existseffect: NoSchedulecontainers:- command:- "/otelcol"- "--config=/conf/otel-agent-config.yaml"image: otel/opentelemetry-collector:0.94.0name: otel-agentresources:limits:cpu: 500mmemory: 500Mirequests:cpu: 100mmemory: 100Miports:- containerPort: 55679 # ZPages endpoint.- containerPort: 4317 # Default OpenTelemetry receiver port.- containerPort: 8888  # Metrics.env:- name: MY_POD_IPvalueFrom:fieldRef:apiVersion: v1fieldPath: status.podIP- name: GOMEMLIMITvalue: 400MiBvolumeMounts:- name: otel-agent-config-volmountPath: /confvolumes:- configMap:name: otel-agent-confitems:- key: otel-agent-configpath: otel-agent-config.yamlname: otel-agent-config-vol
---
apiVersion: v1
kind: ConfigMap
metadata:name: otel-collector-conflabels:app: opentelemetrycomponent: otel-collector-conf
data:otel-collector-config: |receivers:otlp:protocols:grpc:endpoint: ${env:MY_POD_IP}:4317http:endpoint: ${env:MY_POD_IP}:4318processors:batch:memory_limiter:# 80% of maximum memory up to 2Glimit_mib: 1500# 25% of limit up to 2Gspike_limit_mib: 512check_interval: 5sextensions:zpages: {}exporters:otlp:endpoint: "http://someotlp.target.com:4317" # Replace with a real endpoint.tls:insecure: truezipkin:endpoint: "http://10.1.1.10:9411/api/v2/spans"format: "proto"service:extensions: [zpages]pipelines:traces/1:receivers: [otlp]processors: [memory_limiter, batch]exporters: [zipkin]
---
apiVersion: v1
kind: Service
metadata:name: otel-collectorlabels:app: opentelemetrycomponent: otel-collector
spec:ports:- name: otlp-grpc # Default endpoint for OpenTelemetry gRPC receiver.port: 4317protocol: TCPtargetPort: 4317- name: otlp-http # Default endpoint for OpenTelemetry HTTP receiver.port: 4318protocol: TCPtargetPort: 4318- name: metrics # Default endpoint for querying metrics.port: 8888selector:component: otel-collector
---
apiVersion: apps/v1
kind: Deployment
metadata:name: otel-collectorlabels:app: opentelemetrycomponent: otel-collector
spec:selector:matchLabels:app: opentelemetrycomponent: otel-collectorminReadySeconds: 5progressDeadlineSeconds: 120replicas: 1 #TODO - adjust this to your own requirementstemplate:metadata:labels:app: opentelemetrycomponent: otel-collectorspec:tolerations:- key: node-role.kubernetes.io/control-planeoperator: Existseffect: NoSchedulecontainers:- command:- "/otelcol"- "--config=/conf/otel-collector-config.yaml"image: otel/opentelemetry-collector:0.94.0name: otel-collectorresources:limits:cpu: 1memory: 2Girequests:cpu: 200mmemory: 400Miports:- containerPort: 55679 # Default endpoint for ZPages.- containerPort: 4317 # Default endpoint for OpenTelemetry receiver.- containerPort: 14250 # Default endpoint for Jaeger gRPC receiver.- containerPort: 14268 # Default endpoint for Jaeger HTTP receiver.- containerPort: 9411 # Default endpoint for Zipkin receiver.- containerPort: 8888  # Default endpoint for querying metrics.env:- name: MY_POD_IPvalueFrom:fieldRef:apiVersion: v1fieldPath: status.podIP- name: GOMEMLIMITvalue: 1600MiBvolumeMounts:- name: otel-collector-config-volmountPath: /conf
#        - name: otel-collector-secrets
#          mountPath: /secretsvolumes:- configMap:name: otel-collector-confitems:- key: otel-collector-configpath: otel-collector-config.yamlname: otel-collector-config-vol
#        - secret:
#            name: otel-collector-secrets
#            items:
#              - key: cert.pem
#                path: cert.pem
#              - key: key.pem
#                path: key.pem

部署deepflow监控单个k8s集群

官方文档
官方demo

安装helm

snap install helm --classic

设置pv

kubectl apply -f https://openebs.github.io/charts/openebs-operator.yaml
## config default storage class
kubectl patch storageclass openebs-hostpath  -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'

部署deepflow

helm repo add deepflow https://deepflowio.github.io/deepflow
helm repo update deepflow # use `helm repo update` when helm < 3.7.0
helm install deepflow -n deepflow deepflow/deepflow --create-namespace
# 显示如下
NAME: deepflow
LAST DEPLOYED: Tue May 14 14:13:50 2024
NAMESPACE: deepflow
STATUS: deployed
REVISION: 1
NOTES:
██████╗ ███████╗███████╗██████╗ ███████╗██╗      ██████╗ ██╗    ██╗
██╔══██╗██╔════╝██╔════╝██╔══██╗██╔════╝██║     ██╔═══██╗██║    ██║
██║  ██║█████╗  █████╗  ██████╔╝█████╗  ██║     ██║   ██║██║ █╗ ██║
██║  ██║██╔══╝  ██╔══╝  ██╔═══╝ ██╔══╝  ██║     ██║   ██║██║███╗██║
██████╔╝███████╗███████╗██║     ██║     ███████╗╚██████╔╝╚███╔███╔╝
╚═════╝ ╚══════╝╚══════╝╚═╝     ╚═╝     ╚══════╝ ╚═════╝  ╚══╝╚══╝ An automated observability platform for cloud-native developers.# deepflow-agent Port for receiving trace, metrics, and logdeepflow-agent service: deepflow-agent.deepflow
deepflow-agent Host listening port: 38086# Get the Grafana URL to visit by running these commands in the same shellNODE_PORT=$(kubectl get --namespace deepflow -o jsonpath="{.spec.ports[0].nodePort}" services deepflow-grafana)
NODE_IP=$(kubectl get nodes -o jsonpath="{.items[0].status.addresses[0].address}")
echo -e "Grafana URL: http://$NODE_IP:$NODE_PORT  \nGrafana auth: admin:deepflow"

节点安装deepflow-ctl

curl -o /usr/bin/deepflow-ctl https://deepflow-ce.oss-cn-beijing.aliyuncs.com/bin/ctl/stable/linux/$(arch | sed 's|x86_64|amd64|' | sed 's|aarch64|arm64|')/deepflow-ctl
chmod a+x /usr/bin/deepflow-ctl

访问grafana页面

NODE_PORT=$(kubectl get --namespace deepflow -o jsonpath="{.spec.ports[0].nodePort}" services deepflow-grafana)
NODE_IP=$(kubectl get nodes -o jsonpath="{.items[0].status.addresses[0].address}")
echo -e "Grafana URL: http://$NODE_IP:$NODE_PORT  \nGrafana auth: admin:deepflow"

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

FAQ

如何将pod的端口暴露出来

在 Kubernetes 中,如果你想要将 Pod 的端口暴露给集群外部的用户或服务访问,你可以通过创建 Service 来实现。Service 提供了几种不同的类型来支持不同的用例和网络需求。以下是一些常见的方法:

  1. NodePort:这种类型的 Service 会在集群的所有节点上开放一个指定的端口(通常在 30000-32767 范围内),任何发送到这个端口的流量都会被转发到对应的 Pod。这是最简单的方式,但它会占用节点上的端口。

    示例 YAML 配置:

    apiVersion: v1
    kind: Service
    metadata:name: my-service
    spec:type: NodePortselector:app: MyAppports:- protocol: TCPport: 80targetPort: 9376nodePort: 30007
    
  2. LoadBalancer:这种类型的 Service 通常由云提供商支持,它会为 Service 分配一个外部 IP 地址,所有发送到这个 IP 地址的流量都会被转发到 Pod。这种方式适用于需要直接从互联网访问服务的场景。

    示例 YAML 配置:

    apiVersion: v1
    kind: Service
    metadata:name: my-service
    spec:selector:app: MyAppports:- protocol: TCPport: 80targetPort: 9376type: LoadBalancer
    
  3. Ingress:Ingress 是一个 API 对象,它定义了外部访问到集群服务的规则。它可以提供负载均衡、SSL 终端和基于名称的虚拟托管。这是一个更高级的暴露方式,可以让你使用一个单一的入口点来管理多个服务的访问。

    示例 YAML 配置:

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:name: example-ingress
    spec:rules:- host: www.example.comhttp:paths:- path: /pathType: Prefixbackend:service:name: my-serviceport:number: 80
    
  4. Port Forwarding:如果你只是临时需要从本地机器访问 Pod,可以使用 kubectl port-forward 命令将本地端口转发到 Pod 中的端口。

    示例命令:

    kubectl port-forward pods/my-pod 8080:80
    

这些方法可以根据你的具体需求和环境来选择使用。

deepflow是一个可观测平台吗

是的,DeepFlow 是一个可观测性平台。它是由云杉网络开发的,旨在为复杂的云基础设施及云原生应用提供深度可观测性。DeepFlow 基于 eBPF 技术实现了应用性能指标、分布式追踪、持续性能剖析等观测信号的零侵扰采集,并结合智能标签技术实现了所有观测信号的全栈关联和高效存取¹。

DeepFlow 提供了以下核心特性:

  • 全景图:利用 eBPF 技术零侵扰绘制生产环境的服务全景图。
  • 分布式追踪:基于 eBPF 和 Wasm 技术零侵扰实现分布式追踪。
  • 持续性能剖析:利用 eBPF 技术以低开销零侵扰采集生产环境进程的性能剖析数据。
  • 存储性能优化:通过 SmartEncoding 机制大幅降低存储成本。
  • 无缝集成:可以作为 Prometheus、OpenTelemetry、SkyWalking、Pyroscope 的存储后端,也提供 SQL、PromQL、OTLP 等数据接口¹。

DeepFlow 旨在解决传统 APM 方案中的侵扰性和观测盲点问题,提供一种更高效、自动化的可观测性解决方案。

deepflow会自动监控k8s中的pod应用吗

是的,DeepFlow 可以自动监控 Kubernetes 中的 Pod 应用。DeepFlow 是一个可观测性平台,它基于 eBPF 技术实现了应用性能指标、分布式追踪、持续性能剖析等观测信号的零侵扰采集,并结合智能标签技术实现了所有观测信号的全栈关联和高效存取。

以下是 DeepFlow 在 Kubernetes 中自动监控 Pod 应用的一些特性:

  1. 零侵扰采集:
    DeepFlow 使用 eBPF 技术,无需修改应用程序代码,即可自动收集应用性能指标、分布式追踪数据和持续性能剖析信息。

  2. 全栈关联:
    DeepFlow 通过智能标签技术,将所有观测信号(指标、日志、追踪)关联到全栈中的不同组件,帮助您更好地理解应用程序的整体性能。

  3. 自动标记 K8s 资源:
    DeepFlow 自动标记 Kubernetes 资源(如 Pod、Service、Deployment 等),使您可以轻松地按照资源维度进行监控。

  4. 持续性能剖析:
    DeepFlow 可以低开销地采集生产环境进程的性能剖析数据,帮助您深入分析应用程序的性能瓶颈。

总之,DeepFlow 是一个强大的可观测性工具,可以自动监控 Kubernetes 中的应用程序,帮助您更好地理解和优化应用性能。

FAQ

如何将pod的端口暴露出来

在 Kubernetes 中,如果你想要将 Pod 的端口暴露给集群外部的用户或服务访问,你可以通过创建 Service 来实现。Service 提供了几种不同的类型来支持不同的用例和网络需求。以下是一些常见的方法:

  1. NodePort:这种类型的 Service 会在集群的所有节点上开放一个指定的端口(通常在 30000-32767 范围内),任何发送到这个端口的流量都会被转发到对应的 Pod。这是最简单的方式,但它会占用节点上的端口。

    示例 YAML 配置:

    apiVersion: v1
    kind: Service
    metadata:name: my-service
    spec:type: NodePortselector:app: MyAppports:- protocol: TCPport: 80targetPort: 9376nodePort: 30007
    
  2. LoadBalancer:这种类型的 Service 通常由云提供商支持,它会为 Service 分配一个外部 IP 地址,所有发送到这个 IP 地址的流量都会被转发到 Pod。这种方式适用于需要直接从互联网访问服务的场景。

    示例 YAML 配置:

    apiVersion: v1
    kind: Service
    metadata:name: my-service
    spec:selector:app: MyAppports:- protocol: TCPport: 80targetPort: 9376type: LoadBalancer
    
  3. Ingress:Ingress 是一个 API 对象,它定义了外部访问到集群服务的规则。它可以提供负载均衡、SSL 终端和基于名称的虚拟托管。这是一个更高级的暴露方式,可以让你使用一个单一的入口点来管理多个服务的访问。

    示例 YAML 配置:

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:name: example-ingress
    spec:rules:- host: www.example.comhttp:paths:- path: /pathType: Prefixbackend:service:name: my-serviceport:number: 80
    
  4. Port Forwarding:如果你只是临时需要从本地机器访问 Pod,可以使用 kubectl port-forward 命令将本地端口转发到 Pod 中的端口。

    示例命令:

    kubectl port-forward pods/my-pod 8080:80
    

这些方法可以根据你的具体需求和环境来选择使用。

deepflow是一个可观测平台吗

是的,DeepFlow 是一个可观测性平台。它是由云杉网络开发的,旨在为复杂的云基础设施及云原生应用提供深度可观测性。DeepFlow 基于 eBPF 技术实现了应用性能指标、分布式追踪、持续性能剖析等观测信号的零侵扰采集,并结合智能标签技术实现了所有观测信号的全栈关联和高效存取¹。

DeepFlow 提供了以下核心特性:

  • 全景图:利用 eBPF 技术零侵扰绘制生产环境的服务全景图。
  • 分布式追踪:基于 eBPF 和 Wasm 技术零侵扰实现分布式追踪。
  • 持续性能剖析:利用 eBPF 技术以低开销零侵扰采集生产环境进程的性能剖析数据。
  • 存储性能优化:通过 SmartEncoding 机制大幅降低存储成本。
  • 无缝集成:可以作为 Prometheus、OpenTelemetry、SkyWalking、Pyroscope 的存储后端,也提供 SQL、PromQL、OTLP 等数据接口¹。

DeepFlow 旨在解决传统 APM 方案中的侵扰性和观测盲点问题,提供一种更高效、自动化的可观测性解决方案。

deepflow会自动监控k8s中的pod应用吗

是的,DeepFlow 可以自动监控 Kubernetes 中的 Pod 应用。DeepFlow 是一个可观测性平台,它基于 eBPF 技术实现了应用性能指标、分布式追踪、持续性能剖析等观测信号的零侵扰采集,并结合智能标签技术实现了所有观测信号的全栈关联和高效存取。

以下是 DeepFlow 在 Kubernetes 中自动监控 Pod 应用的一些特性:

  1. 零侵扰采集:
    DeepFlow 使用 eBPF 技术,无需修改应用程序代码,即可自动收集应用性能指标、分布式追踪数据和持续性能剖析信息。

  2. 全栈关联:
    DeepFlow 通过智能标签技术,将所有观测信号(指标、日志、追踪)关联到全栈中的不同组件,帮助您更好地理解应用程序的整体性能。

  3. 自动标记 K8s 资源:
    DeepFlow 自动标记 Kubernetes 资源(如 Pod、Service、Deployment 等),使您可以轻松地按照资源维度进行监控。

  4. 持续性能剖析:
    DeepFlow 可以低开销地采集生产环境进程的性能剖析数据,帮助您深入分析应用程序的性能瓶颈。

总之,DeepFlow 是一个强大的可观测性工具,可以自动监控 Kubernetes 中的应用程序,帮助您更好地理解和优化应用性能。

FAQ

如何将pod的端口暴露出来

在 Kubernetes 中,如果你想要将 Pod 的端口暴露给集群外部的用户或服务访问,你可以通过创建 Service 来实现。Service 提供了几种不同的类型来支持不同的用例和网络需求。以下是一些常见的方法:

  1. NodePort:这种类型的 Service 会在集群的所有节点上开放一个指定的端口(通常在 30000-32767 范围内),任何发送到这个端口的流量都会被转发到对应的 Pod。这是最简单的方式,但它会占用节点上的端口。

    示例 YAML 配置:

    apiVersion: v1
    kind: Service
    metadata:name: my-service
    spec:type: NodePortselector:app: MyAppports:- protocol: TCPport: 80targetPort: 9376nodePort: 30007
    
  2. LoadBalancer:这种类型的 Service 通常由云提供商支持,它会为 Service 分配一个外部 IP 地址,所有发送到这个 IP 地址的流量都会被转发到 Pod。这种方式适用于需要直接从互联网访问服务的场景。

    示例 YAML 配置:

    apiVersion: v1
    kind: Service
    metadata:name: my-service
    spec:selector:app: MyAppports:- protocol: TCPport: 80targetPort: 9376type: LoadBalancer
    
  3. Ingress:Ingress 是一个 API 对象,它定义了外部访问到集群服务的规则。它可以提供负载均衡、SSL 终端和基于名称的虚拟托管。这是一个更高级的暴露方式,可以让你使用一个单一的入口点来管理多个服务的访问。

    示例 YAML 配置:

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:name: example-ingress
    spec:rules:- host: www.example.comhttp:paths:- path: /pathType: Prefixbackend:service:name: my-serviceport:number: 80
    
  4. Port Forwarding:如果你只是临时需要从本地机器访问 Pod,可以使用 kubectl port-forward 命令将本地端口转发到 Pod 中的端口。

    示例命令:

    kubectl port-forward pods/my-pod 8080:80
    

这些方法可以根据你的具体需求和环境来选择使用。

deepflow是一个可观测平台吗

是的,DeepFlow 是一个可观测性平台。它是由云杉网络开发的,旨在为复杂的云基础设施及云原生应用提供深度可观测性。DeepFlow 基于 eBPF 技术实现了应用性能指标、分布式追踪、持续性能剖析等观测信号的零侵扰采集,并结合智能标签技术实现了所有观测信号的全栈关联和高效存取¹。

DeepFlow 提供了以下核心特性:

  • 全景图:利用 eBPF 技术零侵扰绘制生产环境的服务全景图。
  • 分布式追踪:基于 eBPF 和 Wasm 技术零侵扰实现分布式追踪。
  • 持续性能剖析:利用 eBPF 技术以低开销零侵扰采集生产环境进程的性能剖析数据。
  • 存储性能优化:通过 SmartEncoding 机制大幅降低存储成本。
  • 无缝集成:可以作为 Prometheus、OpenTelemetry、SkyWalking、Pyroscope 的存储后端,也提供 SQL、PromQL、OTLP 等数据接口¹。

DeepFlow 旨在解决传统 APM 方案中的侵扰性和观测盲点问题,提供一种更高效、自动化的可观测性解决方案。

deepflow会自动监控k8s中的pod应用吗

是的,DeepFlow 可以自动监控 Kubernetes 中的 Pod 应用。DeepFlow 是一个可观测性平台,它基于 eBPF 技术实现了应用性能指标、分布式追踪、持续性能剖析等观测信号的零侵扰采集,并结合智能标签技术实现了所有观测信号的全栈关联和高效存取。

以下是 DeepFlow 在 Kubernetes 中自动监控 Pod 应用的一些特性:

  1. 零侵扰采集:
    DeepFlow 使用 eBPF 技术,无需修改应用程序代码,即可自动收集应用性能指标、分布式追踪数据和持续性能剖析信息。

  2. 全栈关联:
    DeepFlow 通过智能标签技术,将所有观测信号(指标、日志、追踪)关联到全栈中的不同组件,帮助您更好地理解应用程序的整体性能。

  3. 自动标记 K8s 资源:
    DeepFlow 自动标记 Kubernetes 资源(如 Pod、Service、Deployment 等),使您可以轻松地按照资源维度进行监控。

  4. 持续性能剖析:
    DeepFlow 可以低开销地采集生产环境进程的性能剖析数据,帮助您深入分析应用程序的性能瓶颈。

总之,DeepFlow 是一个强大的可观测性工具,可以自动监控 Kubernetes 中的应用程序,帮助您更好地理解和优化应用性能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/345536.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

STM32F103C8移植uCOSIII并以不同周期点亮两个LED灯(HAL库方式)【uCOS】【STM32开发板】【STM32CubeMX】

STM32F103C8移植uC/OSIII并以不同周期点亮两个LED灯&#xff08;HAL库方式&#xff09;【uC/OS】【STM32开发板】【STM32CubeMX】 实验说明 将嵌入式操作系统uC/OSIII移植到STM32F103C8上&#xff0c;构建两个任务&#xff0c;两个任务分别以1s和3s周期对LED进行点亮—熄灭的…

基于Python + Flask+ Mysq实现简易留言板

使用Python Flask Mysql实现简易留言板&#xff0c;包括网友编辑留言、修改留言&#xff0c;删除留言、分页显示四大功能。 写出留言板建设过程&#xff0c;包括开发使用工具、留言板模块设计、数据库设计、页面设计、关键技术。 留言板建设过程总结 一&#xff0e;开发使用…

一文学习yolov5 实例分割:从训练到部署

一文学习yolov5 实例分割&#xff1a;从训练到部署 1.模型介绍1.1 YOLOv5结构1.2 YOLOv5 推理时间 2.构建数据集2.1 使用labelme标注数据集2.2 生成coco格式label2.3 coco格式转yolo格式 3.训练3.1 整理数据集3.2 修改配置文件3.3 执行代码进行训练 4.使用OpenCV进行c部署参考文…

燃料电池汽车践行者

前言 见《氢燃料电池技术综述》 见《燃料电池工作原理详解》 见《燃料电池发电系统详解》 见《燃料电池电动汽车详解》 见《氢燃料电池汽车行业发展》 现代汽车&#xff08;中国&#xff09; 现代汽车集团&#xff0c;自1998年成立氢燃料电池研发小组以来深耕氢燃料电池技术&am…

Python爬虫入门与登录验证自动化思路

1、pytyon爬虫 1.1、爬虫简介 Python爬虫是使用Python编写的程序&#xff0c;可以自动访问网页并提取其中的信息。爬虫可以模拟浏览器的行为&#xff0c;自动点击链接、填写表单、进行登录等操作&#xff0c;从而获取网页中的数据。 使用Python编写爬虫的好处是&#xff0c;…

IGraph使用实例——线性代数计算(blas)

1 概述 在图论中&#xff0c;BLAS&#xff08;Basic Linear Algebra Subprograms&#xff09;并不直接应用于图论的计算&#xff0c;而是作为一套线性代数计算中通用的基本运算操作函数集合&#xff0c;用于进行向量和矩阵的基本运算。然而&#xff0c;这些基本运算在图论的相…

LangChain基础知识入门

LangChain的介绍和入门 1 什么是LangChain LangChain由 Harrison Chase 创建于2022年10月&#xff0c;它是围绕LLMs&#xff08;大语言模型&#xff09;建立的一个框架&#xff0c;LLMs使用机器学习算法和海量数据来分析和理解自然语言&#xff0c;GPT3.5、GPT4是LLMs最先进的代…

矩阵LU分解的应用

矩阵LU分解在机器学习和深度学习中的应用广泛&#xff0c;主要用于解决以下问题&#xff1a; 线性方程组求解&#xff1a;LU分解可以有效地解决线性方程组&#xff0c;这在训练模型时非常有用。矩阵求逆&#xff1a;在一些机器学习算法中&#xff0c;需要进行矩阵求逆操作&…

289M→259M得物包体积治理实践

一、前言 iOS应用的包体积大小是衡量得物性能的重要指标&#xff0c;过大包体积会降低用户对应用的下载意愿&#xff0c;还会增加用户的下载等待时间以及用户手机的存储空间&#xff0c;本文重点介绍在包体积治理中的新思路以及原理与实践。 二、原理介绍 Macho产物测试 我…

Autodesk 3ds Max软件下载安装;3ds Max功能强大的三维建模、渲染软件安装包获取

3ds Max&#xff0c;无论是初学者还是资深设计师&#xff0c;都能通过3ds Max在数字世界中实现自己的创意&#xff0c;打造出令人惊叹的三维作品。 在3ds Max中&#xff0c;灯光系统是至关重要的一环。它提供了光度学灯光和标准灯光两种主要类型&#xff0c;用于照亮和增强场景…

CleanMyMac2028永久破解版苹果mac电脑垃圾清理软件

CleanMyMac&#xff0c;这款苹果mac电脑垃圾清理软件简直就是我的救星啊&#xff01;以前总是被电脑上的各种垃圾文件困扰&#xff0c;不知道如何彻底清理。自从用了CleanMyMac&#xff0c;我的电脑就像重新获得了新生一样&#xff01; 它的功能强大到让我惊叹不已&#xff01;…

R语言探索与分析19-CPI的分析和研究

一、选题背景 CPI&#xff08;居民消费价格指数&#xff09;作为一个重要的宏观经济指标&#xff0c;扮演着评估通货膨胀和居民生活水平的关键角色。在湖北省这个经济活跃的地区&#xff0c;CPI的波动对于居民生活、企业经营以及政府宏观经济政策制定都具有重要的影响。因此&a…

电影制作中的版本控制:Perforce Helix Core帮助某电影短片避免灾难性文件损坏,简化艺术资产管理

Zubaida Nila是来自马来西亚的一名视觉特效师和虚拟制作研究员&#xff0c;她参加了Epic Games的一个为期六周的虚拟培训和指导项目——女性创作者计划。该计划提供了虚幻引擎工作流程的实践经验以及其他课程。Zubaida希望从中获得更多关于虚幻引擎的灯光、后期处理和特效技能方…

机器学习——卷积神经网络

卷积神经网络CNN 多层感知机MLP的层数足够&#xff0c;理论上可以用其提取出二位特征&#xff0c;但是毕竟复杂&#xff0c;卷积神经网络就可以更合适的来提取高维的特征。 而卷积其实是一种运算 二维离散卷积的公式 可以看成g是一个图像的像素点&#xff0c;f是每个像素点对…

使用LabVIEW进行大数据数组操作的优化方法

针对大数据量数组操作&#xff0c;传统的内存处理方法可能导致内存不足。通过LabVIEW的图像批处理技术&#xff0c;可以有效地进行大数据数组操作&#xff0c;包括分块处理、并行处理和内存优化等。这种方法能显著提高处理效率和系统稳定性。 图像批处理的优势 内存优化&#…

docker部署使用本地文件的fastapi项目

项目背景&#xff1a;项目使用python开发&#xff0c;需要使用ubutun系统部署后端api接口&#xff0c;对外使用8901端口。 1:项目结构&#xff1a; 2&#xff1a;项目需要使用的pyhton版本为3.9&#xff0c;dockerfile内容如下&#xff1a; # FROM python:3.9# WORKDIR /co…

LLM大语言模型(十六):最新开源 GLM4-9B 本地部署,带不动,根本带不动

目录 前言 本机环境 GLM4代码库下载 模型文件下载&#xff1a;文件很大 修改为从本地模型文件启动 启动模型cli对话demo 慢&#xff0c;巨慢&#xff0c;一个字一个字的蹦 GPU资源使用情况 GLM3资源使用情况对比 前言 GLM-4-9B 是智谱 AI 推出的最新一代预训练模型 …

面试官:前端实现图片懒加载怎么做?这不是撞我怀里了嘛!

前端懒加载&#xff08;也称为延迟加载或按需加载&#xff09;是一种网页性能优化的技术&#xff0c;主要用于在网页中延迟加载某些资源&#xff0c;如图片、视频或其他媒体文件&#xff0c;直到它们实际需要被用户查看或交互时才进行加载。这种技术特别适用于长页面或包含大量…

单片机数码管时钟电路的设计

5 调试 数码管的引脚1&#xff5e;4&#xff0c;a&#xff5e;g以及小数点的排列都不是连续的&#xff0c;这就意味着难免需要飞线。数码管是分共阴和共阳的&#xff0c;起初我错把原理图中的共阳数码管当成了共阴数码管&#xff0c;焊上去了之后才发现&#xff0c;为了避免拆卸…

JWT 从入门到精通

什么是 JWT JSON Web Token&#xff08;JWT&#xff09;是目前最流行的跨域身份验证解决方案 JSON Web Token Introduction - jwt.ioLearn about JSON Web Tokens, what are they, how they work, when and why you should use them.https://jwt.io/introduction 一、常见会…