{"id":165,"date":"2017-04-12T22:13:02","date_gmt":"2017-04-12T14:13:02","guid":{"rendered":"http:\/\/www.jsjs.org\/?p=165"},"modified":"2017-04-12T22:13:02","modified_gmt":"2017-04-12T14:13:02","slug":"achieving-cicd-with-kubernetes","status":"publish","type":"post","link":"https:\/\/blog.jsjs.org\/?p=165","title":{"rendered":"Achieving CI\/CD with Kubernetes"},"content":{"rendered":"<p>Hola amigos !!(<em>In English &#8211; Hello Friends !!<\/em>) Hope you are having a jolly good day ! Continous Integration\/Delivery is best said in terms of <a href=\"http:\/\/www.martinfowler.com\/\">Martin Fowler<\/a>,according to him it can be defined as, \u201cContinuous Integration is a software development practice where members of a team integrate their work frequently, usually each person integrates at least daily &#8211; leading to multiple integrations per day. Each integration is verified by an automated build (including test) to detect integration errors as quickly as possible. Many teams find that this approach leads to significantly reduced integration problems and allows a team to develop cohesive software more rapidly.\u201d<\/p>\n<p>In this rather interesting piece of article we are going to discuss and explore two amazing and rather interesting pieces technology.One i.e. <a href=\"https:\/\/jenkins.io\/\">Jenkins<\/a>,a popular Continous Integration\/Deployment tool and Second i.e. <a href=\"http:\/\/kubernetes.io\/\">Kubernetes<\/a>,a popular orchestration engine for containers.As an added bonus we are also going to discover fabric8 an awesome tool for microservices platform.So let\u2019s get started,<\/p>\n<p><strong>WARNING<\/strong> Your machine may hang several times while performing the below steps.Choose a pc with high configuration.<\/p>\n<h2 id=\"methodology\">Methodology<\/h2>\n<p>There are many methodologies using which we can achieve CI\/CD for the on our machine.Currently,in this article we are focussed on<\/p>\n<ul>\n<li><a href=\"http:\/\/theremotelab.com\/blog\/achieving-ci-cd-with-k8s\/#kubernetes-jenkins-plugin\">Kubernetes-Jenkins Plugin<\/a><\/li>\n<li><a href=\"http:\/\/theremotelab.com\/blog\/achieving-ci-cd-with-k8s\/#fabric8\">Fabric8<\/a><\/li>\n<\/ul>\n<h2 id=\"overview-of-architecture\">Overview of Architecture<\/h2>\n<p>Before Starting our work,first let\u2019s take a moment and analyze the workflow required to start using <a href=\"http:\/\/kubernetes.io\/\">kubernetes<\/a> containers with <a href=\"https:\/\/jenkins.io\/\">jenkins<\/a>.<a href=\"http:\/\/kubernetes.io\/\">Kubernetes<\/a> is an amazing orchestration engine for containers developed an amazing open source community.The fact that <a href=\"http:\/\/kubernetes.io\/\">kubernetes<\/a> was started by Google,gives Kubernetes an amazing advantage to use multiple open source container projects.By default,<a href=\"http:\/\/docker.com\/\">docker<\/a> is the one that is supported and used most with <a href=\"http:\/\/kubernetes.io\/\">kubernetes<\/a>.So the workflow,with <a href=\"http:\/\/docker.com\/\">docker<\/a> containers looks like,<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloud.githubusercontent.com\/assets\/8342133\/16848715\/ba1473ea-4a14-11e6-99c2-cf8899c351a9.png\" alt=\"k8s-jenkins-docker\" \/><\/p>\n<p>Similarly while using <a href=\"http:\/\/coreos.com\/rkt\">rkt<\/a> containers a.k.a rktnetes.Here\u2019s the architecture:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloud.githubusercontent.com\/assets\/8342133\/16848756\/ef5afe52-4a14-11e6-8723-a251b0b5c675.png\" alt=\"k8s-jenkins-rkt\" \/><\/p>\n<p><em>Currently there is no plugin supported for <a href=\"http:\/\/coreos.com\/rkt\">rkt<\/a> containers by <a href=\"https:\/\/jenkins.io\/\">jenkins<\/a>.But I assume that the workflow will remain the same after its due implementation.<\/em><\/p>\n<h2 id=\"kubernetes-jenkins-plugin\">Kubernetes-Jenkins Plugin<\/h2>\n<p><strong>Setting up Kubernetes on Host Machine<\/strong><\/p>\n<p>Setting up <a href=\"http:\/\/kubernetes.io\/\">kubernetes<\/a> on your host machine is an easy task.In case you wish to try out on your local machine I would recommend you to try out <a href=\"http:\/\/github.com\/kubernetes\/minikube\">minikube<\/a>.In case you wish to the best of <a href=\"http:\/\/kubernetes.io\/\">kubernetes<\/a>,please refer to .Here is a quick follow up guide to get you started with setting up <a href=\"http:\/\/github.com\/kubernetes\/minikube\">minikube<\/a> on your local machine :<\/p>\n<p>An amazing work in the direction of using <a href=\"http:\/\/theremotelab.com\/blog\/achieving-ci-cd-with-k8s\/7\">jenkins<\/a> and <a href=\"http:\/\/theremotelab.com\/blog\/achieving-ci-cd-with-k8s\/11\">kubernetes<\/a> has been done by <a href=\"https:\/\/twitter.com\/carlossg\">carlossg<\/a>.He has built an awesome <a href=\"http:\/\/kubernetes.io\/\">kubernetes<\/a> plugin for <a href=\"https:\/\/jenkins.io\/\">jenkins<\/a>. Using this plugin you can easily start using <a href=\"https:\/\/jenkins.io\/\">jenkins<\/a> with <a href=\"http:\/\/kubernetes.io\/\">kubernetes<\/a> directly.Also to provide users with more easy options to configure.He has built a <a href=\"https:\/\/jenkins.io\/\">jenkins<\/a> image which by default contains the <a href=\"http:\/\/kubernetes.io\/\">kubernetes<\/a> plugin.This image is available at <a href=\"https:\/\/hub.docker.com\/r\/csanchez\/jenkins-kubernetes\/\">docker hub<\/a>.In the next steps we are going to fetch this image from docker hub and create a volume \/var\/jenkins_home for storing all your <a href=\"https:\/\/jenkins.io\/\">jenkins<\/a> data.<\/p>\n<h3 id=\"one-problem\">One Problem<\/h3>\n<p>Although we are doing everything as we planned to do.We will still run into a problem,you will notice that whenever you are about to restart your <a href=\"https:\/\/jenkins.io\/\">jenkins<\/a> container after closing it down.All your data is lost.Whatever you did like creating jobs,installing plugins etc. will be lost.This is one of the common problems with containers.Let\u2019s discuss it in a bit depth:<\/p>\n<h3 id=\"a-word-about-data-containers\">A word about Data Containers<\/h3>\n<p>Data is a tricky concept when it comes to containers.The containers are not very good example of keeping data secure and available all the time.There have been many incidents in the past where the containers have been seen to leak data.There are many ways to deal with such a problem.One is to use docker volumes.Due to some reasons,I did not found it that useful when used in terms of persistent storage.One of the ways I found to deal with persistent storage is to crete another container,called as Data Container, and use it as a source of storing data instead of depending only one image.Here\u2019s a simple figure on how we plan to use the Data Container to ensure reliability of our data,<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloud.githubusercontent.com\/assets\/8342133\/17329686\/54dab2e2-58e1-11e6-9ea8-15717dba3a2e.png\" alt=\"containers\" \/><\/p>\n<p>Here are the steps below to start using the jenkins kubernetes image,<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>\/\/Pulling down the jenkins-kubernetes image\n$ docker pull csanchez\/jenkins-kubernetes\n<\/code><\/pre>\n<\/div>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>\/\/Created a container for containing jenkins data with the image name csanchez\/jenkins-kubernetes\n$ docker create --name jenkins-k8s csanchez\/jenkins-kubernetes\n<\/code><\/pre>\n<\/div>\n<p>The above command will create and save data in a container called jenkins-k8s,which will be used whenever we wish to further use the jenkins containers with a persistent volume.<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>\/\/Running jenkins using another container containing data\n$ docker run --volumes-from jenkins-k8s -p 8080:8080 -p 50000:50000 -v \/var\/jenkins_home csanchez\/jenkins-kubernetes\n<\/code><\/pre>\n<\/div>\n<p>Open http:\/\/localhost:8080 in your browser,you should see the below screen:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloud.githubusercontent.com\/assets\/8342133\/17297438\/5a53522e-5823-11e6-8501-af049b8c2b5f.png\" alt=\"dash\" \/><\/p>\n<h3 id=\"configuring-settings-for-kubernetes-over-jenkins\">Configuring settings for Kubernetes over Jenkins<\/h3>\n<p>Now the jenkins is pre-configured with <a href=\"http:\/\/kubernetes.io\/\">kubernetes<\/a> plugin.So let\u2019s jump to the next step.Using the jenkins GUI go to <strong>Manage Jenkins<\/strong> -&gt; <strong>Configure System<\/strong> -&gt; <strong>Cloud<\/strong> -&gt; <strong>Add a new Cloud<\/strong> \u2013&gt; <strong>Kubernetes<\/strong> The screen looks like below after you have followed the above steps:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloud.githubusercontent.com\/assets\/8342133\/17297596\/02cd4bc6-5824-11e6-8ecc-2c4193f91186.png\" alt=\"k8s-config\" \/><\/p>\n<p>Now fill up your configuration settings according to the the pic below:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloud.githubusercontent.com\/assets\/8342133\/17330268\/d12382b4-58e3-11e6-9139-49f6a58c6026.png\" alt=\"k8s-jenkins5\" \/><\/p>\n<p>In case you wish to use jenkins slave you can use the jnlp-slave image on docker hub.This is a simple image that is used to set up slave node template for you.You configure a slave pod by creating a template like in the figure below,<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloud.githubusercontent.com\/assets\/8342133\/17330331\/16f93c02-58e4-11e6-8a29-e3c47cfd64c4.png\" alt=\"k8s-jenkins6\" \/><\/p>\n<p>In order to use jenkins slave on the run.While creating a new job on jenkins,do this under configure settings of your job<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloud.githubusercontent.com\/assets\/8342133\/17330427\/6fed6ac2-58e4-11e6-948a-bc9805459862.png\" alt=\"k8s-jenkins7\" \/><\/p>\n<p>Now just put the name of the label you put in <strong>kubernetes pod template<\/strong> under the restrict section.Now save and apply the settings for your new job.When build this job you should see the slave node now running after you have build up the job. That\u2019s all folks !! You are ready to go,you can now add more of your plugins as per your needs.<\/p>\n<h2 id=\"fabric8\">Fabric8<\/h2>\n<p>It is an open source microservices platform based on <a href=\"http:\/\/docker.com\/\">Docker<\/a>, <a href=\"http:\/\/kubernetes.io\/\">Kubernetes<\/a> and <a href=\"https:\/\/jenkins.io\/\">Jenkins<\/a>.It is built by the Red Hat guys.The purpose of the project is to make it easy to create microservices, build, test and deploy them via Continuous Delivery pipelines then run and manage them with Continuous Improvement and ChatOps.<\/p>\n<p>Fabric8 installs and configures the following things for you automatically<\/p>\n<ul>\n<li><a href=\"https:\/\/jenkins.io\/\">Jenkins\u200b<\/a><\/li>\n<li><a href=\"https:\/\/gogs.io\/\">Gogs\u200b<\/a><\/li>\n<li>Fabric8 registry\u200b<\/li>\n<li><a href=\"https:\/\/wiki.jenkins-ci.org\/display\/JENKINS\/Nexus+Artifact+Uploader\">Nexus\u200b<\/a><\/li>\n<li><a href=\"http:\/\/sonarqube.org\/\">SonarQube<\/a><\/li>\n<\/ul>\n<p>Here\u2019s a brief pic of the architecture of <a href=\"http:\/\/fabric8.io\/\">Fabric8<\/a><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloud.githubusercontent.com\/assets\/8342133\/17319339\/a37ae71e-58aa-11e6-9956-2562973a2bc4.png\" alt=\"screen shot 2014-11-06 at 10 07 10\" \/><\/p>\n<p>In order to get started,first you need to install the command line tool for <a href=\"http:\/\/fabric8.io\/\">fabric8<\/a> i.e. gofabric8.You can do that by downloading gofabric8 from https:\/\/github.com\/fabric8io\/gofabric8\/releases.Unzipping it and use<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>$ sudo cp \/usr\/local\/bin\/ gofabric8\n<\/code><\/pre>\n<\/div>\n<p>You can check its installation by running `$ gofabric8\u2019 on your terminal.Now run the following commands below,<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>$ gofabric8 deploy -y\n<\/code><\/pre>\n<\/div>\n<p>Your terminal screen should look like this<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloud.githubusercontent.com\/assets\/8342133\/17319676\/e272ed34-58ac-11e6-9a9d-fdd80e4971af.png\" alt=\"fabric8\" \/><\/p>\n<p>Generating Secrets<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>$ gofabric8 secrets -y\n<\/code><\/pre>\n<\/div>\n<p>Your terminal screen should look like this<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloud.githubusercontent.com\/assets\/8342133\/17319713\/2eab1ab4-58ad-11e6-8fb2-aad173854063.png\" alt=\"fabric8-2\" \/><\/p>\n<p>Check for the status of pods using kubectl<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>$ kubectl get pods\n<\/code><\/pre>\n<\/div>\n<p><img decoding=\"async\" src=\"https:\/\/cloud.githubusercontent.com\/assets\/8342133\/17319224\/d4440dd6-58a9-11e6-871e-f5db9d52ca14.png\" alt=\"jenkins-pods\" \/><\/p>\n<p>It will take a while to get all the container images to pull down and getting started.So you can go out and drink coffee \ud83d\ude42 You can use kubectl describe pods to check if something fails.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloud.githubusercontent.com\/assets\/8342133\/17319386\/def51db4-58aa-11e6-9358-659510c082d4.png\" alt=\"fabric8-4\" \/><\/p>\n<p>You can checkout the status of your pods via a opening the <a href=\"http:\/\/kubernetes.io\/\">kubernetes<\/a> dashboard in a browser:<\/p>\n<p>http:\/\/192.168.99.100:30000<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloud.githubusercontent.com\/assets\/8342133\/17319479\/882ba7f4-58ab-11e6-822c-d8c5da934ae2.png\" alt=\"fabric8-5\" \/><\/p>\n<p>Similarly you can open the <a href=\"http:\/\/fabric8.io\/\">fabric8<\/a> hawtio browser interface<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloud.githubusercontent.com\/assets\/8342133\/17319603\/62bcd1a4-58ac-11e6-90b4-4955f54d3274.png\" alt=\"fabric8-console\" \/><\/p>\n<p>From my analysis here\u2019s a depiction of what happened when you ran the above commands.Below is a simple workflow diagram for the same.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloud.githubusercontent.com\/assets\/8342133\/17319646\/ac7e9f2a-58ac-11e6-9b0c-31bb993c950c.png\" alt=\"fabric8-layout\" \/><\/p>\n<h2 id=\"achieving-cicd\">Achieving CI\/CD<\/h2>\n<p>Easier said than done,building <a href=\"https:\/\/jenkins.io\/\">jenkins<\/a> from source and integrating <a href=\"http:\/\/kubernetes.io\/\">kubernetes<\/a> is one part of the story.But achieving Continous Delivery with your setup is another very different and complex part of the story.Here are some of my tips on using certain plugins that could help you in achieving Continous Delivery with <a href=\"https:\/\/jenkins.io\/\">jenkins<\/a>:<\/p>\n<ul>\n<li><a href=\"https:\/\/jenkins.io\/solutions\/pipeline\/\">Pipeline Plugin<\/a><\/li>\n<\/ul>\n<p>This is a core plugin built by the <a href=\"https:\/\/jenkins.io\/\">jenkins<\/a> community.This plugin ensures that you can easily integrate any orchestration engine with your enviorment with very less complexity.Currently,I believe this was started as different communities had started building different plugins for various engines and they had to depend on majorly the <a href=\"https:\/\/jenkins.io\/\">Jenkins<\/a> UI part to do so.Using this plugin users now can now directly implement there project\u2019s entire build\/test\/deploy pipeline in a Jenkinsfile and store that alongside their code, treating their pipeline as another piece of code to be checked into source control<\/p>\n<ul>\n<li><a href=\"https:\/\/wiki.jenkins-ci.org\/display\/JENKINS\/GitHub+Plugin\">Github Plugin<\/a><\/li>\n<\/ul>\n<p>These days most companies are using github as SCM tool.In this case I would recommend you to use this plugin.This plugin helps you to push the code from github and analyze,test it over <a href=\"https:\/\/jenkins.io\/\">Jenkins<\/a>.For authentication purposes I would recommend you to look <a href=\"https:\/\/wiki.jenkins-ci.org\/display\/JENKINS\/GitHub+OAuth+Plugin\">Github Oauth Plugin<\/a><\/p>\n<ul>\n<li><a href=\"https:\/\/wiki.jenkins-ci.org\/display\/JENKINS\/Docker+Plugin\">Docker Plugin<\/a><\/li>\n<\/ul>\n<p>For <a href=\"http:\/\/docker.com\/\">Docker<\/a> guys this is one of the most suitable plugin that helps you do almost everything with <a href=\"http:\/\/docker.com\/\">docker<\/a>.This plugin also helps you to use <a href=\"http:\/\/docker.com\/\">docker<\/a> containers as slaves. There are several other <a href=\"http:\/\/docker.com\/\">docker<\/a> plugins that according to time and your usage you can switch over with.<\/p>\n<ul>\n<li><a href=\"https:\/\/wiki.jenkins-ci.org\/display\/JENKINS\/AWS+CodePipeline+Plugin\">AWS Pipeline<\/a><\/li>\n<\/ul>\n<p>The AWS guys have introduced an awesome service called as pipeline.This particular service helps you to attain continous delivery with your aws setup.Currently this plugin is under heavy development and might not be suitable for production enviorments.Also checkout <a href=\"https:\/\/wiki.jenkins-ci.org\/display\/JENKINS\/CodeCommit+URL+Helper\">AWS CodeCommit<\/a>.<\/p>\n<ul>\n<li><a href=\"https:\/\/wiki.jenkins-ci.org\/display\/JENKINS\/Openstack+Cloud+Plugin\">OpenStack<\/a><\/li>\n<\/ul>\n<p>For the openstack users,this plugin is suitable to configure your openstack settings with your openstack enviorment.<\/p>\n<ul>\n<li><a href=\"https:\/\/wiki.jenkins-ci.org\/display\/JENKINS\/Google+Deployment+Manager+Plugin\">Google Cloud Platform<\/a><\/li>\n<\/ul>\n<p>The deployment manager is service started by the Google Cloud platform.Using Deployment Manager,you can create flexible and declarative templates that can deploy a variety of Cloud Platform services, such as Google Cloud Storage, Google Compute Engine, Google Cloud SQL, and leave it to Deployment Manager to manage the Cloud Platform resources defined in your templates as deployments. This is a very new plugin.But I think it is worth a try if you wish to automate and sort things out with Google Cloud Platform.<\/p>\n<p>In the end,I hope you enjoyed reading this article.Please let me know your valuable thoughts in the comments section below.Regrarding the blog post above I have posted my slides below.Hope you had a fun time experimenting and have a lovely day \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hola amigos !!(In English &#8211; Hello Friends !!) Hope you are having a jolly good day ! Continous Integration\/Delivery is [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[1],"tags":[],"class_list":["post-165","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/blog.jsjs.org\/index.php?rest_route=\/wp\/v2\/posts\/165","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.jsjs.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.jsjs.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.jsjs.org\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.jsjs.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=165"}],"version-history":[{"count":0,"href":"https:\/\/blog.jsjs.org\/index.php?rest_route=\/wp\/v2\/posts\/165\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.jsjs.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=165"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jsjs.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=165"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jsjs.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=165"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}