<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Injecting faults with xk6-disruptor on Grafana Labs</title><link>https://grafana.com/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/</link><description>Recent content in Injecting faults with xk6-disruptor on Grafana Labs</description><generator>Hugo -- gohugo.io</generator><language>en</language><atom:link href="/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/index.xml" rel="self" type="application/rss+xml"/><item><title>xk6-disruptor first steps</title><link>https://grafana.com/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/first-steps/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/first-steps/</guid><content><![CDATA[&lt;h1 id=&#34;xk6-disruptor-first-steps&#34;&gt;xk6-disruptor first steps&lt;/h1&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/grafana/xk6-disruptor&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;xk6-disruptor&lt;/a&gt; is an extension that adds fault injection capabilities to k6.&lt;/p&gt;
&lt;p&gt;It provides a Javascript 
    &lt;a href=&#34;/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/xk6-disruptor/&#34;&gt;API&lt;/a&gt; to inject 
    &lt;a href=&#34;/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/xk6-disruptor/faults/&#34;&gt;faults&lt;/a&gt; such as errors and delays into HTTP and gRPC requests served by selected Kubernetes 
    &lt;a href=&#34;/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/xk6-disruptor/poddisruptor/&#34;&gt;Pods&lt;/a&gt; or 
    &lt;a href=&#34;/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/xk6-disruptor/servicedisruptor/&#34;&gt;Services&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import { ServiceDisruptor } from &amp;#39;k6/x/disruptor&amp;#39;;

