{"id":516,"date":"2018-11-29T12:10:38","date_gmt":"2018-11-29T12:10:38","guid":{"rendered":"https:\/\/blog.ngocha.biz\/?p=516"},"modified":"2018-11-29T12:10:38","modified_gmt":"2018-11-29T12:10:38","slug":"kubernetes-deployment-tutorial","status":"publish","type":"post","link":"https:\/\/blog.ngocha.biz\/?p=516","title":{"rendered":"Kubernetes Deployment Tutorial For Beginners &#8211; Understanding YAML"},"content":{"rendered":"<p>This Kubernetes deployment tutorial guide will explain the key concepts in a Kubernetes YAML specification with an Nginx example deployment.<\/p>\n<h3 id=\"introduction\">Introduction:<\/h3>\n<p>In Kubernetes, pods are the basic units that get deployed in the cluster. Kubernetes deployment is an abstraction layer for the pods.<\/p>\n<p>The main purpose of the deployment object is to maintain the resources declared in the deployment configuration in its desired state. A deployment configuration can be of<code> YAML<\/code> or <code>JSON<\/code> format.<\/p>\n<p>Given below is the simple Kubernetes deployment architecture.<\/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\/08\/deployment.png\" class=\"kg-image\" alt=\"Kubernetes deployment architecture\" loading=\"lazy\" width=\"1586\" height=\"1480\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/08\/deployment.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1000\/2025\/08\/deployment.png 1000w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/08\/deployment.png 1586w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<h3 id=\"key-things-to-understand\">Key Things To Understand<\/h3>\n<ol>\n<li>A Deployment can schedule multiple pods. A pod as a unit cannot scale by itself.<\/li>\n<li>A Deployment represents a single purpose with a group of PODs.<\/li>\n<li>A single POD can have multiple containers and these containers inside a single POD shares the same IP and can talk to each other using localhost address.<\/li>\n<li>To access a Deployment with one or many PODs, you need a Kubernetes Service endpoint mapped to the deployment using labels and selectors.<\/li>\n<li>A deployment should have only stateless services. Any application that requires state management should be deployed as a Kubernetes StatefulSet.<\/li>\n<\/ol>\n<h3 id=\"deployment-yaml\">Deployment YAML:<\/h3>\n<p>Kubernetes deployment Yaml contains the following main specifications.<\/p>\n<ol>\n<li>apiVersion<\/li>\n<li>Kind<\/li>\n<li>metadata<\/li>\n<li>spec<\/li>\n<\/ol>\n<p>Now let&#8217;s look at each specification in detail.<\/p>\n<p><em><strong>Note:<\/strong> In Kubernetes, everything persistent is defined as an object. Example: Deployments, services, Replica Set, Configmap, Jobs etc<\/em><\/p>\n<h4 id=\"apiversion\">apiVersion<\/h4>\n<p>This specifies the API version of the Kubernetes deployment object. It varies between each Kubernetes version.<\/p>\n<p><strong>How To Use the Right API version: <\/strong>Kubernetes contains three API versions.<\/p>\n<ol>\n<li><strong>Alpha<\/strong>: This is the early release candidate. It might contain bugs and there is no guarantee that it will work in the future. Example: <code>scalingpolicy.kope.io\/v1alpha1<\/code><\/li>\n<li><strong>Beta<\/strong>: The API&#8217;s become beta once its alpha tested. It will be in continuous development &amp; testing until it becomes stable. Beta versions will most likely go into the Kubernetes main APIs.Example: <code>batch\/v1beta1<\/code><\/li>\n<li><strong>Stable<\/strong>: The APIs which does not contain alpha and beta goes into the stable category. Only stable versions are recommended to be used in production systems. Example: <code>apps\/v1<\/code><\/li>\n<\/ol>\n<p>These APIs could belong to different API groups.<\/p>\n<p>An example list of Kubernetes APIs from different API groups from Kubernetes version 1.10.6 is shown below. Deployment object belongs to <code>apps<\/code> API group. You can list these API on http:\/\/localhost:8001\/ using the kubectl proxy.<\/p>\n<pre><code>{\n  \"paths\": [\n    \"\/api\",\n    \"\/api\/v1\",\n    \"\/apis\",\n    \"\/apis\/\",\n    \"\/apis\/admissionregistration.k8s.io\",\n    \"\/apis\/admissionregistration.k8s.io\/v1beta1\",\n    \"\/apis\/apiextensions.k8s.io\",\n    \"\/apis\/apiextensions.k8s.io\/v1beta1\",\n    \"\/apis\/apiregistration.k8s.io\",\n    \"\/apis\/apiregistration.k8s.io\/v1\",\n    \"\/apis\/apiregistration.k8s.io\/v1beta1\",\n    \"\/apis\/apps\",\n    \"\/apis\/apps\/v1\",\n    \"\/apis\/apps\/v1beta1\",\n    \"\/apis\/apps\/v1beta2\",\n    \"\/apis\/authentication.k8s.io\",\n    \"\/apis\/authentication.k8s.io\/v1\",\n    \"\/apis\/authentication.k8s.io\/v1beta1\",\n    \"\/apis\/authorization.k8s.io\",\n    \"\/apis\/authorization.k8s.io\/v1\",\n    \"\/apis\/authorization.k8s.io\/v1beta1\",\n    \"\/apis\/autoscaling\",\n    \"\/apis\/autoscaling\/v1\",\n    \"\/apis\/autoscaling\/v2beta1\",\n    \"\/apis\/batch\",\n    \"\/apis\/batch\/v1\",\n    \"\/apis\/batch\/v1beta1\",\n    \"\/apis\/certificates.k8s.io\",\n    \"\/apis\/certificates.k8s.io\/v1beta1\",\n    \"\/apis\/cloud.google.com\",\n    \"\/apis\/cloud.google.com\/v1beta1\",\n    \"\/apis\/extensions\",\n    \"\/apis\/extensions\/v1beta1\",\n    \"\/apis\/metrics.k8s.io\",\n    \"\/apis\/metrics.k8s.io\/v1beta1\",\n    \"\/apis\/networking.k8s.io\",\n    \"\/apis\/networking.k8s.io\/v1\",\n    \"\/apis\/policy\",\n    \"\/apis\/policy\/v1beta1\",\n    \"\/apis\/rbac.authorization.k8s.io\",\n    \"\/apis\/rbac.authorization.k8s.io\/v1\",\n    \"\/apis\/rbac.authorization.k8s.io\/v1beta1\",\n    \"\/apis\/scalingpolicy.kope.io\",\n    \"\/apis\/scalingpolicy.kope.io\/v1alpha1\",\n    \"\/apis\/storage.k8s.io\",\n    \"\/apis\/storage.k8s.io\/v1\",\n    \"\/apis\/storage.k8s.io\/v1beta1\"\n    ]\n}<\/code><\/pre>\n<h4 id=\"kind\">Kind<\/h4>\n<p>Kind describes the type of the object\/resource to be created. In our case its a deployment object. Following are the main list of objects\/resources supported by Kubernetes.<\/p>\n<pre><code>componentstatuses\nconfigmaps\ndaemonsets\ndeployments\nevents\nendpoints\nhorizontalpodautoscalers\ningress\njobs\nlimitranges\nnamespaces\nnodes\npods\npersistentvolumes\npersistentvolumeclaims\nresourcequotas\nreplicasets\nreplicationcontrollers\nserviceaccounts\nservices<\/code><\/pre>\n<h4 id=\"metadata\">Metadata<\/h4>\n<p>It is a set of data to uniquely identify a Kubernetes object. Following are the key metadata that can be added to an object.<\/p>\n<pre><code>labels\nname\nnamespace\nannotations<\/code><\/pre>\n<p>Let&#8217;s have a look at each metadata type<\/p>\n<ol>\n<li><strong>Labels<\/strong>: Key-value pairs primarily used to group and categorize deployment object. It is intended for an object to object grouping and mapping using selectors. For example, kubernetes service uses the pod labels in its selectors to send traffic to the right pods. We will see more about labels and selectors in the service creation section.<\/li>\n<li><strong>Name<\/strong>: It represents the name of the deployment to be created.<\/li>\n<li><strong>Namespace<\/strong>: Name of the namespace where you want to create the deployment.<\/li>\n<li><strong>Annotations<\/strong>: key-value pairs like labels, however, used for different use cases. You can add any information to annotations. For example, you can have an annotation like <code> \"monitoring\" : \"true<\/code> and external sources will be able to find all the objects with this <a href=\"https:\/\/devopscube.com\/setup-prometheus-monitoring-on-kubernetes\/\" rel=\"noopener noreferrer\">annotation to scrape its metrics<\/a>. Objects without this annotation will be omitted.<\/li>\n<\/ol>\n<p>There are other system generated metadata such us UUID, timestamp, resource version etc. that gets added to each deployment.<\/p>\n<p>Example metadata<\/p>\n<pre><code>metadata:\n  name: resource-name\n  namespace: deployment-demo\n  labels:\n    app: web\n    platform: java\n    release: 18.0\n  annotations:\n    monitoring: true\n    prod: true<\/code><\/pre>\n<h4 id=\"spec\">Spec<\/h4>\n<p>Under spec, we declare the desired state and characteristics of the object we want to have. For example, in deployment spec, we would specify the number of replicas, image name etc. Kubernetes will make sure all the declaration under the spec is brought to the desired state.<\/p>\n<p>Spec has three important subfields.<\/p>\n<ol>\n<li><strong>Replicas<\/strong>: It will make sure the numbers of pods running all the time for the deployment. Example, <\/li>\n<\/ol>\n<pre><code>spec: replicas: 3<\/code><\/pre>\n<ol start=\"2\">\n<li><strong>Selector<\/strong>: It defines the labels that match the pods for the deployments to manage. Example,<\/li>\n<\/ol>\n<pre><code>selector:\n    matchLabels:\n      app: nginx<\/code><\/pre>\n<ol start=\"3\">\n<li><strong>Template<\/strong>: It has its own metadata and spec. Spec will have all the container information a pod should have. Container image info, port information, ENV variables, command arguments etc. Example, <\/li>\n<\/ol>\n<pre><code>template:\n    metadata:\n      labels:\n        app: nginx\n    spec:\n      containers:\n        - image: nginx\n          name: nginx<\/code><\/pre>\n<h2 id=\"advanced-options-on-a-deployment\">Advanced Options on a Deployment<\/h2>\n<p>In this section, we will look into the advanced options on a deployment that we will use in every project where we use deployments.<\/p>\n<p>Let&#8217;s look at the options one by one in detail.<\/p>\n<h3 id=\"deployment-strategies\">Deployment Strategies<\/h3>\n<p>Deployment strategy in a deployment defines how new pods can replace old pods when new changes are made.<\/p>\n<p>There are two deployment strategies:<\/p>\n<ul>\n<li>RollingUpdate<\/li>\n<li>Recreate<\/li>\n<\/ul>\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\">The default deployment strategy is RollingUpdate<\/div>\n<\/div>\n<h4 id=\"rollingupdate\">RollingUpdate<\/h4>\n<p>When using this strategy, the new pods will be created one after another by deleting the old pods one by one.<\/p>\n<p>For example, if the deployment has 3 pods when a change is made, it terminates one old pod and creates a new pod.<\/p>\n<p>When the new pod starts running, it then again deletes another old pod and creates a new one. This process is repeated until all pods are rolled out.<\/p>\n<p>We can control the maximum number of pods that can be unavailable using <code>maxUnavailable<\/code> and the maximum pods that can be created above the desired replica using <code>maxSurge<\/code>.<\/p>\n<pre><code>spec:\n  strategy:\n   type: RollingUpdate\n   rollingUpdate:\n     maxSurge: 1\n     maxUnavailable: 1<\/code><\/pre>\n<h4 id=\"recreate\">Recreate<\/h4>\n<p>If you are using this strategy, when a new change is made, it deletes all pods at once and creates new pods.<\/p>\n<pre><code>strategy:\n  type: Recreate<\/code><\/pre>\n<h3 id=\"using-configmap-and-secret-in-deployments\">Using ConfigMap and Secret in Deployments<\/h3>\n<p>It&#8217;s very important not to hardcode sensitive data and configuration values in application code.<\/p>\n<p>That&#8217;s where ConfigMap and Secret help you, use secrets to store sensitive data and configmaps to store non-sensitive configuration values.<\/p>\n<p>When creating a deployment, you can either use the data in a secret, a configmap, and an environment variable or mount them as a volume.<\/p>\n<p>An example of using data in a secret and a configmap as an environment variable is shown below.<\/p>\n<pre><code>spec:\n  containers:\n      envFrom:\n      - configMapRef:\n          name: app-config\n      - secretRef:\n          name: app-secrets\n<\/code><\/pre>\n<h3 id=\"setting-resource-requests-and-limits\">Setting Resource Requests and Limits<\/h3>\n<p>Setting up resource requests and limits in deployment is important, it tells the cluster how much CPU and memory each deployment&#8217;s pods are going to use.<\/p>\n<ul>\n<li><strong>Resource request<\/strong> &#8211; minimum resources the pods are going to use.<\/li>\n<li><strong>Resource limit<\/strong> &#8211; maximum resource it can use.<\/li>\n<\/ul>\n<p>An example of a resource request and limit block is given below.<\/p>\n<pre><code>spec:\n  containers:\n    resources:\n      requests:\n        memory: \"64Mi\"\n        cpu: \"250m\"\n      limits:\n        memory: \"128Mi\"\n        cpu: \"500m\"<\/code><\/pre>\n<h3 id=\"adding-health-check-probes\">Adding Health Check Probes<\/h3>\n<p>There are three health check probes, they are:<\/p>\n<h4 id=\"startupprobe\">startupProbe<\/h4>\n<p>We use a startup probe for an application that takes more time to start, and other health check probes won&#8217;t start until the startup probe check is successful.<\/p>\n<p>If this probe fails, the pod gets terminated, and a new pod will be created.<\/p>\n<h4 id=\"livenessprobe\">livenessProbe<\/h4>\n<p>This probe is used to check if the application is running without any issues.<\/p>\n<p>If the application is not running or crashed, the pod gets restarted.<\/p>\n<h4 id=\"readinessprobe\">readinessProbe<\/h4>\n<p>This probe checks if the application is receiving traffic.<\/p>\n<p>If the application fails to receive traffic, the pod will be removed from the service endpoint.<\/p>\n<p>Given below is an example of how the health check probes are used in a deployment.<\/p>\n<pre><code>spec:\n  containers:\n  \n    startupProbe:\n      httpGet:\n        path: \/startup\n        port: 8080\n      failureThreshold: 30\n      periodSeconds: 10\n      \n    livenessProbe:\n      httpGet:\n        path: \/health\n        port: 8080\n      initialDelaySeconds: 5\n      periodSeconds: 10\n    readinessProbe:\n      httpGet:\n        path: \/ready\n        port: 8080\n      initialDelaySeconds: 5\n      periodSeconds: 10\n<\/code><\/pre>\n<h3 id=\"mounting-persistent-volume\">Mounting Persistent Volume<\/h3>\n<p>Applications need storage to store their data so the data is persistent even if the pods get restarted.<\/p>\n<p>You can create PV and PVC and mount the volume in the directory where your application writes its data.<\/p>\n<p>Below is an example of mounting PV in your application.<\/p>\n<pre><code>spec:\n  template:\n    spec:\n      containers:\n          volumeMounts:\n            - name: test-storage\n              mountPath: \/data\n      volumes:\n        - name: test-storage\n          persistentVolumeClaim:\n            claimName: test-pvc\n<\/code><\/pre>\n<p>Not just PV, you can also mount secrets and configmaps as volumes.<\/p>\n<h2 id=\"kubernetes-example-deployment\">Kubernetes Example Deployment<\/h2>\n<p>Since we have looked at the basics let start with an example deployment. We will do the following in this section.<\/p>\n<ol>\n<li>Create a namespace<\/li>\n<li>Create a Nginx Deployment<\/li>\n<li>Create a Nginx Service<\/li>\n<li>Expose and access the Nginx Service<\/li>\n<\/ol>\n<p><em><strong>Note:<\/strong> Few of the operations we perform in this example can be performed with just kubectl and without a YAML Declaration. However, we are using the YAML specifications for all operations to understand it better.<\/em><\/p>\n<h4 id=\"exercise-folder\">Exercise Folder<\/h4>\n<p>To begin the exercise, create a folder names deployment-demo and cd into that folder. Create all the exercise files in this folder.<\/p>\n<pre><code>mkdir deployment-demo &amp;&amp; cd deployment-demo<\/code><\/pre>\n<h4 id=\"create-a-namespace\">Create a Namespace<\/h4>\n<p>Let&#8217;s create a YAML named <strong>namespace.yaml<\/strong> file for creating the namespace.<\/p>\n<pre><code>apiVersion: v1\nkind: Namespace\nmetadata:\n  name: deployment-demo\n  labels:\n    apps: web-based\n  annotations:\n    type: demo<\/code><\/pre>\n<p>Use kubectl command to create the namespace.<\/p>\n<pre><code>kubectl create -f namespace.yaml<\/code><\/pre>\n<p>Equivalent kubectl command<\/p>\n<pre><code>kubectl create namespace deployment-demo<\/code><\/pre>\n<h4 id=\"assign-resource-quota-to-namespace\">Assign Resource Quota To Namespace<\/h4>\n<p>Now let&#8217;s assign some resource quota limits to our newly created namespace. This will make sure the pods deployed in this namespace will not consume more system resources than mentioned in the resource quota.<\/p>\n<p>Create a file named <strong>resourceQuota.yaml<\/strong>. Here is the resource quota YAML contents.<\/p>\n<pre><code>apiVersion: v1\nkind: ResourceQuota\nmetadata:\n  name: mem-cpu-quota\n  namespace: deployment-demo\nspec:\n  hard:\n    requests.cpu: \"4\"\n    requests.memory: 8Gi\n    limits.cpu: \"8\"\n    limits.memory: 16Gi<\/code><\/pre>\n<p>Create the resource quota using the YAML.<\/p>\n<pre><code>kubectl create -f resourceQuota.yaml<\/code><\/pre>\n<p>Now, let&#8217;s describe the namespace to check if the resource quota has been applied to the deployment-demo namespace.<\/p>\n<pre><code>kubectl describe ns deployment-demo<\/code><\/pre>\n<p>The output should look like the following.<\/p>\n<pre><code>Name:         deployment-demo\nLabels:       apps=web-based\nAnnotations:  type=demo\nStatus:       Active\n\nResource Quotas\n Name:            mem-cpu-quota\n Resource         Used  Hard\n --------         ---   ---\n limits.cpu       0     2\n limits.memory    0     2Gi\n requests.cpu     0     1\n requests.memory  0     1Gi<\/code><\/pre>\n<h3 id=\"create-a-deployment\">Create a Deployment<\/h3>\n<p>We will use the public Nginx image for this deployment.<\/p>\n<p>Create a file named <strong>deployment.yaml<\/strong> and copy the following YAML to the file.<\/p>\n<p><em><strong>Note<\/strong>: This deployment YAML has minimal required information we discussed above. You can have more specification in the deployment YAML based on the requirement.<\/em><\/p>\n<pre><code>apiVersion: apps\/v1\nkind: Deployment\nmetadata:\n  name: nginx\n  labels:\n    app: nginx\n  namespace: deployment-demo\n  annotations:\n    monitoring: \"true\"\nspec:\n  replicas: 1\n  selector:\n    matchLabels:\n      app: nginx\n  template:\n    metadata:\n      labels:\n        app: nginx\n    spec:\n      containers:\n      - image: nginx\n        name: nginx\n        ports:\n        - containerPort: 80\n        resources:\n          limits:\n            memory: \"2Gi\"\n            cpu: \"1000m\"\n          requests: \n            memory: \"1Gi\"\n            cpu: \"500m\"<\/code><\/pre>\n<p>Under containers, we have defined its resource limits, requests and container port (one exposed in Dockerfile).<\/p>\n<p>Create the deployment using kubectl<\/p>\n<pre><code>kubectl create -f deployment.yaml<\/code><\/pre>\n<p>Check the deployment<\/p>\n<pre><code>kubectl get deployments -n deployment-demo<\/code><\/pre>\n<p>Even though we have added minimal information, after deployment, Kubernetes will add more information to the deployment such as resourceVersion, uid, status etc.<\/p>\n<p>You can check it by describing the deployment in YAML format using the kubectl command.<\/p>\n<pre><code>kubectl get deployment nginx -n deployment-demo  --output yaml<\/code><\/pre>\n<h3 id=\"create-a-service-and-expose-the-deployment\">Create a Service and Expose The Deployment<\/h3>\n<p>Now that we have a running deployment, we will create a Kubernetes service of type NodePort ( 30500) pointing to the nginx deployment. Using NodePort you will be able to access the Nginx service on all the kubernetes node on port 30500.<\/p>\n<p>Create a file named <strong>service.yaml<\/strong> and copy the following contents.<\/p>\n<pre><code>apiVersion: v1\nkind: Service\nmetadata:\n  labels:\n    app: nginx\n  name: nginx\n  namespace: deployment-demo\nspec:\n  ports:\n  - nodePort: 30500\n    port: 80\n    protocol: TCP\n    targetPort: 80\n  selector:\n    app: nginx\n  type: NodePort<\/code><\/pre>\n<p>Service is the best example for explaining <strong>labels and selectors<\/strong>. In this service, we have a selector with &#8220;app&#8221; = &#8220;nginx&#8221; label. Using this, the service will be able to match the pods in our nginx deployment as the deployment and the pods have the same label. So automatically all the requests coming to the nginx service will be sent to the nginx deployment.<\/p>\n<p>Let&#8217;s create the service using kubectl command.<\/p>\n<pre><code>kubectl create -f service.yaml<\/code><\/pre>\n<p>You can view the service created using kubectl command.<\/p>\n<pre><code>kubectl get services  -n deployment-demo<\/code><\/pre>\n<p>Now, you will be able to access the nginx service on any one of the kubernetes node IP on port 30500<\/p>\n<p>For example,<\/p>\n<pre><code>http:\/\/35.134.110.153:30500\/<\/code><\/pre>\n<hr>\n<p><strong>Ngu\u1ed3n:<\/strong> <a href=\"https:\/\/devopscube.com\/kubernetes-deployment-tutorial\/\" target=\"_blank\" rel=\"noopener noreferrer\">Kubernetes Deployment Tutorial For Beginners &#8211; Understanding YAML \u2014 DevOpsCube<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Source: https:\/\/devopscube.com\/kubernetes-deployment-tutorial\/<\/p>\n","protected":false},"author":1,"featured_media":517,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-516","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\/516","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=516"}],"version-history":[{"count":0,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/posts\/516\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/media\/517"}],"wp:attachment":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=516"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=516"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=516"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}