1"use strict";(globalThis.webpackChunkweb_opencost=globalThis.webpackChunkweb_opencost||[]).push([[344],{2447(e,t,o){o.d(t,{A:()=>n});const n=o.p+"assets/images/screenshot-e18d519e0cfd37c4051b78db7c4324ff.png"},7233(e,t,o){o.r(t),o.d(t,{assets:()=>l,contentTitle:()=>c,default:()=>d,frontMatter:()=>r,metadata:()=>n,toc:()=>a});var n=o(9748),s=o(4848),i=o(8453);const r={slug:"k8sless-opencost",title:"Cloud Costs Monitoring in Docker",authors:["mattray"],tags:["opencost","docker","cloud costs","integrations"]},c=void 0,l={authorsImageUrls:[void 0]},a=[{value:"Running OpenCost without Kubernetes",id:"running-opencost-without-kubernetes",level:2},{value:"Running with Docker",id:"running-with-docker",level:3},{value:"Building and Running from the CLI",id:"building-and-running-from-the-cli",level:3},{value:"Accessing the Cloud Costs API",id:"accessing-the-cloud-costs-api",level:2},{value:"Using the OpenCost UI from Docker",id:"using-the-opencost-ui-from-docker",level:2},{value:"Walkthrough",id:"walkthrough",level:2},{value:"Code Changes",id:"code-changes",level:2},{value:"Next Steps",id:"next-steps",level:2}];function h(e){const t={a:"a",code:"code",h2:"h2",h3:"h3",img:"img",li:"li",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.a,{href:"https://opencost.io",children:"OpenCost"})," is an open source implementation for Kubernetes cost monitoring and now cloud cost monitoring for AWS, Azure, and GCP.\nThe project makes all of this data accessible via an API and user interface.\nWhile discussing the idea of running OpenCost on platforms besides Kubernetes we realized that with this new ",(0,s.jsx)(t.a,{href:"https://www.opencost.io/blog/cloud-costs",children:"Cloud Costs feature"})," there are users who want API access to their cloud billing data without needing to run on Kubernetes.\nI opened the Issue ",(0,s.jsx)(t.a,{href:"https://github.com/opencost/opencost/issues/2268",children:"OpenCost without Kubernetes #2268"})," and as luck would have it, we had our internal Hackathon last week."]}),"\n",(0,s.jsxs)(t.p,{children:["If you're not familiar with ",(0,s.jsx)(t.a,{href:"https://opencost.io",children:"OpenCost"}),", it's the open source CNCF project for monitoring Kubernetes and cloud spending.\nIt's a Golang implementation of the ",(0,s.jsx)(t.a,{href:"https://www.opencost.io/docs/specification",children:"OpenCost Specification"})," for monitoring Kubernetes cloud costs.\nIt has an optional web UI and you can also run it as a Prometheus metrics exporter.\nThe code is all at ",(0,s.jsx)(t.a,{href:"https://github.com/opencost/opencost",children:"https://github.com/opencost/opencost"})," and you can learn more about the project at ",(0,s.jsx)(t.a,{href:"https://opencost.io",children:"https://opencost.io"})]}),"\n",(0,s.jsx)(t.h2,{id:"running-opencost-without-kubernetes",children:"Running OpenCost without Kubernetes"}),"\n",(0,s.jsx)(t.p,{children:"Given that not everyone who wants to look at their cloud billing is using Kubernetes, to run without Kubernetes you can either run from Docker or directly from the CLI. There are 3 environment variables you'll need to set:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"KUBERNETES_ENABLED=false"})," (default is ",(0,s.jsx)(t.code,{children:"true"}),")"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"CLOUD_COST_ENABLED=true"})," (default is ",(0,s.jsx)(t.code,{children:"false"})," since it's beta)"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"CLOUD_COST_CONFIG_PATH=/path/to/file"})," - you'll need to ",(0,s.jsx)(t.a,{href:"https://www.opencost.io/docs/configuration/",children:"provide your credentials"})," in a file (default is ",(0,s.jsx)(t.code,{children:"cloud-integration.json"}),"). ",(0,s.jsx)(t.a,{href:"https://gist.github.com/mattray/090a43aa4e64f8fc78572cd8d504a4b7",children:"Here\u2019s an example file"}),"."]}),"\n"]}),"\n",(0,s.jsx)(t.h3,{id:"running-with-docker",children:"Running with Docker"}),"\n",(0,s.jsxs)(t.p,{children:["If you want to run with Docker, you can pull down the image from ",(0,s.jsxs)(t.a,{href:"https://hub.docker.com/repository/docker/mattray/opencost/tags",children:["docker.io/mattray/opencost",":k8sless"]})," (or build it yourself)."]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.code,{children:"docker pull mattray/opencost:k8sless"})}),"\n",(0,s.jsx)(t.p,{children:"and run it with"}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.code,{children:"docker run -e KUBERNETES_ENABLED=false -e CLOUD_COST_ENABLED=true -e CLOUD_COST_CONFIG_PATH=/tmp/cloud-integration.json -p 9003
1:9003 -d -v /tmp:/tmp mattray/opencost:k8sless"})}),"\n",(0,s.jsx)(t.h3,{id:"building-and-running-from-the-cli",children:"Building and Running from the CLI"}),"\n",(0,s.jsxs)(t.p,{children:["You can ",(0,s.jsx)(t.a,{href:"https://github.com/mattray/opencost/tree/cloudclost-k8sless",children:"check out the code"})," and run ",(0,s.jsx)(t.code,{children:"make"})," to build."]}),"\n",(0,s.jsx)(t.p,{children:"To test it, run:"}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.code,{children:"KUBERNETES_ENABLED=false CLOUD_COST_ENABLED=true CLOUD_COST_CONFIG_PATH='cloud-costs.json' ./costmodel"})}),"\n",(0,s.jsx)(t.h2,{id:"accessing-the-cloud-costs-api",children:"Accessing the Cloud Costs API"}),"\n",(0,s.jsxs)(t.p,{children:["The OpenCost ",(0,s.jsx)(t.a,{href:"https://www.opencost.io/docs/integrations/api#cloudcost",children:"Cloud Cost API"})," is exposed on port 9003, you test with"]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.code,{children:"curl -G http://localhost:9003/cloudCost -d window=7d -d aggregate=provider | jq"})}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.a,{href:"https://www.opencost.io/docs/integrations/api#cloudcost",children:"Cloud Cost API"})," provides the available query parameters and the ",(0,s.jsx)(t.a,{href:"https://www.opencost.io/docs/integrations/api-examples#cloudcost-examples",children:"API Examples"})," show how you could query the Services by your Provider or how to get billing items over a range of time. There are more Cloud Cost API endpoints available in the code, the documentation hasn\u2019t kept up with all the new options so far."]}),"\n",(0,s.jsx)(t.h2,{id:"using-the-opencost-ui-from-docker",children:"Using the OpenCost UI from Docker"}),"\n",(0,s.jsx)(t.p,{children:"The OpenCost UI for Cloud Costs is still under development, but you can grab the beta build with"}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.code,{children:"docker pull mattray/opencost-ui:docker-ui"})}),"\n",(0,s.jsx)(t.p,{children:"and run it from Docker without Kubernetes:"}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.code,{children:"docker run -p 9090:9090 -d mattray/opencost-ui:docker-ui"})}),"\n",(0,s.jsxs)(t.p,{children:["Go to ",(0,s.jsx)(t.a,{href:"http://localhost:9090/cloud",children:"http://localhost:9090/cloud"})," to check it out. The ",(0,s.jsx)(t.strong,{children:"Cost Allocation"})," tab will be empty because there\u2019s no Kubernetes data, but the ",(0,s.jsx)(t.strong,{children:"Cloud Costs"})," should have whatever clouds you\u2019ve configured access."]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.a,{target:"_blank","data-noBrokenLinkCheck":!0,href:o(9846).A+"",children:(0,s.jsx)(t.img,{alt:"OpenCost Cloud Costs",src:o(2447).A+"",width:"3104",height:"2024"})})}),"\n",(0,s.jsxs)(t.p,{children:["The OpenCost UI already works for local development, you can find instructions ",(0,s.jsx)(t.a,{href:"https://github.com/opencost/opencost/tree/develop/ui#running-locally",children:"here"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"walkthrough",children:"Walkthrough"}),"\n",(0,s.jsx)(t.p,{children:"If you\u2019d rather just see a quick demo, I\u2019ve recorded a screencast walking through the above steps and connecting with the UI."}),"\n",(0,s.jsx)("iframe",{width:"840",height:"472",src:"https://www.youtube.com/embed/rEBaOaHqrK4?si=-mR5lfC9aYHkhPR2",title:"OpenCost Cloud Costs with Docker",frameborder:"1",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share",allowfullscreen:!0}),"\n",(0,s.jsx)(t.h2,{id:"code-changes",children:"Code Changes"}),"\n",(0,s.jsxs)(t.p,{children:["This should get merged soon, but if you want to work with the branch it\u2019s available here: ",(0,s.jsx)(t.a,{href:"https://github.com/mattray/opencost/tree/cloudclost-k8sless",children:"https://github.com/mattray/opencost/tree/cloudclost-k8sless"})," (",(0,s.jsx)(t.a,{href:"https://github.com/opencost/opencost/blob/develop/CONTRIBUTING.md#building-opencost",children:"build instructions"}),"). The OpenCost PR is here: ",(0,s.jsx)(t.a,{href:"https://github.com/opencost/opencost/pull/2317",children:"opencost/opencost#2317"})]}),"\n",(0,s.jsx)(t.p,{children:"I tested on MacOS with Docker (and EKS, K3s, and Kind for regression-checking), but it probably would work on any Unix-compatible platform (Windows?)."}),"\n",(0,s.jsx)(t.h2,{id:"next-steps",children:"Next Steps"}),"\n",(0,s.jsxs)(t.p,{children:["I think there are a lot of use cases we're not aware of yet and hopefully this will get more folks
1interested in the project. We'll continue expanding documentation on the ",(0,s.jsx)(t.a,{href:"https://www.opencost.io/docs/integrations/api#cloudcost",children:"Cloud Costs API"})," and providing more ",(0,s.jsx)(t.a,{href:"https://www.opencost.io/docs/integrations/api-examples#cloudcost-examples",children:"examples"})," as it continues to mature. If you're involved in ",(0,s.jsx)(t.a,{href:"https://www.finops.org",children:"FinOps"})," we'll be adding support for the upcoming ",(0,s.jsx)(t.a,{href:"https://focus.finops.org",children:"FOCUS specification"})," for standardized billing, so that will make this even more compelling. Let me know what you think, looking forward to any feedback on how to get cloud billing data available in useful formats to even more people."]}),"\n",(0,s.jsxs)(t.p,{children:["If you have any questions, email us at ",(0,s.jsx)(t.a,{href:"mailto:[email protected]",children:"[email protected]"}),", join us in ",(0,s.jsx)(t.a,{href:"https://slack.cncf.io",children:"CNCF #opencost Slack"}),", or check out the ",(0,s.jsx)(t.a,{href:"https://www.opencost.io/docs/community",children:"OpenCost Community page"}),"."]})]})}function d(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},8453(e,t,o){o.d(t,{R:()=>r,x:()=>c});var n=o(6540);const s={},i=n.createContext(s);function r(e){const t=n.useContext(i);return n.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),n.createElement(i.Provider,{value:t},e.children)}},9748(e){e.exports=JSON.parse('{"permalink":"/blog/k8sless-opencost","source":"@site/blog/2023-11-21-opencost-k8sless/index.mdx","title":"Cloud Costs Monitoring in Docker","description":"OpenCost is an open source implementation for Kubernetes cost monitoring and now cloud cost monitoring for AWS, Azure, and GCP.","date":"2023-11-21T00:00:00.000Z","tags":[{"inline":true,"label":"opencost","permalink":"/blog/tags/opencost"},{"inline":true,"label":"docker","permalink":"/blog/tags/docker"},{"inline":true,"label":"cloud costs","permalink":"/blog/tags/cloud-costs"},{"inline":true,"label":"integrations","permalink":"/blog/tags/integrations"}],"readingTime":4.31,"hasTruncateMarker":true,"authors":[{"name":"Matt Ray","title":"OpenCost Community Manager @ Kubecost","url":"https://github.com/mattray","imageURL":"https://github.com/mattray.png","key":"mattray","page":null}],"frontMatter":{"slug":"k8sless-opencost","title":"Cloud Costs Monitoring in Docker","authors":["mattray"],"tags":["opencost","docker","cloud costs","integrations"]},"unlisted":false,"prevItem":{"title":"OpenCost Exporter is now in the Prometheus Community Helm Charts","permalink":"/blog/prometheus-opencost-exporter"},"nextItem":{"title":"Announcing OpenCost Integration with Microsoft AKS Cost Analysis","permalink":"/blog/aks-cost-analysis"}}')},9846(e,t,o){o.d(t,{A:()=>n});const n=o.p+"assets/files/screenshot-e18d519e0cfd37c4051b78db7c4324ff.png"}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.