export default function () {
  // Create a new disruptor that targets a service
  const disruptor = new ServiceDisruptor(&amp;#39;app-service&amp;#39;, &amp;#39;app-namespace&amp;#39;);

  // Disrupt the targets by injecting delays and faults into HTTP request for 30 seconds
  const fault = {
    averageDelay: &amp;#39;500ms&amp;#39;,
    errorRate: 0.1,
    errorCode: 500,
  };
  disruptor.injectHTTPFaults(fault, &amp;#39;30s&amp;#39;);
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;next-steps&#34;&gt;Next steps&lt;/h2&gt;
&lt;p&gt;Explore the fault injection 
    &lt;a href=&#34;/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/xk6-disruptor/&#34;&gt;API&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;See 
    &lt;a href=&#34;/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/examples/&#34;&gt;step-by-step examples&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Visit the &lt;a href=&#34;https://killercoda.com/grafana-xk6-disruptor/scenario/killercoda&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;interactive demo environment&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Learn the basics of using the disruptor in your test project:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
    &lt;a href=&#34;/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/requirements/&#34;&gt;Requirements&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
    &lt;a href=&#34;/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/installation/&#34;&gt;Installation&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
]]></content><description>&lt;h1 id="xk6-disruptor-first-steps">xk6-disruptor first steps&lt;/h1>
&lt;p>&lt;a href="https://github.com/grafana/xk6-disruptor" target="_blank" rel="noopener noreferrer">xk6-disruptor&lt;/a> is an extension that adds fault injection capabilities to k6.&lt;/p>
&lt;p>It provides a Javascript
&lt;a href="/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/xk6-disruptor/">API&lt;/a> to inject
&lt;a href="/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/xk6-disruptor/faults/">faults&lt;/a> such as errors and delays into HTTP and gRPC requests served by selected Kubernetes
&lt;a href="/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/xk6-disruptor/poddisruptor/">Pods&lt;/a> or
&lt;a href="/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/xk6-disruptor/servicedisruptor/">Services&lt;/a>.&lt;/p></description></item><item><title>Requirements</title><link>https://grafana.com/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/requirements/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/requirements/</guid><content><![CDATA[&lt;h1 id=&#34;requirements&#34;&gt;Requirements&lt;/h1&gt;
&lt;p&gt;The xk6-disruptor is a k6 extension.
To use it in a k6 test script, you need to bundle a k6 extension that includes the disruptor.
Refer to the 
    &lt;a href=&#34;/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/installation/&#34;&gt;Installation&lt;/a&gt; section for instructions on how to get this custom build.&lt;/p&gt;
&lt;p&gt;xk6-disruptor needs to interact with the Kubernetes cluster on which the application under test is running.
To do so, you must have the credentials to access the cluster in a &lt;a href=&#34;https://kubernetes.io/docs/tasks/access-application-cluster/configure-access-multiple-clusters/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;kubeconfig&lt;/a&gt; file.
Ensure that this file is pointed to by the &lt;code&gt;KUBECONFIG&lt;/code&gt; environment variable or that it is located at the default location, &lt;code&gt;$HOME/.kube/config&lt;/code&gt;.&lt;/p&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;xk6-disruptor requires Kubernetes version 1.23 or higher&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;xk6-disruptor&lt;/code&gt; requires the &lt;a href=&#34;https://github.com/grafana/xk6-disruptor/pkgs/container/xk6-disruptor-agent&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;grafana/xk6-disruptor-agent&lt;/a&gt; image for injecting the 
    &lt;a href=&#34;/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/how--it-works/&#34;&gt;disruptor agent&lt;/a&gt; into the disruption targets. Kubernetes clusters can be configured to restrict the download of images from public repositories. You need to ensure this image is available in the cluster where the application under test is running. Additionally, the xk6-disruptor-agent must run with network access privileges. Kubernetes clusters &lt;a href=&#34;https://kubernetes.io/docs/concepts/security/pod-security-admission/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;can be configured to restrict the privileges of containers&lt;/a&gt;.
If you find an error similar to the following when using the xk6-disruptor, contact your cluster administrator and request the necessary privileges.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;ERROR[0000] error creating PodDisruptor: pods &amp;ldquo;nginx&amp;rdquo; is forbidden: violates PodSecurity &amp;ldquo;baseline:latest&amp;rdquo;: non-default capabilities (container &amp;ldquo;xk6-agent&amp;rdquo; must not include &amp;ldquo;NET_ADMIN&amp;rdquo;, &amp;ldquo;NET_RAW&amp;rdquo; in securityContext.capabilities.add)&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;You also need to ensure your test application is accessible from the machine where the tests run.
Refer to 
    &lt;a href=&#34;/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/expose--your-application/&#34;&gt;Expose your application&lt;/a&gt; section for instructions on how to make your application available from outside the Kubernetes cluster.&lt;/p&gt;
]]></content><description>&lt;h1 id="requirements">Requirements&lt;/h1>
&lt;p>The xk6-disruptor is a k6 extension.
To use it in a k6 test script, you need to bundle a k6 extension that includes the disruptor.
Refer to the
&lt;a href="/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/installation/">Installation&lt;/a> section for instructions on how to get this custom build.&lt;/p></description></item><item><title>Installation</title><link>https://grafana.com/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/installation/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/installation/</guid><content><![CDATA[&lt;h1 id=&#34;installation&#34;&gt;Installation&lt;/h1&gt;
&lt;p&gt;xk6-disruptor is a 
    &lt;a href=&#34;/docs/k6/v2.3.x/extensions/&#34;&gt;k6 extension&lt;/a&gt;. You have to run a k6 version built with the disruptor extension to use the 
    &lt;a href=&#34;/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/xk6-disruptor/&#34;&gt;disruptor APIs&lt;/a&gt; in your k6 tests.&lt;/p&gt;
&lt;p&gt;The following sections explain the different options to get this custom binary.&lt;/p&gt;
&lt;h2 id=&#34;download-a-release-binary&#34;&gt;Download a release binary&lt;/h2&gt;
&lt;p&gt;The quickest way to get started is to &lt;a href=&#34;https://github.com/grafana/xk6-disruptor/releases&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;download a release binary from GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;build-from-source&#34;&gt;Build from source&lt;/h2&gt;
&lt;p&gt;You can also use &lt;a href=&#34;https://github.com/grafana/xk6&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;xk6&lt;/a&gt; to build a k6 binary.&lt;/p&gt;
&lt;p&gt;To learn more about xk6, refer to 
    &lt;a href=&#34;/docs/k6/v2.3.x/extensions/build-k6-binary-using-go/&#34;&gt;Build a k6 binary using Go&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To build the k6 binary with the xk6-disruptor extension:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Ensure you have &lt;a href=&#34;https://golang.org/doc/install&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Go 1.19&lt;/a&gt; and &lt;a href=&#34;https://git-scm.com/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Git&lt;/a&gt; installed.&lt;/li&gt;
