{"id":450,"date":"2025-10-31T12:21:10","date_gmt":"2025-10-31T12:21:10","guid":{"rendered":"https:\/\/blog.ngocha.biz\/?p=450"},"modified":"2025-10-31T12:21:10","modified_gmt":"2025-10-31T12:21:10","slug":"node-feature-discovery","status":"publish","type":"post","link":"https:\/\/blog.ngocha.biz\/?p=450","title":{"rendered":"Node Feature Discovery (NFD) on Kubernetes (Detailed Guide)"},"content":{"rendered":"<p>In this blog, we will look at a Kubernetes feature called Node Feature Discovery.<\/p>\n<p>At the end of this blog, you will learn the following:<\/p>\n<ul>\n<li>What is NFD in Kubernetes<\/li>\n<li>NFD Architecture<\/li>\n<li>Hands on NFD<\/li>\n<li>Label Filtering to avoid label explosion.<\/li>\n<li>Key Use Cases<\/li>\n<\/ul>\n<h2 id=\"what-is-node-feature-discovery\">What is Node Feature Discovery?<\/h2>\n<p>By default, every Kubernetes node comes with a few&nbsp;<strong>basic built-in labels<\/strong>&nbsp;that are automatically added by the&nbsp;<strong>kubelet<\/strong>.<\/p>\n<p>For example,<\/p>\n<ol>\n<li>kubernetes.io\/hostname=&lt;node-name&gt;<\/li>\n<li>kubernetes.io\/os=linux<\/li>\n<li>kubernetes.io\/arch=amd64<\/li>\n<\/ol>\n<p>If your cluster runs on a&nbsp;<strong>cloud provider like AWS EKS<\/strong>, you will also see extra labels that describe the cloud environment, such as:<\/p>\n<ol>\n<li>topology.kubernetes.io\/region=ap-south-1<\/li>\n<li>topology.kubernetes.io\/zone=ap-south-1a<\/li>\n<li>node.kubernetes.io\/instance-type=t3.medium<\/li>\n<\/ol>\n<p>These labels are useful for&nbsp;<strong>scheduling<\/strong>,&nbsp;<strong>automation<\/strong>, and&nbsp;<strong>workload placement<\/strong>.<br \/>For instance, you can schedule a Pod to run only in a certain region or on a specific instance type.<\/p>\n<p>However, notice that these default labels don\u2019t include any details about the&nbsp;<strong>hardware<\/strong>,&nbsp;<strong>kernel<\/strong>, or&nbsp;<strong>device features<\/strong>&nbsp;of the node.<\/p>\n<p>Thats where&nbsp;<strong>Node Feature Discovery (NFD)<\/strong>&nbsp;comes in.<\/p>\n<p><strong>Node Feature Discovery<\/strong>&nbsp;is a Kubernetes add-on that automatically detects and labels node-level features such as CPU flags, memory, kernel version, network adapters, and GPU capabilities.<\/p>\n<p>If you have used&nbsp;<strong>Ansible facts<\/strong>&nbsp;before, NFD works in a similar way.<\/p>\n<p>Just like Ansible gathers system information and provides it as metadata,&nbsp;<strong>NFD collects system details<\/strong>&nbsp;from Kubernetes nodes and exposes them as&nbsp;<strong>node labels<\/strong>.<\/p>\n<h2 id=\"node-feature-discovery-architecture\">Node Feature Discovery Architecture<\/h2>\n<p>Node Feature Discovery has 4 components:<\/p>\n<ul>\n<li>nfd-master<\/li>\n<li>nfd-worker<\/li>\n<li>nfd-topology-updater<\/li>\n<li>nfd-gc<\/li>\n<\/ul>\n<p>The workflow overview for Node Feature Discovery is given below.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/10\/nfd.webp\" class=\"kg-image\" alt=\"Kubernetes Node Feature Discovery Workflow\" loading=\"lazy\" width=\"1578\" height=\"1652\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/10\/nfd.webp 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1000\/2025\/10\/nfd.webp 1000w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/10\/nfd.webp 1578w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<p>Here is how it all works together.<\/p>\n<ul>\n<li><strong>nfd-worker<\/strong>&nbsp;runs as a DaemonSet on each node. It scans multiple sources (CPU, memory, PCI, etc.) and writes raw feature data into&nbsp;<strong>NodeFeature<\/strong>&nbsp;custom resources.<\/li>\n<li>At regular intervals (default ~60s), workers update NodeFeature CRs to reflect changes.<\/li>\n<li><strong>nfd-master<\/strong>&nbsp;runs as a Deployment (usually a single replica). It watches these NodeFeature CRs, applies any filtering or rules, and updates the actual Node objects (labels, taints, extended resources) via the Kubernetes API.<\/li>\n<li><strong>nfd-topology-updater<\/strong>&nbsp;(if enabled) also runs as a DaemonSet. It collects NUMA, CPU, memory, and device topology from nodes and publishes NodeResourceTopology objects so that Topology Manager can do NUMA-aware scheduling.<\/li>\n<li><strong>nfd-gc<\/strong>&nbsp;(Garbage Collector) ensures that for any node that has left the cluster, its corresponding NodeFeature or NodeResourceTopology objects are removed. The default garbage collection interval is 1 hour.<\/li>\n<\/ul>\n<h2 id=\"prerequisites\">Prerequisites<\/h2>\n<p>Below are the prerequisites required before going to the next section.<\/p>\n<ul>\n<li>A running <a href=\"https:\/\/devopscube.com\/production-ready-kubernetes-cluster\/\" rel=\"noreferrer\">Kubernetes cluster<\/a><\/li>\n<li><a href=\"https:\/\/devopscube.com\/create-helm-chart\/\" rel=\"noreferrer\">Helm<\/a> is installed in your system<\/li>\n<\/ul>\n<h2 id=\"install-node-feature-discovery\">Install Node Feature Discovery<\/h2>\n<p>We are going to install Node Feature Discovery using Helm.<\/p>\n<p>Before installing Node Feature Discovery, check the current labels on your node.<\/p>\n<pre><code class=\"language-bash\">kubectl get no --show-labels | grep multi-node-cluster-worker2 <\/code><\/pre>\n<p>I have given one of the node&#8217;s names, update it to your nodes name before running the command.<\/p>\n<pre><code class=\"language-bash\">$ kubectl get no --show-labels | grep multi-node-cluster-worker2 \n\nmulti-node-cluster-worker2         Ready    &lt;none&gt;          8m10s   v1.33.0   beta.kubernetes.io\/arch=amd64,beta.kubernetes.io\/os=linux,kubernetes.io\/arch=amd64,kubernetes.io\/hostname=multi-node-cluster-worker2,kubernetes.io\/os=linux<\/code><\/pre>\n<p>Now, run the following command to install Node Feature Discovery.<\/p>\n<pre><code class=\"language-bash\">helm install -n node-feature-discovery --create-namespace nfd oci:\/\/registry.k8s.io\/nfd\/charts\/node-feature-discovery --version 0.18.1<\/code><\/pre>\n<p>If you want to deploy the <code>topologyUpdater<\/code> pod, add the flags <code>--set topologyUpdater.createCRDs=true<\/code> and  <code>--set topologyUpdater.enable=true<\/code> in the above command.<\/p>\n<p>For example,<\/p>\n<pre><code class=\"language-bash\">helm install -n node-feature-discovery --create-namespace nfd oci:\/\/registry.k8s.io\/nfd\/charts\/node-feature-discovery --version 0.18.1 --set topologyUpdater.createCRDs=true --set topologyUpdater.enable=true<\/code><\/pre>\n<p>For other installation options, refer to the <a href=\"https:\/\/kubernetes-sigs.github.io\/node-feature-discovery\/v0.18\/deployment\/?ref=devopscube.com\">official documentation<\/a>.<\/p>\n<p>Run the following command to check if the pods are created and running.<\/p>\n<pre><code class=\"language-bash\">kubectl get po -n node-feature-discovery<\/code><\/pre>\n<p>You will get the following output.<\/p>\n<pre><code class=\"language-bash\">NAME                                                 READY   STATUS    RESTARTS   AGE\n\nnfd-node-feature-discovery-gc-b765d6879-drf85        1\/1     Running   0          75s\nnfd-node-feature-discovery-master-78b957b755-jbncc   1\/1     Running   0          75s\nnfd-node-feature-discovery-worker-9vgt7              1\/1     Running   0          75s\nnfd-node-feature-discovery-worker-w476p              1\/1     Running   0          75s<\/code><\/pre>\n<p>Once the pods start running, run the following command to check the nodes labels again.<\/p>\n<pre><code class=\"language-bash\">$ kubectl get no --show-labels | grep multi-node-cluster-worker2 \n\nmulti-node-cluster-worker2         Ready    &lt;none&gt;          11m   v1.33.0   beta.kubernetes.io\/arch=amd64,beta.kubernetes.io\/os=linux,feature.node.kubernetes.io\/cpu-cpuid.ADX=true,feature.node.kubernetes.io\/cpu-cpuid.AESNI=true,feature.node.kubernetes.io\/cpu-cpuid.AVX2=true,feature.node.kubernetes.io\/cpu-cpuid.AVX=true,feature.node.kubernetes.io\/cpu-cpuid.CMPXCHG8=true,feature.node.kubernetes.io\/cpu-cpuid.FMA3=true,feature.node.kubernetes.io\/cpu-cpuid.FXSR=true,feature.node.kubernetes.io\/cpu-cpuid.FXSROPT=true,feature.node.kubernetes.io\/cpu-cpuid.HYPERVISOR=true,feature.node.kubernetes.io\/cpu-cpuid.LAHF=true,feature.node.kubernetes.io\/cpu-cpuid.MOVBE=true,feature.node.kubernetes.io\/cpu-cpuid.OSXSAVE=true,feature.node.kubernetes.io\/cpu-cpuid.SYSCALL=true,feature.node.kubernetes.io\/cpu-cpuid.SYSEE=true,feature.node.kubernetes.io\/cpu-cpuid.X87=true,feature.node.kubernetes.io\/cpu-cpuid.XGETBV1=true,feature.node.kubernetes.io\/cpu-cpuid.XSAVE=true,feature.node.kubernetes.io\/cpu-cpuid.XSAVEC=true,feature.node.kubernetes.io\/cpu-cpuid.XSAVEOPT=true,feature.node.kubernetes.io\/cpu-hardware_multithreading=false,feature.node.kubernetes.io\/cpu-model.family=6,feature.node.kubernetes.io\/cpu-model.id=158,feature.node.kubernetes.io\/cpu-model.vendor_id=Intel,feature.node.kubernetes.io\/kernel-config.NO_HZ=true,feature.node.kubernetes.io\/kernel-config.NO_HZ_FULL=true,feature.node.kubernetes.io\/kernel-version.full=6.10.14-linuxkit,feature.node.kubernetes.io\/kernel-version.major=6,feature.node.kubernetes.io\/kernel-version.minor=10,feature.node.kubernetes.io\/kernel-version.revision=14,feature.node.kubernetes.io\/memory-swap=true,feature.node.kubernetes.io\/storage-nonrotationaldisk=true,feature.node.kubernetes.io\/system-os_release.ID=debian,feature.node.kubernetes.io\/system-os_release.VERSION_ID.major=12,feature.node.kubernetes.io\/system-os_release.VERSION_ID=12,kubernetes.io\/arch=amd64,kubernetes.io\/hostname=multi-node-cluster-worker2,kubernetes.io\/os=linux<\/code><\/pre>\n<h2 id=\"advance-node-label-filtering\">Advance Node Label Filtering<\/h2>\n<p>By default NFD gets all available features and updates in the node. This leads to&nbsp;label explosion. Meaning,&nbsp;<strong>too many labels are created<\/strong>&nbsp;on your Kubernetes nodes.<\/p>\n<p>Too many labels make node metadata big, which can slow down API responses.<\/p>\n<p>To mitigate this, you can&nbsp;<strong>limit or filter<\/strong>&nbsp;what NFD labels.<\/p>\n<p>During the NFD installation, you can control the label filtering using the <code>--set worker.config.core.labelSources<\/code> flag.<\/p>\n<p>Lets say, you only need to label the available features on <code>cpu<\/code>, you can use the flag <code>--set worker.config.core.labelSources=\"{cpu}\"<\/code> to filter the components labels you need.<\/p>\n<p>For example,<\/p>\n<pre><code class=\"language-bash\">helm install -n node-feature-discovery --create-namespace nfd oci:\/\/registry.k8s.io\/nfd\/charts\/node-feature-discovery --version 0.18.1 --set worker.config.core.labelSources=\"{cpu}\"<\/code><\/pre>\n<p>For advanced filtering, you need to download the Helm values file.<\/p>\n<pre><code class=\"language-bash\">helm show values oci:\/\/registry.k8s.io\/nfd\/charts\/node-feature-discovery --version 0.18.1 -n node-feature-discovery &gt; values.yaml<\/code><\/pre>\n<p>Then go to the master configuration section and add the following.<\/p>\n<div class=\"kg-card kg-callout-card kg-callout-card-blue\">\n<div class=\"kg-callout-emoji\">\ud83d\udca1<\/div>\n<div class=\"kg-callout-text\">You can do the same configuration on the workers configmap as well, but if you need any changes, you need to restart every worker pod on every node.<\/div>\n<\/div>\n<p>For example, I am going to whitelist only the labels for CPU and memory.<\/p>\n<pre><code class=\"language-bash\">config:\n  extraLabelNs:\n    - \"feature.node.kubernetes.io\"\n  labelWhiteList: \"^(cpu|memory).*\"\n<\/code><\/pre>\n<p>Once the configuration is added under the master, as shown below.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/10\/image-136.png\" class=\"kg-image\" alt=\"filterting labels\" loading=\"lazy\" width=\"517\" height=\"302\"><\/figure>\n<p>Run the following Helm upgrade command.<\/p>\n<pre><code class=\"language-bash\">helm upgrade nfd oci:\/\/registry.k8s.io\/nfd\/charts\/node-feature-discovery --version 0.18.1 -n node-feature-discovery -f values.yaml<\/code><\/pre>\n<p>This will restart the master pod and add only the labels of CPU and Memory to the nodes.<\/p>\n<pre><code class=\"language-bash\">$ kubectl get no --show-labels | grep multi-node-cluster-worker2\n\nmulti-node-cluster-worker2         Ready    &lt;none&gt;          172m   v1.33.0   beta.kubernetes.io\/arch=amd64,beta.kubernetes.io\/os=linux,feature.node.kubernetes.io\/cpu-cpuid.ADX=true,feature.node.kubernetes.io\/cpu-cpuid.AESNI=true,feature.node.kubernetes.io\/cpu-cpuid.AVX2=true,feature.node.kubernetes.io\/cpu-cpuid.AVX=true,feature.node.kubernetes.io\/cpu-cpuid.CMPXCHG8=true,feature.node.kubernetes.io\/cpu-cpuid.FMA3=true,feature.node.kubernetes.io\/cpu-cpuid.FXSR=true,feature.node.kubernetes.io\/cpu-cpuid.FXSROPT=true,feature.node.kubernetes.io\/cpu-cpuid.HYPERVISOR=true,feature.node.kubernetes.io\/cpu-cpuid.LAHF=true,feature.node.kubernetes.io\/cpu-cpuid.MOVBE=true,feature.node.kubernetes.io\/cpu-cpuid.OSXSAVE=true,feature.node.kubernetes.io\/cpu-cpuid.SYSCALL=true,feature.node.kubernetes.io\/cpu-cpuid.SYSEE=true,feature.node.kubernetes.io\/cpu-cpuid.X87=true,feature.node.kubernetes.io\/cpu-cpuid.XGETBV1=true,feature.node.kubernetes.io\/cpu-cpuid.XSAVE=true,feature.node.kubernetes.io\/cpu-cpuid.XSAVEC=true,feature.node.kubernetes.io\/cpu-cpuid.XSAVEOPT=true,feature.node.kubernetes.io\/cpu-hardware_multithreading=false,feature.node.kubernetes.io\/cpu-model.family=6,feature.node.kubernetes.io\/cpu-model.id=158,feature.node.kubernetes.io\/cpu-model.vendor_id=Intel,feature.node.kubernetes.io\/memory-swap=true,kubernetes.io\/arch=amd64,kubernetes.io\/hostname=multi-node-cluster-worker2,kubernetes.io\/os=linux<\/code><\/pre>\n<h2 id=\"how-to-deploy-pods-in-a-specific-node-using-nfd-labels\">How to deploy pods in a specific Node using NFD Labels?<\/h2>\n<p>You can use any of the NFD generated labels in the <code>nodeSelector<\/code> to deploy the workloads in this node.<\/p>\n<p>As an example, let&#8217;s deploy the <a href=\"https:\/\/devopscube.com\/setup-ingress-kubernetes-nginx-controller\/\" rel=\"noreferrer\">nginx<\/a> pod in the node that has <a href=\"https:\/\/devopscube.com\/kubernetes-swap\/\" rel=\"noreferrer\">swap<\/a> enabled.<\/p>\n<div class=\"kg-card kg-callout-card kg-callout-card-blue\">\n<div class=\"kg-callout-emoji\">\ud83d\udccc<\/div>\n<div class=\"kg-callout-text\">One of my node <code spellcheck=\"false\" style=\"white-space: pre-wrap;\">multi-node-cluster-worker2<\/code> already has swap enabled and NFD has enabled the swap label.<\/div>\n<\/div>\n<p>First,c reate a YAML file <code>nfd.yaml<\/code> and copy the following content.<\/p>\n<pre><code class=\"language-yaml\">apiVersion: v1\nkind: Pod\nmetadata:\n  name: nginx\nspec:\n  containers:\n  - name: nginx\n    image: nginx:latest\n  nodeSelector:\n    feature.node.kubernetes.io\/memory-swap: \"true\"\n<\/code><\/pre>\n<p>Use the command below to apply the manifest.<\/p>\n<pre><code class=\"language-bash\">kubectl apply -f nfd.yaml<\/code><\/pre>\n<p>Then, run the following command to check, in which node the pod is deployed.<\/p>\n<pre><code class=\"language-bash\">kubectl get po -o wide<\/code><\/pre>\n<p>You will get the following output.<\/p>\n<pre><code class=\"language-bash\">NAME   READY  STATUS   RESTARTS  AGE  IP          NODE   \n\nnginx  1\/1    Running  0         4m   10.244.1.3  multi-node-cluster-worker2<\/code><\/pre>\n<p>You can see the pod is deployed in the node, which has swap enabled.<\/p>\n<h2 id=\"clean-up\">Clean Up<\/h2>\n<p>If you no longer need this, run the following command.<\/p>\n<pre><code class=\"language-bash\">helm delete -n node-feature-discovery nfd<\/code><\/pre>\n<h2 id=\"nfd-real-world-use-cases\">NFD Real World Use Cases<\/h2>\n<p>Lets look at three key use cases for NFD so that you understand it better.<\/p>\n<h4 id=\"1-detecting-nodes-with-swap-enabled\">1. Detecting Nodes with Swap Enabled<\/h4>\n<p>One simple and practical use case of NFD is to automatically detect nodes with swap enabled.<\/p>\n<p>In our&nbsp;<a href=\"https:\/\/newsletter.devopscube.com\/p\/kubernetes-swap?ref=devopscube.com\" rel=\"noopener noreferrer nofollow\">Kubernetes Swap newsletter<\/a>, I explained how NFD can label such nodes.<br \/>Once installed, NFD adds labels that indicate whether swap is turned on or off for each node.<\/p>\n<p>This makes it easy to schedule or monitor Pods based on swap status.<\/p>\n<h4 id=\"2-scheduling-ai-and-gpu-workloads\">2. Scheduling AI and GPU Workloads<\/h4>\n<p>Another common use case is AI and GPU workload scheduling.<\/p>\n<p>For <a href=\"https:\/\/devopscube.com\/kubernetes-ai-ml-features\/\" rel=\"noreferrer\">Kubernetes AI\/ML<\/a> use cases, NFD works together with the Kubernetes Device Plugin framework (for example, the&nbsp;<a href=\"https:\/\/newsletter.devopscube.com\/p\/kubernetes-built-in-features-for-ai-ml?ref=devopscube.com\" rel=\"noopener noreferrer nofollow\">NVIDIA device plugin<\/a>) to Detect GPU presence and capabilities and ddd GPU-related labels to nodes<\/p>\n<p>This makes it possible to schedule machine learning or deep learning workloads only on GPU-enabled nodes.<\/p>\n<h4 id=\"3-numa-aware-scheduling-and-cpu-pinning\">3. NUMA-Aware Scheduling and CPU Pinning<\/h4>\n<p>For high-performance or latency-sensitive applications, NFD provides the&nbsp;<strong>detailed hardware topology data<\/strong>&nbsp;needed for the following.<\/p>\n<ul>\n<li>NUMA-aware scheduling, where Pods are placed close to the memory and devices they use. (Typically used in AI\/ML inference, Databases etc)<\/li>\n<li>CPU pinning, where specific CPU cores are dedicated to certain workloads (Used in Real-time applications like VoIP, Telecom workloads etc)<\/li>\n<\/ul>\n<p>This helps achieve better performance and resource efficiency in compute-heavy environments.<\/p>\n<p>In short, NFD acts as the hardware awareness layer for Kubernetes.<\/p>\n<p>You can use NFD for any scenario where your application requires special hardware features such as certain GPUs, CPUs, kernel modules, or network devices.<\/p>\n<h2 id=\"conclusion\">Conclusion<\/h2>\n<p>NFD is not required for every Kubernetes setup.<\/p>\n<p>But when you are running&nbsp;<strong>AI\/ML, or network-heavy workloads<\/strong>, it can come in handy.<\/p>\n<p>It helps Kubernetes understand&nbsp;<strong>what your nodes are truly capable of<\/strong>, so pods land exactly where they perform best.<\/p>\n<p>Over to you!<\/p>\n<p>Try out NFD and see if it adds value to your projects.<\/p>\n<hr>\n<p><strong>Ngu\u1ed3n:<\/strong> <a href=\"https:\/\/devopscube.com\/node-feature-discovery\/\" target=\"_blank\" rel=\"noopener noreferrer\">Node Feature Discovery (NFD) on Kubernetes (Detailed Guide) \u2014 DevOpsCube<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Source: https:\/\/devopscube.com\/node-feature-discovery\/<\/p>\n","protected":false},"author":1,"featured_media":451,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-450","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devops"],"_links":{"self":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/posts\/450","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=450"}],"version-history":[{"count":0,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/posts\/450\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/media\/451"}],"wp:attachment":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=450"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=450"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=450"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}