PageSourceSearch

https://www.parca.dev/docs/assets/js/d1263c4e.562c9b86.js

js parca.dev collected 2026-10-03 21:33:09 UTC 14,713 bytes, 1 lines download raw bytes

1"use strict";(globalThis.webpackChunkparca_dev=globalThis.webpackChunkparca_dev||[]).push([[85],{6889(e,a,n){n.d(a,{A:()=>d});var t=n(6540);const r="browserWindow_my1Q",o="browserWindowHeader_jXSR",i="buttons_uHc7",s="browserWindowAddressBar_Pd8y",l="dot_giz1",p="browserWindowMenuIcon_Vhuh",c="bar_rrRL",g="browserWindowBody_Idgs";const d=function({children:e,minHeight:a,url:n}){return t.createElement("div",{className:r,style:{minHeight:a}},t.createElement("div",{className:o},t.createElement("div",{className:i},t.createElement("span",{className:l,style:{background:"#f25f58"}}),t.createElement("span",{className:l,style:{background:"#fbbe3c"}}),t.createElement("span",{className:l,style:{background:"#58cb42"}})),t.createElement("div",{className:s},n),t.createElement("div",{className:p},t.createElement("div",null,t.createElement("span",{className:c}),t.createElement("span",{className:c}),t.createElement("span",{className:c})))),t.createElement("div",{className:g},e))}},8990(e,a,n){n.d(a,{A:()=>i});var t=n(6540),r=n(6588);const o=t.createContext(),i=({children:e,language:a})=>{const{versions:n}=(0,r.P_)("docusaurus-github-releases-plugin");return t.createElement(o.Provider,{value:n},t.createElement(o.Consumer,null,e))}},3918(e,a,n){n.r(a),n.d(a,{assets:()=>g,contentTitle:()=>p,default:()=>m,frontMatter:()=>l,metadata:()=>c,toc:()=>d});var t=n(8168),r=(n(6540),n(5680)),o=n(8990),i=n(2355),s=n(6889);const l={},p="OpenShift",c={unversionedId:"openshift",id:"openshift",title:"OpenShift",description:"You can find interactive version of this tutorial at our Katacoda account. Check it out here.",source:"@site/docs/openshift.mdx",sourceDirName:".",slug:"/openshift",permalink:"/docs/openshift",draft:!1,editUrl:"https://github.com/parca-dev/parca.dev/edit/main/docs/openshift.mdx",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Kubernetes",permalink:"/docs/kubernetes"},next:{title:"Querying Parca",permalink:"/docs/querying-parca"}},g={},d=[{value:"Setting up Parca Server",id:"setting-up-parca-server",level:2},{value:"Setting up Parca Agent",id:"setting-up-parca-agent",level:2},{value:"Exploring the collected data",id:"exploring-the-collected-data",level:2},{value:"Selecting a subset of applications to profile",id:"selecting-a-subset-of-applications-to-profile",level:3}],u={toc:d};function m({components:e,...a}){return(0,r.yg)("wrapper",(0,t.A)({},u,a,{components:e,mdxType:"MDXLayout"}),(0,r.yg)("h1",{id:"openshift"},"OpenShift"),(0,r.yg)("admonition",{type:"tip"},(0,r.yg)("p",{parentName:"admonition"},"You can find interactive version of this tutorial at our Katacoda account. Check it out ",(0,r.yg)("a",{parentName:"p",href:"https://www.katacoda.com/parca/scenarios/openshift"},"here"),".")),(0,r.yg)("admonition",{type:"tip"},(0,r.yg)("p",{parentName:"admonition"},"To quickly try out the Parca and Parca Agent with OpenShift cluster or a local cluster with ",(0,r.yg)("a",{parentName:"p",href:"https://developers.redhat.com/products/codeready-containers/overview"},"Red Hat CodeReady Containers"),"."),(0,r.yg)("pre",{parentName:"admonition"},(0,r.yg)("code",{parentName:"pre",className:"language-shell"},"crc setup\ncrc start\n"))),(0,r.yg)("admonition",{type:"note"},(0,r.yg)("p",{parentName:"admonition"},"The Agent needs to access to Kernel and run as a privileged user to load necessary eBPF programs. Please check ",(0,r.yg)("a",{parentName:"p",href:"/docs/faq#since-parca-agent-has-to-run-as-root-for-ebpf-what-are-the-security-considerations"},"our FAQ for further information"),".")),(0,r.yg)("h2",{id:"setting-up-parca-server"},"Setting up Parca Server"),(0,r.yg)("p",null,"Start by creating a project for Parca components to run in."),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre",className:"language-shell"},'oc new-project parca \\\n    --description="Parca Continuous Profiling" --display-name="Parca Continuous Profiling"\n')),(0,r.yg)("p",null,"To provision the Parca against any OpenShift cluster, and use the API and UI:"),(0,r.yg)(o.A,{language:"bash",mdxType:"WithVersions"},e=>
1(0,r.yg)(i.A,{className:"language-bash",mdxType:"CodeBlock"},"oc apply -f https://github.com/parca-dev/parca/releases/download/",e.server,"/openshift-manifest.yaml")),(0,r.yg)("p",null,"You can verify by selecting pods if everything runs as expected:"),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre",className:"language-shell"},"oc get pods -A\n")),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre",className:"language-shell"},"oc get pods -A\n\nNAMESPACE     NAME                            READY   STATUS    RESTARTS   AGE\nkube-system   coredns-78fcd69978-pwjv7        1/1     Running   0          59m\nkube-system   etcd-parca                      1/1     Running   0          59m\nkube-system   kube-apiserver-parca            1/1     Running   0          59m\nkube-system   kube-controller-manager-parca   1/1     Running   0          59m\nkube-system   kube-proxy-qvv2b                1/1     Running   0          59m\nkube-system   kube-scheduler-parca            1/1     Running   0          59m\nkube-system   storage-provisioner             1/1     Running   0          59m\nparca         parca-5f879c46ff-pv649          1/1     Running   0          53m\n")),(0,r.yg)("p",null,"To view the Parca UI and access the API, we can port-forward using the default port ",(0,r.yg)("inlineCode",{parentName:"p"},"7070"),":"),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre"},"oc -n parca port-forward service/parca 7070\n")),(0,r.yg)("p",null,"Once the Parca is running, and you set up the port-forwarding. Now you can navigate through to the web interface on the browser by visiting visit ",(0,r.yg)("inlineCode",{parentName:"p"},"http://localhost:7070"),"."),(0,r.yg)("p",null,"However, at this stage, you shouldn't see any data. Parca hasn't ingested any data because we haven't configured any data source."),(0,r.yg)("p",null,"So let's set up Parca Agent in our cluster and collect data from our cluster."),(0,r.yg)("h2",{id:"setting-up-parca-agent"},"Setting up Parca Agent"),(0,r.yg)("p",null,"First, let's make sure we have the OpenShift project that we are going to use (if you haven't already done this in the previous step):"),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre",className:"language-shell"},'oc new-project parca \\\n    --description="Parca Continuous Profiling" --display-name="Parca Continuous Profiling"\n')),(0,r.yg)("p",null,"To provision the Parca Agent as a ",(0,r.yg)("inlineCode",{parentName:"p"},"DaemonSet"),":"),(0,r.yg)(o.A,{language:"bash",mdxType:"WithVersions"},e=>(0,r.yg)(i.A,{className:"language-bash",mdxType:"CodeBlock"},"oc apply -f https://github.com/parca-dev/parca-agent/releases/download/",e.agent,"/openshift-manifest.yaml")),(0,r.yg)("p",null,"You can verify by selecting pods if everything runs as expected:"),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre",className:"language-shell"},"oc get pods -n parca\n\nNAME                        READY   STATUS    RESTARTS   AGE\nparca-5f879c46ff-pv649      1/1     Running   0          54m\nparca-agent-b66vt           1/1     Running   0          54m\n")),(0,r.yg)("p",null,"Let's set up a port-forward using the default port ",(0,r.yg)("inlineCode",{parentName:"p"},"7071"),"."),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre"},'oc -n parca port-forward `oc -n parca get pod -lapp.kubernetes.io/name=parca-agent -ojsonpath="{.items[0].metadata.name}"` 7071\n')),(0,r.yg)("p",null,"Now we can view the active profilers by visiting ",(0,r.yg)("inlineCode",{parentName:"p"},"http://localhost:7071"),":"),(0,r.yg)(s.A,{mdxType:"BrowserWindow"},(0,r.yg)("p",null,(0,r.yg)("img",{alt:"image",src:n(196).A,width:"3362",height:"1032"}))),(0,r.yg)("br",null),(0,r.yg)("p",null,"And all the discovered processes:"),(0,r.yg)(s.A,{mdxType:"BrowserWindow"},(0,r.yg)("p",null,(0,r.yg)("img",{alt:"image",src:n(6906).A,width:"3598",height:"2018"}))),(0,r.yg)("br",null),(0,r.yg)("p",null,"To continuously send every profile collected to a Parca server the configure the ",(0,r.yg)("inlineCode",{parentName:"p"},"--store-address")," and the potential credentials needed.\nFor example, to send to a Parca server in the ",(0,r.yg)("inlineCode",{parentName:"p"},"parca")," namespace set: ",(0,r.yg)("inlineCode",{parentName:"p"},"--store-address=parca.parca.svc:7070"),".\nThis has already been set up for our current setup in the previously applied manifests."),(0,r.yg)("admonition",{type:"tip"},(0,r.yg)("p",{parentName:"admonition"},"You can use ",(0,r.yg)("inlineCode",{parentName:"p"},"--remote-store-insecure")," and ",(0,r.yg)("inlineCode",{parentName:"p"},"--remote-store-insecure-skip-verify")," for simpler setups."),(0,r.yg)("pre",{parentName:"admonition"},(0,r.yg)("code",{parentName:"pre",className:"language-shell"},"      --remote-store-insecure     Send gRPC requests via plaintext instead of\n                                  TLS.\n      --remote-store-insecure-skip-verify\n                                  Skip TLS certificate verification.\n"))),(0,r.yg)("h2",{id:"exploring-the-collected-data"},"Exploring the collected data"),(0,r.yg)("p",null,"Once Parca and Parca Agent are both running, you can navigate to the web interface on the browser.\nYou should shortly see the ",(0,r.yg)("inlineCode",{parentName:"p"},"Select profile...")," dropdown menu populate with the profiles that Parca is retrieving from itself and receiving from the Agent."),(0,r.yg)("admonition",{type:"info"},(0,r.yg)("p",{parentName:"admonition"},"Parca supports any pprof formatted profile, but here we are demonstrating Parca Agent's automatic profiling with zero-instrumentation, which currently only supports CPU profiling.")),(0,r.yg)(s.A,{mdxType:"BrowserWindow"},(0,r.yg)("p",null,(0,r.yg)("img",{alt:"image",src:n(7795).A,width:"3598",height:"1490"}))),(0,r.yg)("br",null),(0,r.yg)("p",null,"Selecting ",(0,r.yg)("inlineCode",{parentName:"p"},"CPU Samples")," as profile type and clicking the ",(0,r.yg)("inlineCode",{parentName:"p"},"Search")," button will retrieve the profiles from Parca Agent for the time selection (default Last Hour)."),(0,r.yg)("p",null,"This should result in a time series based on the profile that is interactable.\nClicking anywhere on the line graph should then bring up a Flame Graph for the profile that you've selected."),(0,r.yg)(s.A,{mdxType:"BrowserWindow"},(0,r.yg)("p",null,(0,r.yg)("img",{alt:"image",src:n(3371).A,width:"3596",height:"2012"}))),(0,r.yg)("br",null),(0,r.yg)("p",null,"You can then interact with the Flame Graph to better understand how Parca is behaving."),(0,r.yg)("admonition",{type:"info"},(0,r.yg)("p",{parentName:"admonition"},"One of the cool features of Parca Agent is by default it discovers all the containers run on the nodes that it's been deployed.\nSo out of the box you should be seeing all the system containers running on the system.\nIf you go to query bar and enter ",(0,r.yg)("inlineCode",{parentName:"p"},'namespace="kube-system"')," you can focus on them.")),(0,r.yg)(s.A,{mdxType:"BrowserWindow"},(0,r.yg)("p",null,(0,r.yg)("img",{alt:"image",src:n(4027).A,width:"3356",height:"1252"}))),(0,r.yg)("br",null),(0,r.yg)("p",null,"And you can click the samples on the graph to focus on the individual profiles."),(0,r.yg)(s.A,{mdxType:"BrowserWindow"},(0,r.yg)("p",null,(0,r.yg)("img",{alt:"image",src:n(2498).A,width:"3358",height:"1876"}))),(0,r.yg)("h3",{id:"selecting-a-subset-of-applications-to-profile"},"Selecting a subset of applications to profile"),(0,r.yg)("p",null,"Metadata discovery mechanism enriches the collected profiles with Kubernetes labels. You can use relabelling feature of the Parca Agent to drop a subset of labels.\nAgent utilizes the exact same labelling mechanism Prometheus provides."),
1(0,r.yg)("admonition",{type:"tip"},(0,r.yg)("p",{parentName:"admonition"},"To learn more about relabelling please see the ",(0,r.yg)("a",{parentName:"p",href:"https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config"},"Prometheus ",(0,r.yg)("inlineCode",{parentName:"a"},"relabel_config")," documentation"),".")),(0,r.yg)("p",null,"First you need to specify a configuration file if you haven't already. The relevant manifest changes on ",(0,r.yg)("inlineCode",{parentName:"p"},"parca-agent-daemonSet.yaml")," would like the following:"),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre",className:"language-diff"},"...\ntemplate:\n  metadata:\n    labels:\n      app.kubernetes.io/component: observability\n      app.kubernetes.io/instance: parca-agent\n      app.kubernetes.io/name: parca-agent\n  spec:\n    containers:\n    - args:\n      - /bin/parca-agent\n      - --log-level=info\n      - --node=$(NODE_NAME)\n      - --remote-store-address=parca.parca.svc.cluster.local:7070\n      - --remote-store-insecure\n      - --remote-store-insecure-skip-verify\n+     - --config-path=/etc/parca-agent.yaml\n      - --temp-dir=/tmp\n...\n")),(0,r.yg)("admonition",{type:"info"},(0,r.yg)("p",{parentName:"admonition"},"For brevity, we skip the details of mounting a ",(0,r.yg)("inlineCode",{parentName:"p"},"ConfigMap")," with relevant content to ",(0,r.yg)("inlineCode",{parentName:"p"},"/etc/parca-agent.yaml")," location.")),(0,r.yg)("p",null,"For example, to only profile Pods with the ",(0,r.yg)("inlineCode",{parentName:"p"},"app.kubernetes.io/name=my-web-app")," label, the relevant configuration file ",(0,r.yg)("inlineCode",{parentName:"p"},"/etc/parca-agent.yaml")," would like the following:"),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre",className:"language-yaml"},"relabel_configs:\n  - source_labels: [app_kubernetes_io_name]\n    regex: my-web-app\n    action: keep\n")),(0,r.yg)("admonition",{type:"tip"},(0,r.yg)("p",{parentName:"admonition"},"Pay attention to how label names are sanitized. ",(0,r.yg)("inlineCode",{parentName:"p"},"app.kubernetes.io/name")," becomes ",(0,r.yg)("inlineCode",{parentName:"p"},"app_kubernetes_io_name"))))}m.isMDXComponent=!0},196(e,a,n){n.d(a,{A:()=>t});const t=n.p+"assets/images/active_profilers-176351c6b1b3e52cebd03c03cb68d0cb.png"},3371(e,a,n){n.d(a,{A:()=>t});const t=n.p+"assets/images/cpu_sample_count_select-5e50ba6fa773c88480093aaae7798eab.png"},6906(e,a,n){n.d(a,{A:()=>t});const t=n.p+"assets/images/processes-96e91028bf4fea9fe5fa6fe45e2e5c57.png"},7795(e,a,n){n.d(a,{A:()=>t});const t=n.p+"assets/images/profile_type_dropdown_selected-7cd8129d09c81b6f9a176644703c184b.png"},2498(e,a,n){n.d(a,{A:()=>t});const t=n.p+"assets/images/query_kube_controller_manager-4e1399f48c12d32f00ebaf5b25763381.png"},4027(e,a,n){n.d(a,{A:()=>t});const t=n.p+"assets/images/query_range_kube_system-2a7f545d37ff59e0566f765770f9bfff.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.