&lt;li&gt;Run the following commands in a terminal:&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;# Install xk6
go install go.k6.io/xk6/cmd/xk6@latest

# Clone the xk6-disruptor code
git clone https://github.com/grafana/xk6-disruptor.git
cd xk6-disruptor

# Build the custom binary
xk6 build --output xk6-disruptor --with github.com/grafana/xk6-disruptor=.&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;xk6 will create the &lt;code&gt;xk6-disruptor&lt;/code&gt; binary in the current working directory.&lt;/p&gt;
]]></content><description>&lt;h1 id="installation">Installation&lt;/h1>
&lt;p>xk6-disruptor is a
&lt;a href="/docs/k6/v2.3.x/extensions/">k6 extension&lt;/a>. You have to run a k6 version built with the disruptor extension to use the
&lt;a href="/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/xk6-disruptor/">disruptor APIs&lt;/a> in your k6 tests.&lt;/p></description></item><item><title>Expose your application</title><link>https://grafana.com/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/expose-your-application/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/expose-your-application/</guid><content><![CDATA[&lt;h1 id=&#34;expose-your-application&#34;&gt;Expose your application&lt;/h1&gt;
&lt;p&gt;To access your application from the test scripts, you must assign it an external IP in the cluster where it&amp;rsquo;s running.
How you do this depends on the platform you use to deploy the application.
The following sections explain the different approaches.&lt;/p&gt;
&lt;h2 id=&#34;using-port-forwarding&#34;&gt;Using port-forwarding&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;kubectl&lt;/code&gt;&amp;rsquo;s &lt;code&gt;port-forward&lt;/code&gt; command allows accessing applications running in a Kubernetes cluster using a local port.&lt;/p&gt;
&lt;p&gt;For example, the following command will make &lt;code&gt;my-service&lt;/code&gt;&amp;rsquo;s port &lt;code&gt;80&lt;/code&gt; accessible as &lt;code&gt;localhost:8080&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;kubectl port-forward svc/my-service 8080:80
Forwarding from 127.0.0.1:8080 -&amp;gt; 80&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;limitations-using-port-forwarding&#34;&gt;Limitations using port forwarding&lt;/h3&gt;
&lt;p&gt;To be able to inject faults, &lt;code&gt;xk6-disruptor&lt;/code&gt; must 
    &lt;a href=&#34;/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/how--it-works/&#34;&gt;install an agent on each target&lt;/a&gt; that intercepts the requests and applies the desired disruptions. This process requires any existing connection to the targets to be redirected to the agent.&lt;/p&gt;
&lt;p&gt;Due to an existing bug in &lt;code&gt;kubectl&lt;/code&gt;, the process of installing the disruptor can potentially &lt;a href=&#34;https://github.com/grafana/xk6-disruptor/issues/254&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;break the port forwarding&lt;/a&gt;. Notice that this issue happens only if the faults are injected in the service that is exposed using port forward. If the faults are injected in another service not exposed by port-forwarding, there shouldn&amp;rsquo;t be any issue.&lt;/p&gt;
&lt;p&gt;Until this issue is solved in &lt;code&gt;kubectl&lt;/code&gt;, tests using port forwarding to access a service should ensure the agent is installed in the targets before any traffic is sent by the test.&lt;/p&gt;
&lt;p&gt;The simplest way to accomplish this is to ensure the scenario that executes the load (#2) starts after the scenario that injects the faults (#1):&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;js&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-js&#34;&gt;    scenarios: {
        disrupt: {   // #1 inject faults
            executor: &amp;#39;shared-iterations&amp;#39;,
            iterations: 1,
            vus: 1,
            exec: &amp;#34;disrupt&amp;#34;,
            startTime: &amp;#34;0s&amp;#34;,
        },
        load: {   // #2 execute load
            executor: &amp;#39;constant-arrival-rate&amp;#39;,
            rate: 100,
            preAllocatedVUs: 10,
            maxVUs: 100,
            exec: &amp;#34;default&amp;#34;,
            startTime: &amp;#39;20s&amp;#39;,  // give time for the agents to be installed
            duration: &amp;#34;30s&amp;#34;,
        }
     }&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;as-a-loadbalancer-service&#34;&gt;As a LoadBalancer service&lt;/h2&gt;
&lt;p&gt;A service of type &lt;a href=&#34;https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;code&gt;LoadBalancer&lt;/code&gt;&lt;/a&gt; receives an external IP from an external load-balancer provider.
How you configure the load balancer depends on the your cluster&amp;rsquo;s deployment platform and configuration.
The following sections provide guidelines to expose your application when running in common development environments.
If your cluster is deployed in a public cloud, check your cloud provider documentation.&lt;/p&gt;
&lt;p&gt;If the service that you want your tests to access is not defined as a load balancer, you can change the service type with the following command. The service will then receive an external IP.&lt;/p&gt;



  

  






  

  



  &lt;div class=&#34;code&#34; x-data=&#34;app_code([&amp;#34;bash&amp;#34;,&amp;#34;windows-powershell&amp;#34;], false)&#34; x-init=&#34;init()&#34; data-codetoggle=&#34;true&#34;&gt;
    &lt;div class=&#34;toggle-toolbar &#34;&gt;
      &lt;div&gt;&lt;button class=&#34;toggle-toolbar__item&#34; :class=&#34;{ &#39;toggle-toolbar__item-active&#39;: active === &#39;bash&#39; }&#34; @click=&#34;$store.code.language = &#39;bash&#39;&#34;&gt;
              &lt;span&gt;Bash&lt;/span&gt;
            &lt;/button&gt;&lt;button class=&#34;toggle-toolbar__item&#34; :class=&#34;{ &#39;toggle-toolbar__item-active&#39;: active === &#39;windows-powershell&#39; }&#34; @click=&#34;$store.code.language = &#39;windows-powershell&#39;&#34;&gt;
              &lt;span&gt;windows-powershell&lt;/span&gt;
            &lt;/button&gt;&lt;/div&gt;
      &lt;div class=&#34;d-flex&#34;&gt;&lt;span class=&#34;code-clipboard&#34; x-ref=&#34;tooltip&#34;&gt;
          &lt;button @click=&#34;copy()&#34;&gt;
            &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
            &lt;span&gt;Copy&lt;/span&gt;
          &lt;/button&gt;
        &lt;/span&gt;
      &lt;/div&gt;
      &lt;div class=&#34;toggle-toolbar__border&#34;&gt;&lt;/div&gt;
    &lt;/div&gt;
    
    &lt;div class=&#34;code-rendered&#34; &gt;
      
&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;kubectl -n &amp;lt;name space&amp;gt; patch svc &amp;lt;service name&amp;gt; -p &amp;#39;{&amp;#34;spec&amp;#34;: {&amp;#34;type&amp;#34;: &amp;#34;LoadBalancer&amp;#34;}}&amp;#39;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;windows-powershell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-windows-powershell&#34;&gt;kubectl -n &amp;lt;name space&amp;gt; patch svc &amp;lt;service name&amp;gt; -p &amp;#39;{\&amp;#34;spec\&amp;#34;: {\&amp;#34;type\&amp;#34;: \&amp;#34;LoadBalancer\&amp;#34;}}&amp;#39;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

    &lt;/div&gt;
  &lt;/div&gt;


&lt;p&gt;You can retrieve the external IP address and store it in an environment variable (&lt;code&gt;SVC_IP&lt;/code&gt; in this example) using the following command:&lt;/p&gt;



  

  






  

  



  &lt;div class=&#34;code&#34; x-data=&#34;app_code([&amp;#34;bash&amp;#34;,&amp;#34;windows-powershell&amp;#34;], false)&#34; x-init=&#34;init()&#34; data-codetoggle=&#34;true&#34;&gt;
    &lt;div class=&#34;toggle-toolbar &#34;&gt;
      &lt;div&gt;&lt;button class=&#34;toggle-toolbar__item&#34; :class=&#34;{ &#39;toggle-toolbar__item-active&#39;: active === &#39;bash&#39; }&#34; @click=&#34;$store.code.language = &#39;bash&#39;&#34;&gt;
              &lt;span&gt;Bash&lt;/span&gt;
            &lt;/button&gt;&lt;button class=&#34;toggle-toolbar__item&#34; :class=&#34;{ &#39;toggle-toolbar__item-active&#39;: active === &#39;windows-powershell&#39; }&#34; @click=&#34;$store.code.language = &#39;windows-powershell&#39;&#34;&gt;
              &lt;span&gt;windows-powershell&lt;/span&gt;
            &lt;/button&gt;&lt;/div&gt;
      &lt;div class=&#34;d-flex&#34;&gt;&lt;span class=&#34;code-clipboard&#34; x-ref=&#34;tooltip&#34;&gt;
          &lt;button @click=&#34;copy()&#34;&gt;
            &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
            &lt;span&gt;Copy&lt;/span&gt;
          &lt;/button&gt;
        &lt;/span&gt;
      &lt;/div&gt;
      &lt;div class=&#34;toggle-toolbar__border&#34;&gt;&lt;/div&gt;
    &lt;/div&gt;
    
    &lt;div class=&#34;code-rendered&#34; &gt;
      
&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;SVC_IP=$(kubectl -n &amp;lt;name space&amp;gt;  get svc &amp;lt;service name&amp;gt; --output jsonpath=&amp;#39;{.status.loadBalancer.ingress[0].ip}&amp;#39;)&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;windows-powershell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-windows-powershell&#34;&gt;$Env:SVC_IP=$(kubectl -n &amp;lt;name space&amp;gt;  get svc &amp;lt;service name&amp;gt; --output jsonpath=&amp;#39;{.status.loadBalancer.ingress[0].ip}&amp;#39;)&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

    &lt;/div&gt;
  &lt;/div&gt;


&lt;h3 id=&#34;configuring-a-loadbalancer-in-kind&#34;&gt;Configuring a LoadBalancer in Kind&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://kind.sigs.k8s.io/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Kind&lt;/a&gt; is a tool to run local Kubernetes clusters using a Docker container to emulate nodes.
You can use kind for local development or CI.
Services deployed in a kind cluster can be exposed to be accessed from the host machine &lt;a href=&#34;https://kind.sigs.k8s.io/docs/user/loadbalancer&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;using metallb as a load balancer&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;configuring-a-loadbalancer-in-minikube&#34;&gt;Configuring a LoadBalancer in Minikube&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/kubernetes/minikube&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Minikube&lt;/a&gt; implements a local Kubernetes cluster that supports different technologies to virtualize the cluster&amp;rsquo;s infrastructure, such as containers, VMs or bare metal.&lt;/p&gt;
&lt;p&gt;Minikube&amp;rsquo;s tunnel command runs as a process, creating a network route on the host to the service CIDR of the cluster.
It uses the cluster’s IP address as a gateway. The tunnel command exposes the external IP directly to any program that is running on the host operating system.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;minikube tunnel&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
]]></content><description>&lt;h1 id="expose-your-application">Expose your application&lt;/h1>
&lt;p>To access your application from the test scripts, you must assign it an external IP in the cluster where it&amp;rsquo;s running.
How you do this depends on the platform you use to deploy the application.
The following sections explain the different approaches.&lt;/p></description></item><item><title>How xk6-disruptor works</title><link>https://grafana.com/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/how-it-works/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/how-it-works/</guid><content><![CDATA[&lt;h1 id=&#34;how-xk6-disruptor-works&#34;&gt;How xk6-disruptor works&lt;/h1&gt;
&lt;p&gt;xk6-disruptor consists of two main components:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The xk6-disruptor extension&lt;/strong&gt; provides a Javascript API for injecting faults into a target system using the xk6-disruptor-agent as a backend. This API is built around a collection of &lt;strong&gt;disruptors&lt;/strong&gt;. Each disruptor targets a type of component in the system (for example Pods or cluster Nodes).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The xk6-disruptor-agent&lt;/strong&gt; injects faults into the target system where it runs. It is provided as an Docker image that you can pull from the &lt;a href=&#34;https://github.com/grafana/xk6-disruptor/pkgs/container/xk6-disruptor-agent&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;xk6-disruptor repository&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The xk6-disruptor extension installs the agent in the target and sends commands to inject the desired faults. How this happens depends on the type of disruptor, as described in the following sections.&lt;/p&gt;
&lt;h2 id=&#34;poddisruptor&#34;&gt;PodDisruptor&lt;/h2&gt;
&lt;p&gt;The following diagram shows how PodDisruptor works:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The PodDisruptor selects the target pods based on the selector attributes defined in the 
    &lt;a href=&#34;/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/xk6-disruptor/poddisruptor/constructor/&#34;&gt;constructor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;The PodDisruptor attaches the xk6-disruptor-agent to each of the target pods&lt;/li&gt;
&lt;li&gt;When a fault is injected (e.g. calling the 
    &lt;a href=&#34;/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/xk6-disruptor/poddisruptor/injecthttpfaults/&#34;&gt;injectHTTPFaults&lt;/a&gt;) the PodDisruptor sends a command to the agents to inject the fault in their respective pods&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img
  class=&#34;lazyload d-inline-block&#34;
  data-src=&#34;/media/docs/k6-oss/xk6-disruptor-how-pod-disruptor-works.png&#34;
  alt=&#34;How PodDisruptor works&#34; width=&#34;1119&#34;
     height=&#34;619&#34;/&gt;&lt;/p&gt;
&lt;h2 id=&#34;servicedisruptor&#34;&gt;ServiceDisruptor&lt;/h2&gt;
&lt;p&gt;The ServiceDisruptor works as a wrapper around a PodDisruptor, which targets the pods that back the service.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The ServiceDisruptor uses the definition of the service specified in the 
    &lt;a href=&#34;/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/xk6-disruptor/servicedisruptor/constructor/&#34;&gt;constructor&lt;/a&gt; to create a pod selector that matches the pods that back the service.&lt;/li&gt;
&lt;li&gt;The ServiceDisruptor creates a PodDisruptor using this pod selector.&lt;/li&gt;
&lt;li&gt;The PodDisruptor installs the agent in the target pods.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;From this point, the PodDisruptor works as described before.&lt;/p&gt;
&lt;p&gt;&lt;img
  class=&#34;lazyload d-inline-block&#34;
  data-src=&#34;/media/docs/k6-oss/xk6-disruptor-how-service-disruptor-works.png&#34;
  alt=&#34;How ServiceDisruptor works&#34; width=&#34;1019&#34;
     height=&#34;567&#34;/&gt;&lt;/p&gt;
]]></content><description>&lt;h1 id="how-xk6-disruptor-works">How xk6-disruptor works&lt;/h1>
&lt;p>xk6-disruptor consists of two main components:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>The xk6-disruptor extension&lt;/strong> provides a Javascript API for injecting faults into a target system using the xk6-disruptor-agent as a backend. This API is built around a collection of &lt;strong>disruptors&lt;/strong>. Each disruptor targets a type of component in the system (for example Pods or cluster Nodes).&lt;/li>
&lt;li>&lt;strong>The xk6-disruptor-agent&lt;/strong> injects faults into the target system where it runs. It is provided as an Docker image that you can pull from the &lt;a href="https://github.com/grafana/xk6-disruptor/pkgs/container/xk6-disruptor-agent" target="_blank" rel="noopener noreferrer">xk6-disruptor repository&lt;/a>.&lt;/li>
&lt;/ul>
&lt;p>The xk6-disruptor extension installs the agent in the target and sends commands to inject the desired faults. How this happens depends on the type of disruptor, as described in the following sections.&lt;/p></description></item><item><title>xk6-disruptor API</title><link>https://grafana.com/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/xk6-disruptor/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/xk6-disruptor/</guid><content><![CDATA[&lt;h1 id=&#34;xk6-disruptor-api&#34;&gt;xk6-disruptor API&lt;/h1&gt;
&lt;p&gt;The xk6-disruptor API is organized around &lt;em&gt;disruptors&lt;/em&gt; that affect specific targets such as pods or services. These disruptors can inject different types of 
    &lt;a href=&#34;/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/xk6-disruptor/faults/&#34;&gt;faults&lt;/a&gt; on their targets.&lt;/p&gt;
&lt;section class=&#34;expand-table-wrapper&#34;&gt;&lt;div class=&#34;button-div&#34;&gt;
      &lt;button class=&#34;expand-table-btn&#34;&gt;Expand table&lt;/button&gt;
    &lt;/div&gt;&lt;div class=&#34;responsive-table-wrapper&#34;&gt;
    &lt;table&gt;
      &lt;thead&gt;
          &lt;tr&gt;
              &lt;th&gt;Class&lt;/th&gt;
              &lt;th&gt;Description&lt;/th&gt;
          &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
          &lt;tr&gt;
              &lt;td&gt;
    &lt;a href=&#34;/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/xk6-disruptor/poddisruptor/&#34;&gt;PodDisruptor&lt;/a&gt;&lt;/td&gt;
              &lt;td&gt;Targets the Pods that match selection attributes such as labels.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;
    &lt;a href=&#34;/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/xk6-disruptor/servicedisruptor/&#34;&gt;ServiceDisruptor&lt;/a&gt;&lt;/td&gt;
              &lt;td&gt;Targets the Pods that back a Kubernetes Service&lt;/td&gt;
          &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/div&gt;
&lt;/section&gt;]]></content><description>&lt;h1 id="xk6-disruptor-api">xk6-disruptor API&lt;/h1>
&lt;p>The xk6-disruptor API is organized around &lt;em>disruptors&lt;/em> that affect specific targets such as pods or services. These disruptors can inject different types of
&lt;a href="/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/xk6-disruptor/faults/">faults&lt;/a> on their targets.&lt;/p></description></item><item><title>xk6-disruptor examples</title><link>https://grafana.com/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/examples/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/examples/</guid><content><![CDATA[&lt;h1 id=&#34;xk6-disruptor-examples&#34;&gt;xk6-disruptor examples&lt;/h1&gt;
&lt;p&gt;In this section, we present some examples of using the &lt;code&gt;xk6-disruptor&lt;/code&gt; extension to introduce faults in &lt;code&gt;k6&lt;/code&gt; tests.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
    &lt;a href=&#34;/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/examples/inject-grpc-faults-into-service/&#34;&gt;Injecting gRPC faults into a Service&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
    &lt;a href=&#34;/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/examples/inject-http-faults-into-pod/&#34;&gt;Injecting HTTP faults into a Pod&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://killercoda.com/grafana-xk6-disruptor/scenario/killercoda&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Interactive demo&lt;/a&gt; (Killercoda)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To follow the instructions of the examples, check first the system under test meets the 
    &lt;a href=&#34;/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/requirements/&#34;&gt;requirements&lt;/a&gt; to receive faults, in particular:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You have configured the credentials to access the Kubernetes cluster.&lt;/li&gt;
&lt;li&gt;This cluster exposes the service using an external IP.&lt;/li&gt;
&lt;/ul&gt;
]]></content><description>&lt;h1 id="xk6-disruptor-examples">xk6-disruptor examples&lt;/h1>
&lt;p>In this section, we present some examples of using the &lt;code>xk6-disruptor&lt;/code> extension to introduce faults in &lt;code>k6&lt;/code> tests.&lt;/p>
&lt;ul>
&lt;li>
&lt;a href="/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/examples/inject-grpc-faults-into-service/">Injecting gRPC faults into a Service&lt;/a>&lt;/li>
&lt;li>
&lt;a href="/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/examples/inject-http-faults-into-pod/">Injecting HTTP faults into a Pod&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://killercoda.com/grafana-xk6-disruptor/scenario/killercoda" target="_blank" rel="noopener noreferrer">Interactive demo&lt;/a> (Killercoda)&lt;/li>
&lt;/ul>
&lt;p>To follow the instructions of the examples, check first the system under test meets the
&lt;a href="/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/requirements/">requirements&lt;/a> to receive faults, in particular:&lt;/p></description></item></channel></rss>