<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://harvesterhci.io/kb</id>
    <title>The open-source hyperconverged infrastructure solution for a cloud-native world Blog</title>
    <updated>2024-11-28T00:00:00.000Z</updated>
    <generator>https://github.com/jpmonette/feed</generator>
    <link rel="alternate" href="https://harvesterhci.io/kb"/>
    <subtitle>The open-source hyperconverged infrastructure solution for a cloud-native world Blog</subtitle>
    <icon>https://harvesterhci.io/img/favicon.ico</icon>
    <entry>
        <title type="html"><![CDATA[KubeVirt Certificates Rotation]]></title>
        <id>kubevirt_certificates_rotation</id>
        <link href="https://harvesterhci.io/kb/kubevirt_certificates_rotation"/>
        <updated>2024-11-28T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[KubeVirt Certificates Rotation.]]></summary>
        <content type="html"><![CDATA[<p>Harvester's embedded Rancher UI may display warnings about expiring KubeVirt certificates. You can safely ignore these warnings because automatic certificate rotation is handled by KubeVirt and is enabled by default.</p><p><img loading="lazy" alt="kubevirt-certs-expired" src="/assets/images/kubevirt_certs_expired-af496d05bad47614e7fb644c8971950d.png" width="1716" height="937"></p><h2 class="anchor anchorWithStickyNavbar_mojV" id="kubevirt-certificate-rotation-strategy">KubeVirt Certificate Rotation Strategy<a class="hash-link" href="#kubevirt-certificate-rotation-strategy" title="Direct link to heading">​</a></h2><p>KubeVirt provides a self-signed certificate mechanism that rotates both CA and certifcates on a defined recurring interval. You can check the setting  <code>certificateRotateStrategy</code> by running the following command:</p><div class="codeBlockContainer_I0IT language-sh theme-code-block"><div class="codeBlockContent_wNvx sh"><pre tabindex="0" class="prism-code language-sh codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">kubectl get kubevirt -n harvester-system -o yaml</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>By default, the value of <code>certificateRotateStrategy</code> is empty, which means that KubeVirt uses its default rotation settings and no manual configuration is required.</p><div class="codeBlockContainer_I0IT language-yaml theme-code-block"><div class="codeBlockContent_wNvx yaml"><pre tabindex="0" class="prism-code language-yaml codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token key atrule" style="color:#00a4db">certificateRotateStrategy</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><h2 class="anchor anchorWithStickyNavbar_mojV" id="configuration-fields">Configuration Fields<a class="hash-link" href="#configuration-fields" title="Direct link to heading">​</a></h2><p>You can use the following fields to configure <code>certificateRotateStrategy</code>.</p><ul><li><code>.ca.duration</code>: Validity period of the CA certificate. The default value is "168h".</li><li><code>.ca.renewBefore</code>: Amount of time before a CA certificate expires during which a new certificate is issued. The default value is "33.6h".</li><li><code>.server.duration</code>: Validity period of server component certificates (for example, virt-api, virt-handler, and virt-operator). The default value is "24h".</li><li><code>.server.renewBefore</code>: Amount of time before a server certificate expires during which a new certificate is issued. The default value is "4.8h".</li></ul><p>Example of a complete configuration:</p><div class="codeBlockContainer_I0IT language-yaml theme-code-block"><div class="codeBlockContent_wNvx yaml"><pre tabindex="0" class="prism-code language-yaml codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token key atrule" style="color:#00a4db">certificateRotateStrategy</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">selfSigned</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">ca</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token key atrule" style="color:#00a4db">duration</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> 168h</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token key atrule" style="color:#00a4db">renewBefore</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> 33.6h</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">server</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token key atrule" style="color:#00a4db">duration</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> 24h</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token key atrule" style="color:#00a4db">renewBefore</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> 4.8h</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><h2 class="anchor anchorWithStickyNavbar_mojV" id="certificate-rotation-triggers">Certificate Rotation Triggers<a class="hash-link" href="#certificate-rotation-triggers" title="Direct link to heading">​</a></h2><p>Certificate rotation can be triggered by several conditions. The following list only outlines key triggers and is not exhaustive.</p><ul><li>Missing certificate: A required certificate does not exist.</li><li>Invalid CA signature: A certificate was not signed by the specified CA.</li><li>Proactive renewal: The <code>renewBefore</code> value takes effect. A new certificate must be issued before the current one expires.</li><li>CA expiration: The CA certificate has expired, so the certificate signed by the CA is also rotated.</li></ul><p>When certificate rotation is triggered, you should see <code>virt-operator</code> log records similar to the following:</p><div class="codeBlockContainer_I0IT language-txt theme-code-block"><div class="codeBlockContent_wNvx txt"><pre tabindex="0" class="prism-code language-txt codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">{"component":"virt-operator","level":"info","msg":"secret kubevirt-virt-api-certs updated","pos":"core.go:278","timestamp":"2024-12-06T08:02:01.045809Z"}</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">{"component":"virt-operator","level":"info","msg":"secret kubevirt-controller-certs updated","pos":"core.go:278","timestamp":"2024-12-06T08:02:01.056759Z"}</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">{"component":"virt-operator","level":"info","msg":"secret kubevirt-exportproxy-certs updated","pos":"core.go:278","timestamp":"2024-12-06T08:02:01.063530Z"}</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">{"component":"virt-operator","level":"info","msg":"secret kubevirt-virt-handler-server-certs updated","pos":"core.go:278","timestamp":"2024-12-06T08:02:01.068608Z"}</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">{"component":"virt-operator","level":"info","msg":"secret kubevirt-virt-handler-certs updated","pos":"core.go:278","timestamp":"2024-12-06T08:02:01.074555Z"}</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">{"component":"virt-operator","level":"info","msg":"secret kubevirt-operator-certs updated","pos":"core.go:278","timestamp":"2024-12-06T08:02:01.078719Z"}</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">{"component":"virt-operator","level":"info","msg":"secret kubevirt-export-ca updated","pos":"core.go:278","timestamp":"2024-12-06T08:03:36.063496Z"}</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">{"component":"virt-operator","level":"info","msg":"secret kubevirt-ca updated","pos":"core.go:278","timestamp":"2024-12-06T08:04:06.052750Z"}</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><h2 class="anchor anchorWithStickyNavbar_mojV" id="references">References<a class="hash-link" href="#references" title="Direct link to heading">​</a></h2><ul><li>Harvester: <a href="https://github.com/harvester/harvester/issues/5798" target="_blank" rel="noopener noreferrer">Issue 5798</a></li><li><a href="https://kubevirt.io/2020/KubeVirt-Security-Fundamentals.html" target="_blank" rel="noopener noreferrer">https://kubevirt.io/2020/KubeVirt-Security-Fundamentals.html</a></li><li><a href="https://github.com/kubevirt/kubevirt/blob/v1.1.1/pkg/virt-operator/resource/generate/components/secrets.go#L326" target="_blank" rel="noopener noreferrer">https://github.com/kubevirt/kubevirt/blob/v1.1.1/pkg/virt-operator/resource/generate/components/secrets.go#L326</a></li><li><a href="https://github.com/kubevirt/kubevirt/blob/v1.1.1/pkg/virt-operator/resource/apply/certificates.go" target="_blank" rel="noopener noreferrer">https://github.com/kubevirt/kubevirt/blob/v1.1.1/pkg/virt-operator/resource/apply/certificates.go</a></li></ul>]]></content>
        <author>
            <name>Cooper Tseng</name>
            <uri>https://github.com/brandboat</uri>
        </author>
        <category label="harvester" term="harvester"/>
        <category label="kubevirt" term="kubevirt"/>
        <category label="certificates" term="certificates"/>
        <category label="cert" term="cert"/>
        <category label="ca" term="ca"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Best Practices for Harvester Security]]></title>
        <id>harvester_security_best_practices</id>
        <link href="https://harvesterhci.io/kb/harvester_security_best_practices"/>
        <updated>2024-05-31T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[A set of best practices for Harvester security.]]></summary>
        <content type="html"><![CDATA[<h2 class="anchor anchorWithStickyNavbar_mojV" id="user-provided-credentials-on-harvester">User-Provided Credentials on Harvester<a class="hash-link" href="#user-provided-credentials-on-harvester" title="Direct link to heading">​</a></h2><p>When <a href="https://docs.harvesterhci.io/v1.2/install/index#installation-steps" target="_blank" rel="noopener noreferrer">installing a Harvester cluster</a>, you are asked to provide the following credential related information:</p><ul><li><p>Cluster token of the first node that is added to the cluster. Other nodes must use this token to join the cluster.</p></li><li><p>Password for the default Linux user <code>rancher</code> on each node.</p></li><li><p>SSH keys on each node (optional).</p></li><li><p>HTTP proxy on each node (optional).</p></li></ul><p>You may plan to change them from time to time, the following paragraphs describe the detailed steps.</p><h3 class="anchor anchorWithStickyNavbar_mojV" id="cluster-token">Cluster Token<a class="hash-link" href="#cluster-token" title="Direct link to heading">​</a></h3><h4 class="anchor anchorWithStickyNavbar_mojV" id="cluster-token-on-nodes-joining-an-existing-cluster">Cluster Token on Nodes Joining an Existing Cluster<a class="hash-link" href="#cluster-token-on-nodes-joining-an-existing-cluster" title="Direct link to heading">​</a></h4><p>When a node is unable to join a cluster because of a cluster token error, perform the recommended <a href="https://docs.harvesterhci.io/v1.2/troubleshooting/index/#modifying-cluster-token-on-agent-nodes" target="_blank" rel="noopener noreferrer">troubleshooting steps</a>.</p><h4 class="anchor anchorWithStickyNavbar_mojV" id="cluster-token-rke2-token-rotation">Cluster Token (RKE2 Token Rotation)<a class="hash-link" href="#cluster-token-rke2-token-rotation" title="Direct link to heading">​</a></h4><p>Harvester does not allow you to change the cluster token even if RKE2 is a core component of Harvester.</p><p>The <a href="https://docs.rke2.io/security/token#server-token-rotation" target="_blank" rel="noopener noreferrer">RKE2 documentation</a> states that the November 2023 releases of RKE2 (v1.28.3+rke2r2, v1.27.7+rke2r2, v1.26.10+rke2r2, and v1.25.15+rke2r2) allow you to rotate the cluster token using the command <code>rke2 token rotate --token original --new-token new</code>. </p><p>During testing, the command was run on the first node of a cluster running <strong>Harvester v1.3.0 with RKE2 v1.27.10+rke2r1</strong>.</p><ol><li>Rotate the token on initial node.</li></ol><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">/opt/rke2/bin $ ./rke2 token rotate --token rancher --new-token rancher1</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">WARNING: Recommended to keep a record of the old token. If restoring from a snapshot, you must use the token associated with that snapshot.</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">WARN[0000] Cluster CA certificate is not trusted by the host CA bundle, but the token does not include a CA hash. Use the full token from the server's node-token file to enable Cluster CA validation. </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Token rotated, restart rke2 nodes with new token</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><ol start="2"><li>When the first cluster node was rebooted, RKE2 service was unable to start.</li></ol><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">RKE2 log:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">...</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">May 29 15:45:11 harv41 rke2[3293]: time="2024-05-29T15:45:11Z" level=info msg="etcd temporary data store connection OK"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">May 29 15:45:11 harv41 rke2[3293]: time="2024-05-29T15:45:11Z" level=info msg="Reconciling bootstrap data between datastore and disk"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">May 29 15:45:11 harv41 rke2[3293]: time="2024-05-29T15:45:11Z" level=fatal msg="Failed to reconcile with temporary etcd: bootstrap data already found and encrypted with different token"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">May 29 15:45:11 harv41 systemd[1]: rke2-server.service: Main process exited, code=exited, status=1/FAILURE</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">...</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>This known issue was logged on Github issue <a href="https://github.com/rancher/rke2/issues/6250" target="_blank" rel="noopener noreferrer">rke2 token rotate does not work as expected (v1.27.10+rke2r1)</a>.</p><p>:::Warning</p><p>Do not attempt to rotate the RKE2 token on your cluster before Harvester announces official support for this feature (even if the embedded RKE2 binary has the <code>token rotate</code> option).</p><p>:::</p><h3 class="anchor anchorWithStickyNavbar_mojV" id="password-of-the-default-user-rancher">Password of the Default User <code>rancher</code><a class="hash-link" href="#password-of-the-default-user-rancher" title="Direct link to heading">​</a></h3><p>This process is node-specific. You must change the <a href="https://docs.harvesterhci.io/v1.2/install/update-harvester-configuration/#password-of-user-rancher" target="_blank" rel="noopener noreferrer">password of the default user</a> on each node even if the same password is used on all Harvester nodes.</p><h3 class="anchor anchorWithStickyNavbar_mojV" id="ssh-keys">SSH keys<a class="hash-link" href="#ssh-keys" title="Direct link to heading">​</a></h3><p>You must log into a Harvester node using the default user account <code>rancher</code> to change the <a href="https://docs.harvesterhci.io/v1.2/install/update-harvester-configuration#ssh-keys-of-user-rancher" target="_blank" rel="noopener noreferrer">SSH keys</a>.</p><h3 class="anchor anchorWithStickyNavbar_mojV" id="http-proxy">HTTP Proxy<a class="hash-link" href="#http-proxy" title="Direct link to heading">​</a></h3><p>After a Harvester cluster is installed, you can use the Harvester UI to change the <a href="https://docs.harvesterhci.io/v1.2/advanced/index#http-proxy" target="_blank" rel="noopener noreferrer">HTTP proxy</a>.</p><p>Alternatively, you can use <code>kubectl</code> or the rest API against the URI <code>/harvesterhci.io.setting/http-proxy</code>.</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">$ kubectl get settings.harvesterhci.io http-proxy -oyaml</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">apiVersion: harvesterhci.io/v1beta1</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">default: '{}'</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">kind: Setting</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">metadata:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  creationTimestamp: "2024-05-13T20:44:20Z"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  generation: 1</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  name: http-proxy</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  resourceVersion: "5914"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  uid: 282506bb-f1dd-4247-bf0e-93640698c1f5</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">status: {}</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>Harvester has a webhook that checks this setting to ensure it meets all conditions, e.g. the internal IPs and CIDRs are specified in the <code>noProxy</code> field.</p><div class="admonition admonition-note alert alert--secondary"><div class="admonition-heading"><h5><span class="admonition-icon"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>note</h5></div><div class="admonition-content"><p>Avoid changing the HTTP proxy from files in the host <code>/oem</code> path for the following reasons:</p><ul><li><p>You must manually change the HTTP proxy on each node.</p></li><li><p>Contents of local files are not automatically populated to new nodes.</p></li><li><p>Without help from the webhook, some erroneous configurations may not be promptly detected (see <a href="https://github.com/harvester/harvester/pull/5824" target="_blank" rel="noopener noreferrer">Node IP should be in noProxy</a>).</p></li><li><p>Harvester may change the file naming or content structure in the future.</p></li></ul></div></div><h2 class="anchor anchorWithStickyNavbar_mojV" id="other-credentials-and-settings">Other Credentials and Settings<a class="hash-link" href="#other-credentials-and-settings" title="Direct link to heading">​</a></h2><h3 class="anchor anchorWithStickyNavbar_mojV" id="auto-rotate-rke2-certs"><code>auto-rotate-rke2-certs</code><a class="hash-link" href="#auto-rotate-rke2-certs" title="Direct link to heading">​</a></h3><p>Harvester is built on top of Kubernetes, RKE2, and Rancher. RKE2 generates a list of <code>*.crt</code> and <code>*.key</code> files that allow Kubernetes components to function. The <code>*.crt</code> file expires after one year by default.</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">$ ls /var/lib/rancher/rke2/server/tls/ -alth</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">...</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">-rw-r--r-- 1 root root  570 May 27 08:45 server-ca.nochain.crt</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">-rw------- 1 root root 1.7K May 27 08:45 service.current.key</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">-rw-r--r-- 1 root root  574 May 27 08:45 client-ca.nochain.crt</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">drwxr-xr-x 2 root root 4.0K May 13 20:45 kube-controller-manager</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">drwxr-xr-x 2 root root 4.0K May 13 20:45 kube-scheduler</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">drwx------ 6 root root 4.0K May 13 20:45 .</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">drwx------ 8 root root 4.0K May 13 20:45 ..</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">-rw-r--r-- 1 root root 3.9K May 13 20:40 dynamic-cert.json</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">drwx------ 2 root root 4.0K May 13 20:39 temporary-certs</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">-rw------- 1 root root 1.7K May 13 20:39 service.key</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">-rw-r--r-- 1 root root 1.2K May 13 20:39 client-auth-proxy.crt</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">-rw------- 1 root root  227 May 13 20:39 client-auth-proxy.key</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">-rw-r--r-- 1 root root 1.2K May 13 20:39 client-rke2-cloud-controller.crt</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">...</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">-rw-r--r-- 1 root root 1.2K May 13 20:39 client-admin.crt</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">-rw------- 1 root root  227 May 13 20:39 client-admin.key</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">...</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">$ openssl x509 -enddate -noout -in /var/lib/rancher/rke2/server/tls/client-admin.crt</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">notAfter=May 13 20:39:42 2025 GMT</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>When a cluster has been running for over one year, Kubernetes components may fail to start after upgrades or node rebooting. The <a href="https://github.com/harvester/harvester/issues/3863#issuecomment-1539681311" target="_blank" rel="noopener noreferrer">workaround</a> is to delete the related files and restart the pod.</p><p>Harvester v1.3.0 added the setting <a href="https://docs.harvesterhci.io/v1.3/advanced/index#auto-rotate-rke2-certs" target="_blank" rel="noopener noreferrer"><code>auto-rotate-rke2-certs</code></a>, which allows you to set the Harvester cluster to automatically rotate certificates for RKE2 services. When you enable the setting and specify a certificate validity period, Harvester automatically replaces the certificate before the specified period ends.</p><div class="admonition admonition-note alert alert--secondary"><div class="admonition-heading"><h5><span class="admonition-icon"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>note</h5></div><div class="admonition-content"><p>Enabling this setting on your cluster is highly recommended.</p></div></div><h3 class="anchor anchorWithStickyNavbar_mojV" id="harvester-cloud-credentials">Harvester Cloud Credentials<a class="hash-link" href="#harvester-cloud-credentials" title="Direct link to heading">​</a></h3><p>See the article <a href="https://harvesterhci.io/kb/renew_harvester_cloud_credentials" target="_blank" rel="noopener noreferrer">Renew Harvester Cloud Credentials</a>.</p><h3 class="anchor anchorWithStickyNavbar_mojV" id="additional-ca"><code>additional-ca</code><a class="hash-link" href="#additional-ca" title="Direct link to heading">​</a></h3><p>See the <a href="https://docs.harvesterhci.io/v1.2/advanced/index#additional-ca" target="_blank" rel="noopener noreferrer">documentation</a> for this setting.</p><h3 class="anchor anchorWithStickyNavbar_mojV" id="ssl-certificates"><code>ssl-certificates</code><a class="hash-link" href="#ssl-certificates" title="Direct link to heading">​</a></h3><p>See the <a href="https://docs.harvesterhci.io/v1.2/advanced/index#ssl-certificates" target="_blank" rel="noopener noreferrer">documentation</a> for this setting.</p><h3 class="anchor anchorWithStickyNavbar_mojV" id="ssl-parameters"><code>ssl-parameters</code><a class="hash-link" href="#ssl-parameters" title="Direct link to heading">​</a></h3><p>See the <a href="https://docs.harvesterhci.io/v1.2/advanced/index#ssl-parameters" target="_blank" rel="noopener noreferrer">documentation</a> for this setting.</p><h3 class="anchor anchorWithStickyNavbar_mojV" id="containerd-registry"><code>containerd-registry</code><a class="hash-link" href="#containerd-registry" title="Direct link to heading">​</a></h3><p>See the <a href="https://docs.harvesterhci.io/v1.2/advanced/index#containerd-registry" target="_blank" rel="noopener noreferrer">documentation</a> for this setting.</p>]]></content>
        <author>
            <name>Jian Wang</name>
            <uri>https://github.com/w13915984028</uri>
        </author>
        <category label="harvester" term="harvester"/>
        <category label="security" term="security"/>
        <category label="credential" term="credential"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Renew Harvester Cloud Credentials]]></title>
        <id>renew_harvester_cloud_credentials</id>
        <link href="https://harvesterhci.io/kb/renew_harvester_cloud_credentials"/>
        <updated>2024-05-17T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[How to renew expired Harvester cloud credentials when using Rancher 2.8.x.]]></summary>
        <content type="html"><![CDATA[<h2 class="anchor anchorWithStickyNavbar_mojV" id="expiration-of-kubeconfig-tokens-in-rancher-28x">Expiration of kubeconfig Tokens in Rancher 2.8.x<a class="hash-link" href="#expiration-of-kubeconfig-tokens-in-rancher-28x" title="Direct link to heading">​</a></h2><p>In Rancher 2.8.x, the default value of the <a href="https://ranchermanager.docs.rancher.com/api/api-tokens#kubeconfig-default-token-ttl-minutes" target="_blank" rel="noopener noreferrer">kubeconfig-default-token-ttl-minutes</a> setting is <code>30</code> days.</p><p>A side effect of using this default value is the expiration of authentication tokens embedded in kubeconfigs that Rancher uses to provision guest Kubernetes clusters on Harvester. When such tokens expire, Rancher loses the ability to perform management operations for the corresponding Rancher-managed guest Kubernetes clusters. <a href="https://github.com/rancher/rancher/issues/44912" target="_blank" rel="noopener noreferrer">Issue #44912</a> tracks the issue described in this article.</p><div class="admonition admonition-note alert alert--secondary"><div class="admonition-heading"><h5><span class="admonition-icon"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>note</h5></div><div class="admonition-content"><p>The issue affects only guest Kubernetes clusters running on Harvester that use cloud credentials created after installing or upgrading to Rancher v2.8.x.</p></div></div><h2 class="anchor anchorWithStickyNavbar_mojV" id="workaround">Workaround<a class="hash-link" href="#workaround" title="Direct link to heading">​</a></h2><p>You can patch the expired Harvester cloud credentials to use a new authentication token.</p><ol><li><p>Identify the expired cloud credentials and which Harvester cluster is
affected by them.</p><p><img loading="lazy" alt="identify-credentials" src="/assets/images/identify-cloud-credential-96a0eea63d2ff91994343792fff4065f.png" width="2231" height="980"></p></li><li><p>Download a new kubeconfig file for the affected Harvester cluster.</p><p><img loading="lazy" alt="context-menu" src="/assets/images/harvester-renew-kubeconfig-menu-988dc9a3898df89b96f1933a2455a0da.png" width="2037" height="945"></p></li><li><p>Patch the cloud credentials. The cloud credential is stored as a secret in <code>cattle-global-data</code> namespace, and can be replaced with the new kubeconfig file. Ensure that the environment variable <code>KUBECONFIG_FILE</code> contains the path to the new kubeconfig file.</p><div class="codeBlockContainer_I0IT language-shell theme-code-block"><div class="codeBlockContent_wNvx shell"><pre tabindex="0" class="prism-code language-shell codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token shebang important">#!/bin/sh</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token assign-left variable" style="color:#36acaa">CLOUD_CREDENTIAL_ID</span><span class="token operator" style="color:#393A34">=</span><span class="token variable" style="color:#36acaa">$1</span><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic"># .metadata.name of the cloud credential</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token assign-left variable" style="color:#36acaa">KUBECONFIG_FILE</span><span class="token operator" style="color:#393A34">=</span><span class="token variable" style="color:#36acaa">$2</span><span class="token plain">      </span><span class="token comment" style="color:#999988;font-style:italic"># path to the downloaded kubeconfig file</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token assign-left variable" style="color:#36acaa">kubeconfig</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"</span><span class="token string variable" style="color:#36acaa">$(</span><span class="token string variable" style="color:#36acaa">base64 -w </span><span class="token string variable number" style="color:#36acaa">0</span><span class="token string variable" style="color:#36acaa"> </span><span class="token string variable string" style="color:#e3116c">"</span><span class="token string variable string variable" style="color:#36acaa">${KUBECONFIG_FILE}</span><span class="token string variable string" style="color:#e3116c">"</span><span class="token string variable" style="color:#36acaa">)</span><span class="token string" style="color:#e3116c">"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token assign-left variable" style="color:#36acaa">patch_file</span><span class="token operator" style="color:#393A34">=</span><span class="token variable" style="color:#36acaa">$(</span><span class="token variable" style="color:#36acaa">mktemp</span><span class="token variable" style="color:#36acaa">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">cat</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">${patch_file}</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&lt;&lt;</span><span class="token string" style="color:#e3116c">EOF</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">data:</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">  harvestercredentialConfig-kubeconfigContent: </span><span class="token string variable" style="color:#36acaa">$kubeconfig</span><span class="token string" style="color:#e3116c"></span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">EOF</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">kubectl patch secret </span><span class="token variable" style="color:#36acaa">${CLOUD_CREDENTIAL_ID}</span><span class="token plain"> -n cattle-global-data --patch-file </span><span class="token variable" style="color:#36acaa">${patch_file}</span><span class="token plain"> --type merge</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">rm</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">${patch_file}</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><div class="admonition admonition-info alert alert--info"><div class="admonition-heading"><h5><span class="admonition-icon"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>important</h5></div><div class="admonition-content"><p>macOS users must use <code>gbase64</code> to ensure that the <code>-w</code> flag is supported.</p></div></div></li></ol><h2 class="anchor anchorWithStickyNavbar_mojV" id="expiration-of-kubeconfig-tokens-in-rancher-293">Expiration of kubeconfig Tokens in Rancher 2.9.3<a class="hash-link" href="#expiration-of-kubeconfig-tokens-in-rancher-293" title="Direct link to heading">​</a></h2><p>In Rancher 2.9.3 and later versions, the Rancher UI displays a warning when a Harvester cloud credential or a related cluster contains an expired token. You can renew the token on the <strong>Cloud Credentials</strong> screen by selecting <strong>⋮ &gt; Renew</strong>, or the Clusters screen by selecting <strong>⋮ &gt; Renew Cloud Credential</strong></p><p><img loading="lazy" alt="cc-renew" src="/assets/images/cc-renew-b94bcdd9ea16e36ced4101021ed3bacb.png" width="1481" height="444"></p><div class="admonition admonition-note alert alert--secondary"><div class="admonition-heading"><h5><span class="admonition-icon"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>note</h5></div><div class="admonition-content"><p>When you upgrade Rancher, the Rancher UI does not display a warning for Harvester cloud credentials that expired before the upgrade was started. However, you can still renew the token on the <strong>Cloud Credentials</strong> or <strong>Clusters</strong> screen.</p></div></div>]]></content>
        <author>
            <name>Gaurav Mehta</name>
            <uri>https://github.com/ibrokethecloud</uri>
        </author>
        <author>
            <name>Moritz Röhrich</name>
            <uri>https://github.com/m-ildefons</uri>
        </author>
        <category label="harvester" term="harvester"/>
        <category label="cloud credentials" term="cloud credentials"/>
        <category label="rancher" term="rancher"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Configuring Harvester to Boot from an iSCSI Root Disk in Special Circumstances]]></title>
        <id>install_iscsi_firmware_install_boot</id>
        <link href="https://harvesterhci.io/kb/install_iscsi_firmware_install_boot"/>
        <updated>2024-03-05T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[How to modify GRUB configuration so Harvester will use system firmware to access an iSCSI boot/root disk]]></summary>
        <content type="html"><![CDATA[<p>Through v1.3.0, no explicit support has been provided for using Harvester (installing, booting, and running) with any type of storage that is not locally attached. This is in keeping with the philosophy of Hyper-Converged Infrastructure (HCI), which by definition hosts computational capability, storage, and networking in a single device or a set of similar devices operating in a cluster.</p><p>However, there are certain limited conditions that allow Harvester to be used on nodes without locally-attached bootable storage devices. Specifically, the use of converged network adapters (CNAs) as well as manual changes to the boot loader configuration of the installed system are required.</p><h2 class="anchor anchorWithStickyNavbar_mojV" id="concepts-requirements-and-limitations">Concepts, Requirements, and Limitations<a class="hash-link" href="#concepts-requirements-and-limitations" title="Direct link to heading">​</a></h2><p>This section describes background concepts and outlines requirements and limitations that you must consider before performing the procedure. For more information about the described concepts, see the references listed at the end of this article.</p><h3 class="anchor anchorWithStickyNavbar_mojV" id="iscsi-concepts-and-terminology">iSCSI Concepts and Terminology<a class="hash-link" href="#iscsi-concepts-and-terminology" title="Direct link to heading">​</a></h3><p>SCSI (Small Computer System Interface) is a set of standards for transferring data between computers systems and I/O devices. It is primarily used with storage devices.</p><p>The SCSI standards specify the following:</p><ul><li><strong>SCSI protocol</strong>: A set of message formats and rules of exchange</li><li><strong>SCSI transports</strong>: Methods for physically connecting storage devices to the computer system and transferring SCSI messages between them</li></ul><p>A number of SCSI transports are defined, including the following:</p><ul><li><strong>SAS (Serial Attached SCSI)</strong> and <strong>UAS (USB Attached SCSI)</strong>: Used to access SCSI storage devices that are directly attached to the computers using that storage</li><li><strong>FCP (Fibre Channel Protocol)</strong> and <strong>iSCSI (Internet SCSI)</strong>: Permit computer systems to access storage via a Storage Area Network (SAN), where the storage devices are attached to a system other than the computers using that storage</li></ul><p>The SCSI protocol is a client-server protocol, which means that all interaction occurs between clients that send requests and a server that services the requests. In the SCSI context, the client is called the <strong>initiator</strong> and the server is called the <strong>target</strong>. iSCSI initiators and targets identify themselves using a specially formatted identifier called an <strong>iSCSI qualified name (IQN)</strong>. The controller used to provide access to the storage devices is commonly called a <strong>host bus adapter (HBA)</strong>.</p><p>When using iSCSI, access is provided by a traditional Internet protocol, with an extra layer to encapsulate SCSI commands within TCP/IP messages. This can be implemented entirely in software (transferring messages using a traditional NIC), or it can be "offloaded" to a "smart" NIC that contains the iSCSI protocol and provides access through special firmware. Such NICs, which provide both a traditional Ethernet interface for regular Internet traffic and a higher-level storage interface for iSCSI services, are often called <strong>converged network adapters (CNAs)</strong>.</p><p>Systems with iSCSI CNAs can be configured to enable the system bootstrap firmware to boot the system via iSCSI. In addition, if the loaded operating system is aware of such an interface provided by the CNA, it can access the bootstrap device using that firmware interface <em>as if it were a locally attached device</em> without requiring initialization of the operating system's full software iSCSI protocol machinery.</p><h3 class="anchor anchorWithStickyNavbar_mojV" id="additional-concepts-and-terminology">Additional Concepts and Terminology<a class="hash-link" href="#additional-concepts-and-terminology" title="Direct link to heading">​</a></h3><p>Harvester must be installed on a bootable storage device, which is referred to as the <em>boot disk</em>.</p><p>Other storage devices, which are referred to as <em>non-boot disks</em>, may also be used in the Harvester ecosystem.</p><h3 class="anchor anchorWithStickyNavbar_mojV" id="requirements">Requirements<a class="hash-link" href="#requirements" title="Direct link to heading">​</a></h3><p>You must install Harvester on a node with a converged NIC that provides iSCSI offload capability with firmware support. This firmware must specifically support the iSCSI Boot Firmware Table (iBFT).</p><div class="admonition admonition-note alert alert--secondary"><div class="admonition-heading"><h5><span class="admonition-icon"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>note</h5></div><div class="admonition-content"><p>The procedure was tested with the following:</p><ul><li>Harvester v1.2.1 and v1.3.0</li><li>Dell PowerEdge R650 (Other systems with comparable hardware and firmware iSCSI support may also be suitable.)</li></ul></div></div><h3 class="anchor anchorWithStickyNavbar_mojV" id="limitations">Limitations<a class="hash-link" href="#limitations" title="Direct link to heading">​</a></h3><p>The procedure will not work in environments with the following conditions:</p><ul><li>iSCSI is not implemented in a converged NIC.</li><li>Nodes boot via PXE.</li><li>Harvester is installed only on virtual machines.</li></ul><h2 class="anchor anchorWithStickyNavbar_mojV" id="procedure">Procedure<a class="hash-link" href="#procedure" title="Direct link to heading">​</a></h2><p>The following is a summary of the procedure. Individual steps, which are described in the following sections, must be performed interactively. A fully automated installation is <strong>not</strong> possible at this time.</p><ol><li>Provision storage for your Harvester node on your iSCSI server system.</li><li>Configure system firmware to boot via iSCSI using the available CNA.</li><li>Boot the Harvester install image and install to the iSCSI device.</li><li>On first Harvester boot after installation, edit the kernel boot parameters in the GRUB kernel command line.</li><li>Permanently edit the GRUB configuration file in the normally read-only partition.</li></ol><div class="admonition admonition-info alert alert--info"><div class="admonition-heading"><h5><span class="admonition-icon"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>important</h5></div><div class="admonition-content"><p>The boot configuration changes will persist across node reboots but <strong>not</strong> across system upgrades, which will overwrite the GRUB parameters. </p></div></div><h3 class="anchor anchorWithStickyNavbar_mojV" id="1-provision-storage-for-your-harvester-node-on-your-iscsi-server-system">1. Provision storage for your Harvester node on your iSCSI server system.<a class="hash-link" href="#1-provision-storage-for-your-harvester-node-on-your-iscsi-server-system" title="Direct link to heading">​</a></h3><p>Before attempting to install Harvester onto a disk accessed by iSCSI,
the storage must first be provisioned on the storage server.</p><p>The details depend on the storage server and will not be discussed here.</p><p>However, several pieces of information must be obtained
in order for the system being installed to be able
to access the storage using iSCSI.</p><ul><li>The IP address and port number of the iSCSI server.</li><li>The iSCSI Qualified Name (IQN) of the iSCSI target on the server.</li><li>The LUN of the volume on the server to be accessed from the client as the disk on which Harvester will be installed.</li><li>Depending on on how the server is administered, authentication parameters may also be required.</li></ul><p>These items of information will be determined by the server system.</p><p>In addition, an IQN must be chosen for the client system to be used as its initiator identifier.</p><p>An IQN is a string in a certain format.
In general, any string in the defined format can be used as long as it is unique.
However, specific environments may place stricter requirements on the choice of names.</p><p>The format of an IQN is illustrated in the following example:</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">    iqn.2024-02.com.example:cluster1-node0-boot-disk</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>There are lots of variations of this format, and this is just an example.</p><p>The correct name to use should be chosen in consultation with the administrator of your storage server and storage area network.</p><h3 class="anchor anchorWithStickyNavbar_mojV" id="2-configure-system-firmware-to-boot-via-iscsi-using-the-available-cna">2. Configure system firmware to boot via iSCSI using the available CNA.<a class="hash-link" href="#2-configure-system-firmware-to-boot-via-iscsi-using-the-available-cna" title="Direct link to heading">​</a></h3><p>When your system to be installed powers on or is reset, you must enter the firmware setup menu to change the boot settings and enable booting via iSCSI.</p><p>Precise details for this are difficult to provide because they vary from system to system.</p><p>It is typical to force the system to enter the firmware settings menu by typing a special key such as F2, F7, ESC, etc.
Which one works for your system varies.
Often the system will display a list of which key(s) are available for specific firmware functions,
but it is not uncommon for the firmware to erase this list and start to boot after only a very short delay,
so you have to pay close attention.</p><p>If in doubt, consult the system provider's documentation.
An example document link is provided in the References section.
Other vendors should provide similar documentation.</p><p>The typical things you need to configure are:</p><ul><li>Enable UEFI boot</li><li>Configure iSCSI initiator and target parameters</li><li>Enable the iSCSI device in the boot menu</li><li>Set the boot order so that your system will boot from the iSCSI device</li></ul><h3 class="anchor anchorWithStickyNavbar_mojV" id="boot-the-harvester-install-image-and-install-to-the-iscsi-device">Boot the Harvester install image and install to the iSCSI device<a class="hash-link" href="#boot-the-harvester-install-image-and-install-to-the-iscsi-device" title="Direct link to heading">​</a></h3><p>This can be done by whatever means you would normally use to load the Harvester install image.</p><p>The Harvester installer <em>should</em> automatically "see" the iSCSI device in the dialog where you chose the installation destination.
Choose this device to install.</p><p>Installation should proceed and complete normally.</p><p>When installation completes, your system should reboot.</p><h3 class="anchor anchorWithStickyNavbar_mojV" id="4-on-first-boot-edit-kernel-boot-parameters-in-the-grub-kernel-command-line">4. On first boot, edit kernel boot parameters in the GRUB kernel command line.<a class="hash-link" href="#4-on-first-boot-edit-kernel-boot-parameters-in-the-grub-kernel-command-line" title="Direct link to heading">​</a></h3><p>As your system starts to come up after the first reboot,
the firmware will load the boot loader (GRUB) from the iSCSI device,
and GRUB will be able to use this device to load the kernel.</p><p>However, the kernel will <strong>not</strong> be aware of the iSCSI boot disk <strong>unless</strong> you modify the kernel parameters in the GRUB command line.</p><p>If you don't modify the kernel parameters, then system startup procedures will fail to find the <code>COS_OEM</code> and other paritions on the boot disk,
and it will be unable to access the <code>cloud-init</code> configuration or any of the container images needed to </p><p>The first time the GRUB menu appears after installation, you should stop the GRUB boot loader from automatically loading the kernel,
and edit the kernel command line.</p><p>To stop GRUB from automatically loading the kernel, hit the ESC key as soon as the menu appears.
You will only have a few seconds to do this before the system automatically boots.</p><p>Then, type "e" to edit the GRUB configuration for the first boot option.</p><p>It will show you something similar to the following:</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">setparams 'Harvester v1.3.0'</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  # label is kept around for backward compatibility</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  set label=${active_label}</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  set img=/cOS/active.img</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  loopback $loopdev /$img</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  source $(loopdev)/etc/cos/bootargs.cfg</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  linux ($loopdev)$kernel $kernelcmd ${extra_cmdline} ${extra_active_cmdline}</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  initrd ($loopdev)$initramfs</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>Move the cursor down to the line that begins with <code>linux</code>, and move the cursor to the end of that line.</p><p>Append the following string (two parameters): <code>rd.iscsi.firmware rd.iscsi.ibft</code>.</p><p>The line beginning with <code>linux</code> should now look like this:</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">  linux ($loopdev)$kernel $kernelcmd ${extra_cmdline} ${extra_active_cmdline} rd.iscsi.firmware rd.iscsi.ibft</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>At this point, type Ctrl-X to resume booting with the modified kernel command line.</p><p>Now the node should come up normally, and finish with the normal Harvester console screen that shows the cluster and node IP addresses and status.</p><p>The the node should operate normally now <strong>but</strong> the kernel boot argument changes will not be preserved across a reboot unless you perform the next step.</p><h3 class="anchor anchorWithStickyNavbar_mojV" id="5-permanently-edit-the-grub-configuration-file">5. Permanently edit the GRUB configuration file.<a class="hash-link" href="#5-permanently-edit-the-grub-configuration-file" title="Direct link to heading">​</a></h3><p>At this point you need to preserve these boot argument changes.</p><p>You can do this from the console by pressing F12 and logging in, or you can use an SSH session over the network.</p><p>The changes must be made permanent by editing the GRUB configuration file <code>grub.cfg</code>.</p><p>The trick here is that the file to be changed is stored in a partition which is normally <strong>read-only</strong>,
so the first thing you must do is to re-mount the volume to be read-write.</p><p>Start out by using the <code>blkid</code> command to find the device name of the correct partition:</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">    $ sudo -i</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    # blkid -L COS_STATE</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    /dev/sda4</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    #</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>The device name will be something like <code>/dev/sda4</code>.  The following examples assume that's the name but you should modify the commands to match what you see on your system.</p><p>Now, re-mount that volume to make it writable:</p><div class="codeBlockContainer_I0IT language-shell theme-code-block"><div class="codeBlockContent_wNvx shell"><pre tabindex="0" class="prism-code language-shell codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic"># mount -o remount -rw /dev/sda4 /run/initramfs/cos-state</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>Next, edit the <code>grub.cfg</code> file.</p><div class="codeBlockContainer_I0IT language-shell theme-code-block"><div class="codeBlockContent_wNvx shell"><pre tabindex="0" class="prism-code language-shell codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic"># vim /run/initramfs/cos-state/grub2/grub.cfg</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>Look for <code>menuentry</code> directives.  There will be several of these; at least one as a fallback, and one for recovery.  You should apply the same change to all of them.</p><p>In each of these, edit the line beginning with <code>linux</code> just as you did for the interactive GRUB menu, appending <code> rd.iscsi.firmware rd.iscsi.ibft</code> to the arguments.</p><p>Then save the changes.</p><p>It is not necessary, but probably advisable to remount that volume again to return it to its read-only state:</p><div class="codeBlockContainer_I0IT language-shell theme-code-block"><div class="codeBlockContent_wNvx shell"><pre tabindex="0" class="prism-code language-shell codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic"># mount -o remount -ro /dev/sda4 /run/initramfs/cos-state</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>From this point on, these changes will persist across node reboots.</p><p>A few important notes:</p><ul><li>You must perform this same procedure for every node of your cluster that you are booting with iSCSI.</li><li>These changes will be overwritten by the upgrade procedure if you upgrade your cluster to a newer version of Harvester.  Therefore, if you do an upgrade, be sure to re-do the procedure to edit the <code>grub.cfg</code> on every node of your cluster that is booting by iSCSI.</li></ul><h2 class="anchor anchorWithStickyNavbar_mojV" id="references">References<a class="hash-link" href="#references" title="Direct link to heading">​</a></h2><ul><li><a href="https://en.wikipedia.org/wiki/SCSI" target="_blank" rel="noopener noreferrer">SCSI</a> provides an overview of SCSI and contains references to additional material.</li><li><a href="https://en.wikipedia.org/wiki/ISCSI" target="_blank" rel="noopener noreferrer">iSCSI</a> provides an overview of iSCSI and contains references to additional material.</li><li><a href="https://en.wikipedia.org/wiki/Converged_network_adapter" target="_blank" rel="noopener noreferrer">Converged Network Adapter</a> provides a summary of CNAs and references to additional material.</li><li><a href="https://docs.harvesterhci.io/v1.2/troubleshooting/os/#how-to-permanently-edit-kernel-parameters" target="_blank" rel="noopener noreferrer">Harvester Docuementation</a> provides a general description of how to permanently edit kernel parameters to be used when booting a Harvester node.</li><li><a href="https://www.dell.com/support/manuals/en-us/poweredge-r630/r630_om_pub/uefi-iscsi-settings?guid=guid-adc7d625-5c7b-469d-ba9c-4a2c704fcc49&amp;lang=en-us" target="_blank" rel="noopener noreferrer">Dell PowerEdge R630 Owner's Manual</a> This is an example of relevant vendor documentation.  Other vendors such as HPE, IBM, Lenovo, etc should provide comparable documentation, though the details will vary.</li></ul>]]></content>
        <author>
            <name>Jeff Radick</name>
        </author>
        <category label="harvester" term="harvester"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Mitigating filesystem trim Risk]]></title>
        <id>the_potential_risk_with_filesystem_trim</id>
        <link href="https://harvesterhci.io/kb/the_potential_risk_with_filesystem_trim"/>
        <updated>2024-01-30T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[The potential risk with filesystem trim and how to avoid it]]></summary>
        <content type="html"><![CDATA[<p>Filesystem trim is a common way to release unused space in a filesystem. However, this operation is known to cause IO errors when used with Longhorn volumes that are rebuilding. For more information about the errors, see the following issues:</p><ul><li>Harvester: <a href="https://github.com/harvester/harvester/issues/4739" target="_blank" rel="noopener noreferrer">Issue 4793</a></li><li>Longhorn: <a href="https://github.com/longhorn/longhorn/issues/7103" target="_blank" rel="noopener noreferrer">Issue 7103</a></li></ul><div class="admonition admonition-info alert alert--info"><div class="admonition-heading"><h5><span class="admonition-icon"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>important</h5></div><div class="admonition-content"><p>Filesystem trim was introduced in Longhorn v1.4.0 because of <a href="https://github.com/longhorn/longhorn/issues/836" target="_blank" rel="noopener noreferrer">Issue 836</a>.</p><p>Longhorn volumes affected by the mentioned IO errors can disrupt operations in Harvester VMs that use those volumes. If you are using any of the affected Harvester versions, upgrade to a version with fixes or follow the instructions for risk mitigation in this article.</p><p><strong>Affected Harvester versions</strong>: v1.2.0 (uses Longhorn v1.4.3), v1.2.1 (uses Longhorn v1.4.3), and v1.3.0 (uses Longhorn v1.6.0)</p><p><strong>Harvester versions with fixes</strong>: v1.2.2 (uses Longhorn v1.5.5) and v1.3.1 (uses Longhorn v1.6.2)</p></div></div><h2 class="anchor anchorWithStickyNavbar_mojV" id="risks-associated-with-filesystem-trim">Risks Associated with Filesystem Trim<a class="hash-link" href="#risks-associated-with-filesystem-trim" title="Direct link to heading">​</a></h2><p>A consequence of the IO errors caused by filesystem trim is that VMs using affected Longhorn volumes become stuck. Imagine the VM is running critical applications, then becomes unavailable. This is significant because Harvester typically uses Longhorn volumes as VM disks. The IO errors will cause VMs to flap between running and paused states until volume rebuilding is completed.</p><p>Although the described system behavior does not affect data integrity, it might induce panic in some users. Consider the guest Kubernetes cluster scenario. In a stuck VM, the etcd service is unavailable. The effects of this failure cascade from the Kubernetes cluster becoming unavailable to services running on the cluster becoming unavailable.</p><h2 class="anchor anchorWithStickyNavbar_mojV" id="how-to-check-if-filesystem-trim-is-enabled">How to Check If Filesystem Trim Is Enabled<a class="hash-link" href="#how-to-check-if-filesystem-trim-is-enabled" title="Direct link to heading">​</a></h2><h3 class="anchor anchorWithStickyNavbar_mojV" id="linux">Linux<a class="hash-link" href="#linux" title="Direct link to heading">​</a></h3><p>In most Linux distributions, filesystem trim is enabled by default. You can check if the related service fstrim is enabled by running the following command:</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">$ systemctl status fstrim.timer</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">● fstrim.timer - Discard unused blocks once a week</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">     Loaded: loaded (/lib/systemd/system/fstrim.timer; enabled; vendor preset: enabled)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">     Active: active (waiting) since Mon 2024-03-18 03:40:24 UTC; 1 week 1 day ago</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    Trigger: Mon 2024-04-01 01:00:06 UTC; 5 days left</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">   Triggers: ● fstrim.service</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">       Docs: man:fstrim</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Mar 18 03:40:24 harvester-cluster-01-pool1-49b619f6-tpc4v systemd[1]: Started Discard unused blocks once a week.</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>When the fstrim.timer service is enabled, the system periodically runs fstrim.</p><h3 class="anchor anchorWithStickyNavbar_mojV" id="windows">Windows<a class="hash-link" href="#windows" title="Direct link to heading">​</a></h3><p>You can check if filesystem trim is enabled by running the following command:</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">C:\&gt; fsutil behavior query DisableDeleteNotify</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">NTFS DisableDeleteNotify = 0  (Allows TRIM operations to be sent to the storage device)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">ReFS DisableDeleteNotify = 0  (Allows TRIM operations to be sent to the storage device)</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p><code>DisableDeleteNotify = 0</code> indicates that TRIM operations are enabled. For more information, see <a href="https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/fsutil-behavior" target="_blank" rel="noopener noreferrer">fsutil behavior</a> in the Microsoft documentation.</p><h2 class="anchor anchorWithStickyNavbar_mojV" id="risk-mitigation">Risk Mitigation<a class="hash-link" href="#risk-mitigation" title="Direct link to heading">​</a></h2><h3 class="anchor anchorWithStickyNavbar_mojV" id="linux-1">Linux<a class="hash-link" href="#linux-1" title="Direct link to heading">​</a></h3><p>One way to mitigate the described risks is to disable fstrim services in VMs. fstrim services is enabled by default in many modern Linux distributions.
You can determine if fstrim is enabled in VMs that use affected Longhorn volumes by checking the following:</p><ul><li><p><code>/etc/fstab</code>: Some root filesystems mount with the <em>discard</em> option.</p><p>Example:</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">/dev/mapper/rootvg-rootlv /                       xfs     defaults,discard        0 0</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>You can disable fstrim on the root filesystem by removing the <em>discard</em> option.</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">/dev/mapper/rootvg-rootlv /                       xfs     defaults        0 0   &lt;-- remove the discard option</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>After removing the <em>discard</em> option, you can remount the root filesystem using the command <code>mount -o remount /</code> or by rebooting the VM.</p></li><li><p><code>fstrim.timer</code>: When this service is enabled, fstrim executes weekly by default. You can either disable the service or edit the service file to prevent simultaneous fstrim execution on VMs.</p><p>You can disable the service using the following command:</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">systemctl disable fstrim.timer</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>To prevent simultaneous fstrim execution, use the following values in the service file (located at <code>/usr/lib/systemd/system/fstrim.timer</code>):</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">[Timer]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">OnCalendar=weekly</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">AccuracySec=1h</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Persistent=true</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">RandomizedDelaySec=6000</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div></li></ul><h3 class="anchor anchorWithStickyNavbar_mojV" id="windows-1">Windows<a class="hash-link" href="#windows-1" title="Direct link to heading">​</a></h3><p>To mitigate the described risks, you can disable TRIM operations using the following commands:</p><ul><li><p>ReFS v2</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">C:\&gt; fsutil behavior set DisableDeleteNotify ReFS 1</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div></li><li><p>NTFS and ReFS v1</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">C:\&gt; fsutil behavior set DisableDeleteNotify 1</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div></li></ul>]]></content>
        <author>
            <name>Vicente Cheng</name>
            <uri>https://github.com/Vicente-Cheng</uri>
        </author>
        <category label="harvester" term="harvester"/>
        <category label="rancher integration" term="rancher integration"/>
        <category label="longhorn" term="longhorn"/>
        <category label="filesystem trim" term="filesystem trim"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Calculation of Resource Metrics in Harvester]]></title>
        <id>calculation_of_resource_metrics_in_harvester</id>
        <link href="https://harvesterhci.io/kb/calculation_of_resource_metrics_in_harvester"/>
        <updated>2024-01-23T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Understand how resource metrics are calculated.]]></summary>
        <content type="html"><![CDATA[<p>Harvester calculates the resource metrics using data that is dynamically collected from the system. Host-level resource metrics are calculated and then aggregated to obtain the cluster-level metrics.</p><p>You can view resource-related metrics on the Harvester UI.</p><ul><li><p><strong>Hosts</strong> screen: Displays host-level metrics</p><p><img loading="lazy" alt="host level resources metrics" src="/assets/images/host-resource-usage-3f7d2c16335caae1ef42aa94f62a0dcb.png" width="3198" height="606"></p></li><li><p><strong>Dashboard</strong> screen: Displays cluster-level metrics</p><p><img loading="lazy" alt="cluster level resources metrics" src="/assets/images/cluster-resource-usage-6165985252a3fce5f61a11807124c423.png" width="3168" height="488"></p></li></ul><h2 class="anchor anchorWithStickyNavbar_mojV" id="cpu-and-memory">CPU and Memory<a class="hash-link" href="#cpu-and-memory" title="Direct link to heading">​</a></h2><p>The following sections describe the data sources and calculation methods for CPU and memory resources.</p><ul><li>Resource capacity: Baseline data</li><li>Resource usage: Data source for the <strong>Used</strong> field on the <strong>Hosts</strong> screen</li><li>Resource reservation: Data source for the <strong>Reserved</strong> field on the <strong>Hosts</strong> screen</li></ul><h3 class="anchor anchorWithStickyNavbar_mojV" id="resource-capacity">Resource Capacity<a class="hash-link" href="#resource-capacity" title="Direct link to heading">​</a></h3><p>In Kubernetes, a <code>Node</code> object is created for each host.</p><p>The <code>.status.allocatable.cpu</code> and <code>.status.allocatable.memory</code> represent the available CPU and Memory resources of a host.</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain"># kubectl get nodes -A -oyaml</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">apiVersion: v1</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">items:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">- apiVersion: v1</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  kind: Node</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  metadata:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">..</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      management.cattle.io/pod-limits: '{"cpu":"12715m","devices.kubevirt.io/kvm":"1","devices.kubevirt.io/tun":"1","devices.kubevirt.io/vhost-net":"1","memory":"17104951040"}'</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      management.cattle.io/pod-requests: '{"cpu":"5657m","devices.kubevirt.io/kvm":"1","devices.kubevirt.io/tun":"1","devices.kubevirt.io/vhost-net":"1","ephemeral-storage":"50M","memory":"9155862208","pods":"78"}'</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      node.alpha.kubernetes.io/ttl: "0"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">..</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    name: harv41</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    resourceVersion: "2170215"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    uid: b6f5850a-2fbc-4aef-8fbe-121dfb671b67</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  spec:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    podCIDR: 10.52.0.0/24</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    podCIDRs:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    - 10.52.0.0/24</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    providerID: rke2://harv41</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  status:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    addresses:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    - address: 192.168.122.141</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      type: InternalIP</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    - address: harv41</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      type: Hostname</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    allocatable:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      cpu: "10"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      devices.kubevirt.io/kvm: 1k</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      devices.kubevirt.io/tun: 1k</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      devices.kubevirt.io/vhost-net: 1k</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      ephemeral-storage: "149527126718"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      hugepages-1Gi: "0"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      hugepages-2Mi: "0"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      memory: 20464216Ki</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      pods: "200"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    capacity:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      cpu: "10"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      devices.kubevirt.io/kvm: 1k</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      devices.kubevirt.io/tun: 1k</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      devices.kubevirt.io/vhost-net: 1k</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      ephemeral-storage: 153707984Ki</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      hugepages-1Gi: "0"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      hugepages-2Mi: "0"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      memory: 20464216Ki</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      pods: "200"</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><h3 class="anchor anchorWithStickyNavbar_mojV" id="resource-usage">Resource Usage<a class="hash-link" href="#resource-usage" title="Direct link to heading">​</a></h3><p>CPU and memory usage data is continuously collected and stored in the <code>NodeMetrics</code> object. Harvester reads the data from <code>usage.cpu</code> and <code>usage.memory</code>.</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain"># kubectl get NodeMetrics -A -oyaml</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">apiVersion: v1</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">items:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">- apiVersion: metrics.k8s.io/v1beta1</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  kind: NodeMetrics</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  metadata:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">...</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    name: harv41</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  timestamp: "2024-01-23T12:04:44Z"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  usage:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    cpu: 891736742n</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    memory: 9845008Ki</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  window: 10.149s</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><h3 class="anchor anchorWithStickyNavbar_mojV" id="resource-reservation">Resource Reservation<a class="hash-link" href="#resource-reservation" title="Direct link to heading">​</a></h3><p>Harvester dynamically calculates the resource limits and requests of all pods running on a host, and updates the information to the annotations of the <code>NodeMetrics</code> object.</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">      management.cattle.io/pod-limits: '{"cpu":"12715m",...,"memory":"17104951040"}'</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      management.cattle.io/pod-requests: '{"cpu":"5657m",...,"memory":"9155862208"}'</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>For more information, see <a href="https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#requests-and-limits" target="_blank" rel="noopener noreferrer">Requests and Limits</a> in the Kubernetes documentation.</p><h2 class="anchor anchorWithStickyNavbar_mojV" id="storage">Storage<a class="hash-link" href="#storage" title="Direct link to heading">​</a></h2><p>Longhorn is the default Container Storage Interface (CSI) driver of Harvester, providing storage management features such as distributed block storage and tiering.</p><h3 class="anchor anchorWithStickyNavbar_mojV" id="reserved-storage-in-longhorn">Reserved Storage in Longhorn<a class="hash-link" href="#reserved-storage-in-longhorn" title="Direct link to heading">​</a></h3><p>Longhorn allows you to specify the percentage of disk space that is not allocated to the default disk on each new Longhorn node. The default value is "30". For more information, see <a href="https://longhorn.io/docs/1.5.3/references/settings/#storage-reserved-percentage-for-default-disk" target="_blank" rel="noopener noreferrer">Storage Reserved Percentage For Default Disk</a> in the Longhorn documentation.</p><p>Depending on the disk size, you can modify the default value using the <a href="https://docs.harvesterhci.io/v1.2/troubleshooting/harvester/#access-embedded-rancher-and-longhorn-dashboards" target="_blank" rel="noopener noreferrer">embedded Longhorn UI</a>.</p><div class="admonition admonition-note alert alert--secondary"><div class="admonition-heading"><h5><span class="admonition-icon"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>note</h5></div><div class="admonition-content"><p>Before changing the settings, read the Longhorn documentation carefully.</p></div></div><h3 class="anchor anchorWithStickyNavbar_mojV" id="data-sources-and-calculation">Data Sources and Calculation<a class="hash-link" href="#data-sources-and-calculation" title="Direct link to heading">​</a></h3><p>Harvester uses the following data to calculate metrics for storage resources.</p><ul><li><p>Sum of the <code>storageMaximum</code> values of all disks (<code>status.diskStatus.disk-name</code>): Total storage capacity</p></li><li><p>Total storage capacity - Sum of the <code>storageAvailable</code> values of all disks (<code>status.diskStatus.disk-name</code>): Data source for the <strong>Used</strong> field on the <strong>Hosts</strong> screen</p></li><li><p>Sum of the <code>storageReserved</code> values of all disks (<code>spec.disks</code>): Data source for the <strong>Reserved</strong> field on the <strong>Hosts</strong> screen</p></li></ul><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain"># kubectl get nodes.longhorn.io -n longhorn-system -oyaml</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">apiVersion: v1</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">items:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">- apiVersion: longhorn.io/v1beta2</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  kind: Node</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  metadata:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">..</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    name: harv41</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    namespace: longhorn-system</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">..</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  spec:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    allowScheduling: true</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    disks:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      default-disk-ef11a18c36b01132:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        allowScheduling: true</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        diskType: filesystem</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        evictionRequested: false</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        path: /var/lib/harvester/defaultdisk</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        storageReserved: 24220101427</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        tags: []</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">..</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  status:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">..</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    diskStatus:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      default-disk-ef11a18c36b01132:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">..</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        diskType: filesystem</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        diskUUID: d2788933-8817-44c6-b688-dee414cc1f73</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        scheduledReplica:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          pvc-95561210-c39c-4c2e-ac9a-4a9bd72b3100-r-20affeca: 2147483648</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          pvc-9e83b2dc-6a4b-4499-ba70-70dc25b2d9aa-r-4ad05c86: 32212254720</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          pvc-bc25be1e-ca4e-4818-a16d-48353a0f2f96-r-c7b88c60: 3221225472</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          pvc-d9d3e54d-8d67-4740-861e-6373f670f1e4-r-f4c7c338: 2147483648</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          pvc-e954b5fe-bbd7-4d44-9866-6ff6684d5708-r-ba6b87b6: 5368709120</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        storageAvailable: 77699481600</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        storageMaximum:   80733671424</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        storageScheduled: 45097156608</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    region: ""</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    snapshotCheckStatus: {}</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    zone: ""</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div>]]></content>
        <author>
            <name>Jian Wang</name>
            <uri>https://github.com/w13915984028</uri>
        </author>
        <category label="harvester" term="harvester"/>
        <category label="resource metrics" term="resource metrics"/>
        <category label="reserved resource" term="reserved resource"/>
        <category label="calculation" term="calculation"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Best Practices for Optimizing Longhorn Disk Performance]]></title>
        <id>best_practices_for_optimizing_longhorn_disk_performance</id>
        <link href="https://harvesterhci.io/kb/best_practices_for_optimizing_longhorn_disk_performance"/>
        <updated>2023-12-27T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Follow the recommendations for achieving optimal disk performance.]]></summary>
        <content type="html"><![CDATA[<p>The Longhorn documentation provides <a href="https://longhorn.io/docs/1.6.0/best-practices/" target="_blank" rel="noopener noreferrer">best practice recommendations</a> for deploying Longhorn in production environments. Before configuring workloads, ensure that you have set up the following basic requirements for optimal disk performance.</p><ul><li>SATA/NVMe SSDs or disk drives with similar performance</li><li>10 Gbps network bandwidth between nodes</li><li>Dedicated Priority Classes for system-managed and user-deployed Longhorn components</li></ul><p>The following sections outline other recommendations for achieving optimal disk performance.</p><h2 class="anchor anchorWithStickyNavbar_mojV" id="io-performance">IO Performance<a class="hash-link" href="#io-performance" title="Direct link to heading">​</a></h2><ul><li><p><strong>Storage network</strong>: Use a <a href="https://docs.harvesterhci.io/v1.3/advanced/storagenetwork" target="_blank" rel="noopener noreferrer">dedicated storage network</a> to improve IO performance and stability.  </p></li><li><p><strong>Longhorn disk</strong>: Use a <a href="https://docs.harvesterhci.io/v1.3/host/#multi-disk-management" target="_blank" rel="noopener noreferrer">dedicated disk</a> for Longhorn storage instead of using the root disk.  </p></li><li><p><strong>Replica count</strong>: Set the <a href="https://docs.harvesterhci.io/v1.3/advanced/storageclass#parameters-tab" target="_blank" rel="noopener noreferrer">default replica count</a> to "2" to achieve data availability with better disk space usage or less impact to system performance. This practice is especially beneficial to data-intensive applications.  </p></li><li><p><strong>Storage tag</strong>: Use storage tags to define storage tiering for data-intensive applications. For example, only high-performance disks can be used for storing performance-sensitive data. You can either <a href="https://docs.harvesterhci.io/v1.3/host/#storage-tags" target="_blank" rel="noopener noreferrer">add disks with tags</a> or <a href="https://docs.harvesterhci.io/v1.3/advanced/storageclass#disk-selector-optional" target="_blank" rel="noopener noreferrer">create StorageClasses with tags</a>.  </p></li><li><p><strong>Data locality</strong>: Use <code>best-effort</code> as the default <a href="https://longhorn.io/docs/1.6.0/high-availability/data-locality/" target="_blank" rel="noopener noreferrer">data locality</a> of Longhorn Storage Classes.  </p><p>For applications that support data replication (for example, a distributed database), you can use the <code>strict-local</code> option to ensure that only one replica is created for each volume. This practice prevents the extra disk space usage and IO performance overhead associated with volume replication.  </p><p>For data-intensive applications, you can use pod scheduling functions such as node selector or taint toleration. These functions allow you to schedule the workload to a specific storage-tagged node together with one replica.  </p></li></ul><h2 class="anchor anchorWithStickyNavbar_mojV" id="space-efficiency">Space Efficiency<a class="hash-link" href="#space-efficiency" title="Direct link to heading">​</a></h2><ul><li><p><strong>Recurring snapshots</strong>: Periodically clean up system-generated snapshots and retain only the number of snapshots that makes sense for your implementation. </p><p>For applications with replication capability, periodically <a href="https://longhorn.io/docs/1.6.0/concepts/#243-deleting-snapshots" target="_blank" rel="noopener noreferrer">delete all types of snapshots</a>.</p></li></ul><h2 class="anchor anchorWithStickyNavbar_mojV" id="disaster-recovery">Disaster Recovery<a class="hash-link" href="#disaster-recovery" title="Direct link to heading">​</a></h2><ul><li><p><strong>Recurring backups</strong>: Create <a href="https://longhorn.io/docs/1.6.0/snapshots-and-backups/scheduling-backups-and-snapshots/" target="_blank" rel="noopener noreferrer">recurring backup jobs</a> for mission-critical application volumes.</p></li><li><p><strong>System backup</strong>: Run periodic system backups.</p></li></ul>]]></content>
        <author>
            <name>David Ko</name>
            <uri>https://github.com/innobead</uri>
        </author>
        <author>
            <name>Jillian Maroket</name>
            <uri>https://github.com/jillian-maroket/</uri>
        </author>
        <category label="harvester" term="harvester"/>
        <category label="longhorn" term="longhorn"/>
        <category label="best practices" term="best practices"/>
        <category label="disk performance" term="disk performance"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[VM Live Migration Policy and Configuration]]></title>
        <id>vm_live_migration_policy_and_configuration</id>
        <link href="https://harvesterhci.io/kb/vm_live_migration_policy_and_configuration"/>
        <updated>2023-09-01T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Know how VM live migration works, the migration policies, how to tune the policies and check status]]></summary>
        <content type="html"><![CDATA[<p>In Harvester, the <strong>VM Live Migration</strong> is well supported by the UI. Please refer to <a href="https://docs.harvesterhci.io/v1.1/vm/live-migration" target="_blank" rel="noopener noreferrer">Harvester VM Live Migration</a> for more details.</p><p>The VM Live Migration process is finished smoothly in most cases. However, sometimes the migration may get stuck and not end as expected.</p><p>This article dives into the VM Live Migration process in more detail. There are three main parts:</p><ul><li>General Process of VM Live Migration</li><li>VM Live Migration Strategies</li><li>VM Live Migration Configurations</li></ul><p>Related issues:</p><ul><li><a href="https://github.com/harvester/harvester/issues/4352" target="_blank" rel="noopener noreferrer">Migration should show the proper status and progress in the UI</a></li><li><a href="https://github.com/harvester/harvester/issues/4376" target="_blank" rel="noopener noreferrer">VM Migration policy and status</a></li></ul><div class="admonition admonition-note alert alert--secondary"><div class="admonition-heading"><h5><span class="admonition-icon"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>note</h5></div><div class="admonition-content"><p>A big part of the following contents are copied from <code>kubevirt</code> document <a href="https://kubevirt.io/user-guide/operations/live_migration/" target="_blank" rel="noopener noreferrer">https://kubevirt.io/user-guide/operations/live_migration/</a>, some contents/formats are adjusted to fit in this document.</p></div></div><h2 class="anchor anchorWithStickyNavbar_mojV" id="general-process-of-vm-live-migration">General Process of VM Live Migration<a class="hash-link" href="#general-process-of-vm-live-migration" title="Direct link to heading">​</a></h2><h3 class="anchor anchorWithStickyNavbar_mojV" id="starting-a-migration-from-harvester-ui">Starting a Migration from Harvester UI<a class="hash-link" href="#starting-a-migration-from-harvester-ui" title="Direct link to heading">​</a></h3><ol><li>Go to the <strong>Virtual Machines</strong> page.</li><li>Find the virtual machine that you want to migrate and select <strong>⋮</strong> &gt; <strong>Migrate</strong>.</li><li>Choose the node to which you want to migrate the virtual machine and select <strong>Apply</strong>.</li></ol><p>After successfully selecting <strong>Apply</strong>, a CRD <code>VirtualMachineInstanceMigration</code> object is created, and the related <code>controller/operator</code> will start the process.</p><h3 class="anchor anchorWithStickyNavbar_mojV" id="migration-crd-object">Migration CRD Object<a class="hash-link" href="#migration-crd-object" title="Direct link to heading">​</a></h3><p>You can also create the CRD <code>VirtualMachineInstanceMigration</code> object manually via <code>kubectl</code> or other tools.</p><p>The example below starts a migration process for a virtual machine instance (VMI) <code>new-vm</code>.</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">apiVersion: kubevirt.io/v1</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">kind: VirtualMachineInstanceMigration</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">metadata:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  name: migration-job</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">spec:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  vmiName: new-vm</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>Under the hood, the open source projects <code>Kubevirt, Libvirt, QEMU, ... </code> perform most of the <code>VM Live Migration</code>. <a href="#references">References.</a></p><h3 class="anchor anchorWithStickyNavbar_mojV" id="migration-status-reporting">Migration Status Reporting<a class="hash-link" href="#migration-status-reporting" title="Direct link to heading">​</a></h3><p>When starting a virtual machine instance (VMI), it has also been calculated whether the machine is live migratable. The result is being stored in the VMI <code>VMI.status.conditions</code>. The calculation can be based on multiple parameters of the VMI, however, at the moment, the calculation is largely based on the Access Mode of the VMI volumes. Live migration is only permitted when the volume access mode is set to ReadWriteMany. Requests to migrate a non-LiveMigratable VMI will be rejected.</p><p>The reported Migration Method is also being calculated during VMI start. <code>BlockMigration</code> indicates that some of the VMI disks require copying from the source to the destination. <code>LiveMigration</code> means that only the instance memory will be copied.</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">Status:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  Conditions:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    Status: True</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    Type: LiveMigratable</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  Migration Method: BlockMigration</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><h3 class="anchor anchorWithStickyNavbar_mojV" id="migration-status">Migration Status<a class="hash-link" href="#migration-status" title="Direct link to heading">​</a></h3><p>The migration progress status is reported in <code>VMI.status</code>. Most importantly, it indicates whether the migration has been completed or failed.</p><p>Below is an example of a successful migration.</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">Migration State:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    Completed:        true</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    End Timestamp:    2019-03-29T03:37:52Z</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    Migration Config:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      Completion Timeout Per GiB:  800</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      Progress Timeout:             150</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    Migration UID:                  c64d4898-51d3-11e9-b370-525500d15501</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    Source Node:                    node02</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    Start Timestamp:                2019-03-29T04:02:47Z</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    Target Direct Migration Node Ports:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      35001:                      0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      41068:                      49152</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      38284:                      49153</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    Target Node:                  node01</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    Target Node Address:          10.128.0.46</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    Target Node Domain Detected:  true</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    Target Pod:                   virt-launcher-testvmimcbjgw6zrzcmp8wpddvztvzm7x2k6cjbdgktwv8tkq</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><h2 class="anchor anchorWithStickyNavbar_mojV" id="vm-live-migration-strategies">VM Live Migration Strategies<a class="hash-link" href="#vm-live-migration-strategies" title="Direct link to heading">​</a></h2><p>VM Live Migration is a process during which a running Virtual Machine Instance moves to another compute node while the guest workload continues to run and remain accessible.</p><h3 class="anchor anchorWithStickyNavbar_mojV" id="understanding-different-vm-live-migration-strategies">Understanding Different VM Live Migration Strategies<a class="hash-link" href="#understanding-different-vm-live-migration-strategies" title="Direct link to heading">​</a></h3><p>VM Live Migration is a complex process. During a migration, the source VM needs to transfer its whole state (mainly RAM) to the target VM. If there are enough resources available, such as network bandwidth and CPU power, migrations should converge nicely. If this is not the scenario, however, the migration might get stuck without an ability to progress.</p><p>The main factor that affects migrations from the guest perspective is its dirty rate, which is the rate by which the VM dirties memory. Guests with high dirty rate lead to a race during migration. On the one hand, memory would be transferred continuously to the target, and on the other, the same memory would get dirty by the guest. On such scenarios, one could consider to use more advanced migration strategies. Refer to <a href="https://kubevirt.io/user-guide/operations/live_migration/#understanding-different-migration-strategies" target="_blank" rel="noopener noreferrer">Understanding different migration strategies</a> for more details.</p><p>There are 3 <code>VM Live Migration</code> strategies/policies:</p><h4 class="anchor anchorWithStickyNavbar_mojV" id="vm-live-migration-strategy-pre-copy">VM Live Migration Strategy: Pre-copy<a class="hash-link" href="#vm-live-migration-strategy-pre-copy" title="Direct link to heading">​</a></h4><p>Pre-copy is the default strategy. It should be used for most cases.</p><p>The way it works is as following:</p><ol><li>The target VM is created, but the guest keeps running on the source VM.</li><li>The source starts sending chunks of VM state (mostly memory) to the target. This continues until all of the state has been transferred to the target.</li><li>The guest starts executing on the target VM. 4. The source VM is being removed.</li></ol><p>Pre-copy is the safest and fastest strategy for most cases. Furthermore, it can be easily cancelled, can utilize multithreading, and more. If there is no real reason to use another strategy, this is definitely the strategy to go with.</p><p>However, on some cases migrations might not converge easily, that is, by the time the chunk of source VM state would be received by the target VM, it would already be mutated by the source VM (which is the VM the guest executes on). There are many reasons for migrations to fail converging, such as a high dirty-rate or low resources like network bandwidth and CPU. On such scenarios, see the following alternative strategies below.</p><h4 class="anchor anchorWithStickyNavbar_mojV" id="vm-live-migration-strategy-post-copy">VM Live Migration Strategy: Post-copy<a class="hash-link" href="#vm-live-migration-strategy-post-copy" title="Direct link to heading">​</a></h4><p>The way post-copy migrations work is as following:</p><ol><li>The target VM is created.</li><li>The guest is being run on the target VM.</li><li>The source starts sending chunks of VM state (mostly memory) to the target.</li><li>When the guest, running on the target VM, would access memory: 1. If the memory exists on the target VM, the guest can access it. 2. Otherwise, the target VM asks for a chunk of memory from the source VM.</li><li>Once all of the memory state is updated at the target VM, the source VM is being removed.</li></ol><p>The main idea here is that the guest starts to run immediately on the target VM. This approach has advantages and disadvantages:</p><p><strong>Advantages:</strong></p><ul><li>The same memory chink is never being transferred twice. This is possible due to the fact that with post-copy it doesn't matter that a page had been dirtied since the guest is already running on the target VM.</li><li>This means that a high dirty-rate has much less effect.</li><li>Consumes less network bandwidth.</li></ul><p><strong>Disadvantages:</strong></p><ul><li>When using post-copy, the VM state has no one source of truth. When the guest (running on the target VM) writes to memory, this memory is one part of the guest's state, but some other parts of it may still be updated only at the source VM. This situation is generally dangerous, since, for example, if either the target or guest VMs crash the state cannot be recovered.</li><li>Slow warmup: when the guest starts executing, no memory is present at the target VM. Therefore, the guest would have to wait for a lot of memory in a short period of time.</li><li>Slower than pre-copy on most cases.</li><li>Harder to cancel a migration.</li></ul><h4 class="anchor anchorWithStickyNavbar_mojV" id="vm-live-migration-strategy-auto-converge">VM Live Migration Strategy: Auto-converge<a class="hash-link" href="#vm-live-migration-strategy-auto-converge" title="Direct link to heading">​</a></h4><p>Auto-converge is a technique to help pre-copy migrations converge faster without changing the core algorithm of how the migration works.</p><p>Since a high dirty-rate is usually the most significant factor for migrations to not converge, auto-converge simply throttles the guest's CPU. If the migration would converge fast enough, the guest's CPU would not be throttled or throttled negligibly. But, if the migration would not converge fast enough, the CPU would be throttled more and more as time goes.</p><p>This technique dramatically increases the probability of the migration converging eventually.</p><h3 class="anchor anchorWithStickyNavbar_mojV" id="observe-the-vm-live-migration-progress-and-result">Observe the VM Live Migration Progress and Result<a class="hash-link" href="#observe-the-vm-live-migration-progress-and-result" title="Direct link to heading">​</a></h3><h4 class="anchor anchorWithStickyNavbar_mojV" id="migration-timeouts">Migration Timeouts<a class="hash-link" href="#migration-timeouts" title="Direct link to heading">​</a></h4><p>Depending on the type, the live migration process will copy virtual machine memory pages and disk blocks to the destination. During this process non-locked pages and blocks are being copied and become free for the instance to use again. To achieve a successful migration, it is assumed that the instance will write to the free pages and blocks (pollute the pages) at a lower rate than these are being copied.</p><h4 class="anchor anchorWithStickyNavbar_mojV" id="completion-time">Completion Time<a class="hash-link" href="#completion-time" title="Direct link to heading">​</a></h4><p>In some cases the virtual machine can write to different memory pages / disk blocks at a higher rate than these can be copied, which will prevent the migration process from completing in a reasonable amount of time. In this case, live migration will be aborted if it is running for a long period of time. The timeout is calculated base on the size of the VMI, it's memory and the ephemeral disks that are needed to be copied. The configurable parameter completionTimeoutPerGiB, which defaults to 800s is the time for GiB of data to wait for the migration to be completed before aborting it. A VMI with 8Gib of memory will time out after 6400 seconds.</p><h4 class="anchor anchorWithStickyNavbar_mojV" id="progress-timeout">Progress Timeout<a class="hash-link" href="#progress-timeout" title="Direct link to heading">​</a></h4><p>A VM Live Migration will also be aborted when it notices that copying memory doesn't make any progress. The time to wait for live migration to make progress in transferring data is configurable by the <code>progressTimeout</code> parameter, which defaults to 150 seconds.</p><h2 class="anchor anchorWithStickyNavbar_mojV" id="vm-live-migration-configurations">VM Live Migration Configurations<a class="hash-link" href="#vm-live-migration-configurations" title="Direct link to heading">​</a></h2><h3 class="anchor anchorWithStickyNavbar_mojV" id="changing-cluster-wide-migration-limits">Changing Cluster Wide Migration Limits<a class="hash-link" href="#changing-cluster-wide-migration-limits" title="Direct link to heading">​</a></h3><p>KubeVirt puts some limits in place so that migrations don't overwhelm the cluster. By default, it is to only run 5 migrations in parallel with an additional limit of a maximum of 2 outbound migrations per node. Finally, every migration is limited to a bandwidth of 64MiB/s.</p><p>You can change these values in the <code>kubevirt</code> CR:</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">    apiVersion: kubevirt.io/v1</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    kind: Kubevirt</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    metadata:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      name: kubevirt</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      namespace: kubevirt</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    spec:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      configuration:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        migrations:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          parallelMigrationsPerCluster: 5</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          parallelOutboundMigrationsPerNode: 2</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          bandwidthPerMigration: 64Mi</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          completionTimeoutPerGiB: 800</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          progressTimeout: 150</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          disableTLS: false</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          nodeDrainTaintKey: "kubevirt.io/drain"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          allowAutoConverge: false ---------------------&gt; related to: Auto-converge</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          allowPostCopy: false -------------------------&gt; related to: Post-copy</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          unsafeMigrationOverride: false</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>Remember that most of these configurations can be overridden and fine-tuned to a specified group of VMs. For more information, please refer to the Migration Policies section below.</p><h3 class="anchor anchorWithStickyNavbar_mojV" id="migration-policies">Migration Policies<a class="hash-link" href="#migration-policies" title="Direct link to heading">​</a></h3><p><a href="https://kubevirt.io/user-guide/operations/migration_policies/" target="_blank" rel="noopener noreferrer">Migration policies</a> provides a new way of applying migration configurations to Virtual Machines. The policies can refine Kubevirt CR's <code>MigrationConfiguration</code> that sets the cluster-wide migration configurations. This way, the cluster-wide settings default how the migration policy can be refined (i.e., changed, removed, or added).</p><p>Remember that migration policies are in version <code>v1alpha1</code>. This means that this API is not fully stable yet and that APIs may change in the future.</p><h4 class="anchor anchorWithStickyNavbar_mojV" id="migration-configurations">Migration Configurations<a class="hash-link" href="#migration-configurations" title="Direct link to heading">​</a></h4><p>Currently, the <code>MigrationPolicy</code> spec only includes the following configurations from Kubevirt CR's <code>MigrationConfiguration</code>. (In the future, more configurations that aren't part of Kubevirt CR will be added):</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">apiVersion: migrations.kubevirt.io/v1alpha1</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">kind: MigrationPolicy</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  spec:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    allowAutoConverge: true</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    bandwidthPerMigration: 217Ki</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    completionTimeoutPerGiB: 23</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    allowPostCopy: false</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>All the above fields are optional. When omitted, the configuration will be applied as defined in KubevirtCR's <code>MigrationConfiguration</code>. This way, KubevirtCR will serve as a configurable set of defaults for both VMs that are not bound to any <code>MigrationPolicy</code> and VMs that are bound to a <code>MigrationPolicy</code> that does not define all fields of the configurations.</p><h5 class="anchor anchorWithStickyNavbar_mojV" id="matching-policies-to-vms">Matching Policies to VMs<a class="hash-link" href="#matching-policies-to-vms" title="Direct link to heading">​</a></h5><p>Next in the spec are the selectors defining the group of VMs to apply the policy. The options to do so are the following.</p><p>This policy applies to the VMs in namespaces that have all the required labels:</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">apiVersion: migrations.kubevirt.io/v1alpha1</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">kind: MigrationPolicy</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  spec:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  selectors:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    namespaceSelector:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      hpc-workloads: true       # Matches a key and a value</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>The policy below applies to the VMs that have all the required labels:</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">apiVersion: migrations.kubevirt.io/v1alpha1</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">kind: MigrationPolicy</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  spec:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  selectors:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    virtualMachineInstanceSelector:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      workload-type: db       # Matches a key and a value</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><h2 class="anchor anchorWithStickyNavbar_mojV" id="references">References<a class="hash-link" href="#references" title="Direct link to heading">​</a></h2><h3 class="anchor anchorWithStickyNavbar_mojV" id="documents">Documents<a class="hash-link" href="#documents" title="Direct link to heading">​</a></h3><h3 class="anchor anchorWithStickyNavbar_mojV" id="libvirt-guest-migration">Libvirt Guest Migration<a class="hash-link" href="#libvirt-guest-migration" title="Direct link to heading">​</a></h3><p><code>Libvirt</code> has a chapter to describe the pricipal of <code>VM/Guest Live Migration</code>.</p><p><a href="https://libvirt.org/migration.html" target="_blank" rel="noopener noreferrer">https://libvirt.org/migration.html</a></p><h3 class="anchor anchorWithStickyNavbar_mojV" id="kubevirt-live-migration">Kubevirt Live Migration<a class="hash-link" href="#kubevirt-live-migration" title="Direct link to heading">​</a></h3><p><a href="https://kubevirt.io/user-guide/operations/live_migration/" target="_blank" rel="noopener noreferrer">https://kubevirt.io/user-guide/operations/live_migration/</a></p><h3 class="anchor anchorWithStickyNavbar_mojV" id="source-code">Source Code<a class="hash-link" href="#source-code" title="Direct link to heading">​</a></h3><p>The <code>VM Live Migration</code> related configuration options are passed to each layer correspondingly.</p><h4 class="anchor anchorWithStickyNavbar_mojV" id="kubevirt">Kubevirt<a class="hash-link" href="#kubevirt" title="Direct link to heading">​</a></h4><p><a href="https://github.com/kubevirt/kubevirt/blob/d425593ae392111dab80403ef0cde82625e37653/pkg/virt-launcher/virtwrap/live-migration-source.go#L103" target="_blank" rel="noopener noreferrer">https://github.com/kubevirt/kubevirt/blob/d425593ae392111dab80403ef0cde82625e37653/pkg/virt-launcher/virtwrap/live-migration-source.go#L103</a></p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">...</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">import "libvirt.org/go/libvirt"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">...</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">func generateMigrationFlags(isBlockMigration, migratePaused bool, options *cmdclient.MigrationOptions) libvirt.DomainMigrateFlags {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">...</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    if options.AllowAutoConverge {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        migrateFlags |= libvirt.MIGRATE_AUTO_CONVERGE</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    }</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    if options.AllowPostCopy {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        migrateFlags |= libvirt.MIGRATE_POSTCOPY</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    }</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">...</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">}</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><h4 class="anchor anchorWithStickyNavbar_mojV" id="go-package-libvirt">Go Package Libvirt<a class="hash-link" href="#go-package-libvirt" title="Direct link to heading">​</a></h4><p><a href="https://pkg.go.dev/libvirt.org/go/libvirt" target="_blank" rel="noopener noreferrer">https://pkg.go.dev/libvirt.org/go/libvirt</a></p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">const (</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">...</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    MIGRATE_AUTO_CONVERGE                 = DomainMigrateFlags(C.VIR_MIGRATE_AUTO_CONVERGE)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    MIGRATE_RDMA_PIN_ALL                  = DomainMigrateFlags(C.VIR_MIGRATE_RDMA_PIN_ALL)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    MIGRATE_POSTCOPY                      = DomainMigrateFlags(C.VIR_MIGRATE_POSTCOPY)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">...</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">)</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><h4 class="anchor anchorWithStickyNavbar_mojV" id="libvirt">Libvirt<a class="hash-link" href="#libvirt" title="Direct link to heading">​</a></h4><p><a href="https://github.com/libvirt/libvirt/blob/bfe53e9145cd5996a791c5caff0686572b850f82/include/libvirt/libvirt-domain.h#L1030" target="_blank" rel="noopener noreferrer">https://github.com/libvirt/libvirt/blob/bfe53e9145cd5996a791c5caff0686572b850f82/include/libvirt/libvirt-domain.h#L1030</a></p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">    /* Enable algorithms that ensure a live migration will eventually converge.</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">     * This usually means the domain will be slowed down to make sure it does</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">     * not change its memory faster than a hypervisor can transfer the changed</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">     * memory to the destination host. VIR_MIGRATE_PARAM_AUTO_CONVERGE_*</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">     * parameters can be used to tune the algorithm.</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">     *</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">     * Since: 1.2.3</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">     */</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    VIR_MIGRATE_AUTO_CONVERGE = (1 &lt;&lt; 13),</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">...</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">   /* Setting the VIR_MIGRATE_POSTCOPY flag tells libvirt to enable post-copy</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">     * migration. However, the migration will start normally and</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">     * virDomainMigrateStartPostCopy needs to be called to switch it into the</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">     * post-copy mode. See virDomainMigrateStartPostCopy for more details.</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">     *</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">     * Since: 1.3.3</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">     */</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    VIR_MIGRATE_POSTCOPY = (1 &lt;&lt; 15),</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div>]]></content>
        <author>
            <name>Jian Wang</name>
            <uri>https://github.com/w13915984028</uri>
        </author>
        <category label="harvester" term="harvester"/>
        <category label="virtual machine" term="virtual machine"/>
        <category label="VM" term="VM"/>
        <category label="live migration" term="live migration"/>
        <category label="policy" term="policy"/>
        <category label="strategy" term="strategy"/>
        <category label="configuration" term="configuration"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Use Rook Ceph External Storage with Harvester]]></title>
        <id>use_rook_ceph_external_storage</id>
        <link href="https://harvesterhci.io/kb/use_rook_ceph_external_storage"/>
        <updated>2023-08-23T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Use Rook Ceph External Storage with Harvester]]></summary>
        <content type="html"><![CDATA[<p>Starting with Harvester v1.2.0, it offers the capability to install a Container Storage Interface (CSI) in your Harvester cluster. This allows you to leverage external storage for the Virtual Machine's non-system data disk, giving you the flexibility to use different drivers tailored for specific needs, whether it's for performance optimization or seamless integration with your existing in-house storage solutions.</p><p>It's important to note that, despite this enhancement, the provisioner for the Virtual Machine (VM) image in Harvester still relies on Longhorn. Prior to version 1.2.0, Harvester exclusively supported Longhorn for storing VM data and did not offer support for external storage as a destination for VM data.</p><p>One of the options for integrating external storage with Harvester is Rook, an open-source cloud-native storage orchestrator. Rook provides a robust platform, framework, and support for Ceph storage, enabling seamless integration with cloud-native environments.</p><p><a href="https://ceph.io" target="_blank" rel="noopener noreferrer">Ceph</a> is a software-defined distributed storage system that offers versatile storage capabilities, including file, block, and object storage. It is designed for large-scale production clusters and can be deployed effectively in such environments.</p><p><a href="https://rook.io" target="_blank" rel="noopener noreferrer">Rook</a> simplifies the deployment and management of Ceph, offering self-managing, self-scaling, and self-healing storage services. It leverages Kubernetes resources to automate the deployment, configuration, provisioning, scaling, upgrading, and monitoring of Ceph.</p><p>In this article, we will walk you through the process of installing, configuring, and utilizing <a href="https://rook.io/docs/rook/v1.12/Getting-Started/intro/" target="_blank" rel="noopener noreferrer">Rook</a> to use storage from an <a href="https://www.rook.io/docs/rook/v1.12/CRDs/Cluster/external-cluster/" target="_blank" rel="noopener noreferrer">existing external Ceph cluster</a> as a data disk for a VM within the Harvester environment.</p><h2 class="anchor anchorWithStickyNavbar_mojV" id="install-harvester-cluster">Install Harvester Cluster<a class="hash-link" href="#install-harvester-cluster" title="Direct link to heading">​</a></h2><p>Harvester's operating system follows an immutable design, meaning that most OS files revert to their pre-configured state after a reboot. To accommodate Rook Ceph's requirements, you need to add specific persistent paths to the <code>os.persistentStatePaths</code> section in the <a href="https://docs.harvesterhci.io/dev/install/harvester-configuration#ospersistent_state_paths" target="_blank" rel="noopener noreferrer">Harvester configuration</a>. These paths include:</p><div class="codeBlockContainer_I0IT language-yaml theme-code-block"><div class="codeBlockContent_wNvx yaml"><pre tabindex="0" class="prism-code language-yaml codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token key atrule" style="color:#00a4db">os</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">persistent_state_paths</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> /var/lib/rook</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> /var/lib/ceph</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">modules</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> rbd</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> nbd</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>After the cluster is installed, refer to <a href="https://docs.harvesterhci.io/v1.1/faq#how-can-i-access-the-kubeconfig-file-of-the-harvester-cluster" target="_blank" rel="noopener noreferrer">How can I access the kubeconfig file of the Harvester cluster?</a> to get the kubeconfig of the Harvester cluster.</p><h2 class="anchor anchorWithStickyNavbar_mojV" id="install-rook-to-harvester">Install Rook to Harvester<a class="hash-link" href="#install-rook-to-harvester" title="Direct link to heading">​</a></h2><p>Install Rook to the Harvester cluster by referring to <a href="https://rook.io/docs/rook/v1.12/Getting-Started/quickstart/" target="_blank" rel="noopener noreferrer">Rook Quickstart</a>.</p><div class="codeBlockContainer_I0IT language-bash theme-code-block"><div class="codeBlockContent_wNvx bash"><pre tabindex="0" class="prism-code language-bash codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">curl</span><span class="token plain"> -fsSLo rook.tar.gz https://github.com/rook/rook/archive/refs/tags/v1.12.2.tar.gz </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token operator" style="color:#393A34">&amp;&amp;</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">tar</span><span class="token plain"> -zxf rook.tar.gz </span><span class="token operator" style="color:#393A34">&amp;&amp;</span><span class="token plain"> </span><span class="token builtin class-name">cd</span><span class="token plain"> rook-1.12.2/deploy/examples</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># apply configurations ref: https://rook.github.io/docs/rook/v1.12/Getting-Started/example-configurations/</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">kubectl apply -f crds.yaml -f common.yaml -f operator.yaml</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">kubectl -n rook-ceph </span><span class="token function" style="color:#d73a49">wait</span><span class="token plain"> --for</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">condition</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">Available deploy rook-ceph-operator --timeout</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">10m</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><h2 class="anchor anchorWithStickyNavbar_mojV" id="using-an-existing-external-ceph-cluster">Using an existing external Ceph cluster<a class="hash-link" href="#using-an-existing-external-ceph-cluster" title="Direct link to heading">​</a></h2><ol><li>Run the python script <code>create-external-cluster-resources.py</code> in the <a href="https://www.rook.io/docs/rook/v1.12/CRDs/Cluster/external-cluster/" target="_blank" rel="noopener noreferrer">existing external Ceph cluster</a> for creating all users and keys.</li></ol><div class="codeBlockContainer_I0IT language-bash theme-code-block"><div class="codeBlockContent_wNvx bash"><pre tabindex="0" class="prism-code language-bash codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic"># script help ref: https://www.rook.io/docs/rook/v1.12/CRDs/Cluster/external-cluster/#1-create-all-users-and-keys</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">curl</span><span class="token plain"> -s https://raw.githubusercontent.com/rook/rook/v1.12.2/deploy/examples/create-external-cluster-resources.py </span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> create-external-cluster-resources.py</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">python3 create-external-cluster-resources.py --rbd-data-pool-name </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain">pool_name</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> --namespace rook-ceph-external --format </span><span class="token function" style="color:#d73a49">bash</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><ol start="2"><li>Copy the Bash output.</li></ol><p>Example output:</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">export NAMESPACE=rook-ceph-external</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">export ROOK_EXTERNAL_FSID=b3b47828-4c60-11ee-be38-51902f85c805</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">export ROOK_EXTERNAL_USERNAME=client.healthchecker</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">export ROOK_EXTERNAL_CEPH_MON_DATA=ceph-1=192.168.5.99:6789</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">export ROOK_EXTERNAL_USER_SECRET=AQDd6/dkFyu/IhAATv/uCMbHtWk4AYK2KXzBhQ==</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">export ROOK_EXTERNAL_DASHBOARD_LINK=https://192.168.5.99:8443/</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">export CSI_RBD_NODE_SECRET=AQDd6/dk2HsjIxAA06Yw9UcOg0dfwV/9IFBRhA==</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">export CSI_RBD_NODE_SECRET_NAME=csi-rbd-node</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">export CSI_RBD_PROVISIONER_SECRET=AQDd6/dkEY1kIxAAAzrXZnVRf4x+wDUz1zyaQg==</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">export CSI_RBD_PROVISIONER_SECRET_NAME=csi-rbd-provisioner</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">export MONITORING_ENDPOINT=192.168.5.99</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">export MONITORING_ENDPOINT_PORT=9283</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">export RBD_POOL_NAME=test</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">export RGW_POOL_PREFIX=default</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><ol start="3"><li>Consume the external Ceph cluster resources on the Harvester cluster.</li></ol><div class="codeBlockContainer_I0IT language-bash theme-code-block"><div class="codeBlockContent_wNvx bash"><pre tabindex="0" class="prism-code language-bash codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic"># Paste the above output from create-external-cluster-resources.py into import-env.sh</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">vim</span><span class="token plain"> import-env.sh</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token builtin class-name">source</span><span class="token plain"> import-env.sh</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># this script will create a StorageClass ceph-rbd</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token builtin class-name">source</span><span class="token plain"> import-external-cluster.sh</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><div class="codeBlockContainer_I0IT language-bash theme-code-block"><div class="codeBlockContent_wNvx bash"><pre tabindex="0" class="prism-code language-bash codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">kubectl apply -f common-external.yaml</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">kubectl apply -f cluster-external.yaml</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># wait for all pods to become Ready</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">watch</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'kubectl --namespace rook-ceph get pods'</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><ol start="4"><li>Create the VolumeSnapshotClass <code>csi-rbdplugin-snapclass-external</code>.</li></ol><div class="codeBlockContainer_I0IT language-bash theme-code-block"><div class="codeBlockContent_wNvx bash"><pre tabindex="0" class="prism-code language-bash codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">cat</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain">./csi/rbd/snapshotclass-external.yaml </span><span class="token operator" style="color:#393A34">&lt;&lt;</span><span class="token string" style="color:#e3116c">EOF</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">---</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">apiVersion: snapshot.storage.k8s.io/v1</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">kind: VolumeSnapshotClass</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">metadata:</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">  name: csi-rbdplugin-snapclass-external</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">driver: rook-ceph.rbd.csi.ceph.com # driver:namespace:operator</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">parameters:</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">  clusterID: rook-ceph-external # namespace:cluster</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">  csi.storage.k8s.io/snapshotter-secret-name: rook-csi-rbd-provisioner</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">  csi.storage.k8s.io/snapshotter-secret-namespace: rook-ceph-external # namespace:cluster</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">deletionPolicy: Delete</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">EOF</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">kubectl apply -f ./csi/rbd/snapshotclass-external.yaml</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><h2 class="anchor anchorWithStickyNavbar_mojV" id="configure-harvester-cluster">Configure Harvester Cluster<a class="hash-link" href="#configure-harvester-cluster" title="Direct link to heading">​</a></h2><p>Before you can make use of Harvester's <strong>Backup &amp; Snapshot</strong> features, you need to set up some essential configurations through the Harvester <a href="https://docs.harvesterhci.io/v1.4/advanced/index#csi-driver-config" target="_blank" rel="noopener noreferrer">csi-driver-config</a> setting. To set up these configurations, follow these steps:</p><ol><li>Login to the Harvester UI, then navigate to <strong>Advanced</strong> &gt; <strong>Settings</strong>.</li><li>Find and select <strong>csi-driver-config</strong>, and then click on the <strong>⋮</strong> &gt; <strong>Edit Setting</strong> to access the configuration options.</li><li>In the settings, set the <strong>Provisioner</strong> to <code>rook-ceph.rbd.csi.ceph.com</code>.</li><li>Next, specify the <strong>Volume Snapshot Class Name</strong> as <code>csi-rbdplugin-snapclass-external</code>. This setting points to the name of the <code>VolumeSnapshotClass</code> used for creating volume snapshots or VM snapshots.</li><li>Similarly, set the <strong>Backup Volume Snapshot Class Name</strong> to <code>csi-rbdplugin-snapclass-external</code>. This corresponds to the name of the <code>VolumeSnapshotClass</code> responsible for creating VM backups.</li></ol><p><img loading="lazy" alt="csi-driver-config-external" src="/assets/images/csi-driver-config-external-59b885aff7095a9bda897ed59f289d82.png" width="3824" height="1848"></p><h2 class="anchor anchorWithStickyNavbar_mojV" id="use-rook-ceph-in-harvester">Use Rook Ceph in Harvester<a class="hash-link" href="#use-rook-ceph-in-harvester" title="Direct link to heading">​</a></h2><p>After successfully configuring these settings, you can proceed to utilize the Rook Ceph StorageClass, which is named <code>rook-ceph-block</code> for the internal Ceph cluster or named <code>ceph-rbd</code> for the external Ceph cluster. You can apply this StorageClass when creating an empty volume or adding a new block volume to a VM, enhancing your Harvester cluster's storage capabilities.</p><p>With these configurations in place, your Harvester cluster is ready to make the most of the Rook Ceph storage integration.</p><p><img loading="lazy" alt="rook-ceph-volume-external" src="/assets/images/rook-ceph-volume-external-974d73b9b863e95495c7b119d2c50954.png" width="3824" height="1848"></p><p><img loading="lazy" alt="rook-ceph-vm-external" src="/assets/images/rook-ceph-vm-external-4c1b4f6b6a6676e13d312cac3498d786.png" width="3824" height="1848"></p>]]></content>
        <author>
            <name>Hang Yu</name>
            <uri>https://github.com/futuretea</uri>
        </author>
        <category label="harvester" term="harvester"/>
        <category label="rook" term="rook"/>
        <category label="ceph" term="ceph"/>
        <category label="csi" term="csi"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Upgrade Guest Kubernetes Clusters to be Compatible with Harvester IP Pools]]></title>
        <id>upgrading_guest_clusters_with_harvester_ip_pool_compatibility</id>
        <link href="https://harvesterhci.io/kb/upgrading_guest_clusters_with_harvester_ip_pool_compatibility"/>
        <updated>2023-08-21T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Explain how to keep load balancer IP during upgrading guest cluster]]></summary>
        <content type="html"><![CDATA[<p>As <strong>Harvester v1.2.0</strong> is released, a new Harvester cloud provider version <strong>0.2.2</strong> is integrated into RKE2 <strong>v1.24.15+rke2r1</strong>, <strong>v1.25.11+rke2r1</strong>,  <strong>v1.26.6+rke2r1</strong>, <strong>v1.27.3+rke2r1</strong>, and newer versions.</p><p>With Harvester v1.2.0, the new Harvester cloud provider offers enhanced load balancing capabilities for guest Kubernetes services. Specifically, it introduces the Harvester IP Pool feature, a built-in IP address management (IPAM) solution for the Harvester load balancer. It allows you to define an IP pool specific to a particular guest cluster by specifying the guest cluster name. For example, you can create an IP pool exclusively for the guest cluster named cluster2:</p><p><img loading="lazy" alt="image" src="/assets/images/ippoolforcluster2-264c61833ccd9a79fb03dd73930d2401.png" width="3050" height="972"></p><p>However, after upgrading, the feature is not automatically compatible with existing guest Kubernetes clusters, as they do not pass the correct cluster name to the Harvester cloud provider. Refer to <a href="https://github.com/harvester/harvester/issues/4232" target="_blank" rel="noopener noreferrer">issue 4232</a> for more details. Users can manually upgrade the Harvester cloud provider using Helm as a workaround and provide the correct cluster name after upgrading. However, this would result in a change in the load balancer IPs. </p><p>This article outlines a workaround that allows you to leverage the new IP pool feature while keeping the load balancer IPs unchanged.</p><h2 class="anchor anchorWithStickyNavbar_mojV" id="prerequisites">Prerequisites<a class="hash-link" href="#prerequisites" title="Direct link to heading">​</a></h2><ul><li><p>Download the Harvester kubeconfig file from the Harvester UI. If you have imported Harvester into Rancher, do not use the kubeconfig file from the Rancher UI. Refer to <a href="https://docs.harvesterhci.io/v1.1/faq#how-can-i-access-the-kubeconfig-file-of-the-harvester-cluster" target="_blank" rel="noopener noreferrer">Access Harvester Cluster</a> to get the desired one.</p></li><li><p>Download the kubeconfig file for the guest Kubernetes cluster you plan to upgrade. Refer to <a href="https://ranchermanager.docs.rancher.com/how-to-guides/new-user-guides/manage-clusters/access-clusters/use-kubectl-and-kubeconfig#accessing-clusters-with-kubectl-from-your-workstation" target="_blank" rel="noopener noreferrer">Accessing Clusters with kubectl from Your Workstation</a> for instructions on how to download the kubeconfig file.</p></li></ul><h2 class="anchor anchorWithStickyNavbar_mojV" id="steps-to-keep-load-balancer-ip">Steps to Keep Load Balancer IP<a class="hash-link" href="#steps-to-keep-load-balancer-ip" title="Direct link to heading">​</a></h2><ol><li><p>Execute the following script before upgrading.</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">curl -sfL https://raw.githubusercontent.com/harvester/harvesterhci.io/main/kb/2023-08-21/keepip.sh | sh -s before_upgrade &lt;Harvester-kubeconfig-path&gt; &lt;guest-cluster-kubeconfig-path&gt; &lt;guest-cluster-name&gt; &lt;guest-cluster-nodes-namespace&gt;</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><ul><li><code>&lt;Harvester-kubeconfig-path&gt;</code>: Path to the Harvester kubeconfig file.</li><li><code>&lt;guest-cluster-kubeconfig-path&gt;</code>: Path to the kubeconfig file of your guest Kubernetes cluster.</li><li><code>&lt;guest-cluster-name&gt;</code>: Name of your guest cluster.</li><li><code>&lt;guest-cluster-nodes-namespace&gt;</code>: Namespace where the VMs of the guest cluster are located.</li></ul><p>The script will help users copy the DHCP information to the service annotation and modify the IP pool allocated history to make sure the IP is unchanged.</p><p><img loading="lazy" alt="image" src="/assets/images/before-upgrade-32da6d40ebe06324de4a258174ac6220.png" width="2196" height="780"></p><p>After executing the script, the load balancer service with DHCP mode will be annotated with the DHCP information. For example:</p><div class="codeBlockContainer_I0IT language-yaml theme-code-block"><div class="codeBlockContent_wNvx yaml"><pre tabindex="0" class="prism-code language-yaml codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token key atrule" style="color:#00a4db">apiVersion</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> v1</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">kind</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Service</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">metadata</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">annotations</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">kube-vip.io/hwaddr</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> 00</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">00</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">6c</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">4f</span><span class="token punctuation" style="color:#393A34">:</span><span class="token datetime number" style="color:#36acaa">18:68</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">kube-vip.io/requestedIP</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> 172.19.105.215</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> lb0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">namespace</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> default</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>As for the load balancer service with pool mode, the IP pool allocated history will be modified as the new load balancer name. For example:</p><div class="codeBlockContainer_I0IT language-yaml theme-code-block"><div class="codeBlockContent_wNvx yaml"><pre tabindex="0" class="prism-code language-yaml codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token key atrule" style="color:#00a4db">apiVersion</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> loadbalancer.harvesterhci.io/v1beta1</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">kind</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> IPPool</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">metadata</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> default</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">spec</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">status</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">allocatedHistory</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">192.168.100.2</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> default/cluster</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">name</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">default</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">lb1</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">ddc13071 </span><span class="token comment" style="color:#999988;font-style:italic"># replace the new load balancer name</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div></li><li><p>Add network selector for the pool.</p><p>For example, the following cluster is under the VM network <code>default/mgmt-untagged</code>. The network selector should be <code>default/mgmt-untagged</code>.</p><p><img loading="lazy" alt="image" src="/assets/images/network-ba7294269bf230843a11803191e20f1e.png" width="3498" height="1980"></p><p><img loading="lazy" alt="image" src="/assets/images/network-selector-0f179a6c97e2fa3621bcaadd8c09e39d.png" width="3054" height="1232"></p></li><li><p>Upgrade the RKE2 cluster in the Rancher UI and select the new version.</p><p><img loading="lazy" alt="image" src="/assets/images/upgrade-6356d7891793f5c94e25da1f6aa22944.png" width="3502" height="2052"></p></li><li><p>Execute the script after upgrading.</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">curl -sfL https://raw.githubusercontent.com/harvester/harvesterhci.io/main/kb/2023-08-21/keepip.sh | sh -s after_upgrade &lt;Harvester-kubeconfig-path&gt; &lt;guest-cluster-kubeconfig-path&gt; &lt;guest-cluster-name&gt; &lt;guest-cluster-nodes-namespace&gt;</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p><img loading="lazy" alt="image" src="/assets/images/before-upgrade-32da6d40ebe06324de4a258174ac6220.png" width="2196" height="780"></p><p> In this step, the script wraps the operations to upgrade the Harvester cloud provider to set the cluster name. After the Harvester cloud provider is running, the new Harvester load balancers will be created with the unchanged IPs.</p></li></ol>]]></content>
        <author>
            <name>Canwu Yao</name>
            <uri>https://github.com/yaocw2020</uri>
        </author>
        <category label="harvester" term="harvester"/>
        <category label="load balancer" term="load balancer"/>
        <category label="cloud provider" term="cloud provider"/>
        <category label="ip pool" term="ip pool"/>
        <category label="upgrade" term="upgrade"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Using NetApp Storage on Harvester]]></title>
        <id>install_netapp_trident_csi</id>
        <link href="https://harvesterhci.io/kb/install_netapp_trident_csi"/>
        <updated>2023-08-11T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Installation procedure for NetApp Astra Trident CSI Driver]]></summary>
        <content type="html"><![CDATA[<p>This article covers instructions for installing the Netapp Astra Trident CSI driver into a Harvester cluster, which enables NetApp storage systems to store storage volumes usable by virtual machines running in Harvester.</p><p>The NetApp storage will be an option in addition to the normal Longhorn storage; it will not replace Longhorn. Virtual machine images will still be stored using Longhorn.</p><p>This has been tested with Harvester 1.2.0 and Trident v23.07.0.</p><p>This procedure only works to access storage via iSCSI, not NFS.</p><div class="admonition admonition-note alert alert--secondary"><div class="admonition-heading"><h5><span class="admonition-icon"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>note</h5></div><div class="admonition-content"><p>3rd party storage classes (including those based on Trident) can only be used for non-boot volumes of Harvester VMs.</p></div></div><h1>Detailed Instructions</h1><p>We assume that before beginning this procedure, a Harvester cluster and a NetApp ONTAP storage system are both installed and configured for use.</p><p>Most of these steps can be performed on any system with the <code>helm</code> and <code>kubectl</code> commands installed and network connectivity to the management port of the Harvester cluster.  Let's call this your workstation.  Certain steps must be performed on one or more cluster nodes themselves.  The steps described below should be done on your workstation unless otherwise indicated.</p><p>The last step (enabling multipathd) should be done on all nodes after the Trident CSI has been installed.</p><p>Certain parameters of your installation will require modification of details in the examples in the procedure given below. Those which you may wish to modify include:</p><ul><li>The namespace.  <code>trident</code> is used as the namespace in the examples, but you may prefer to use another.</li><li>The name of the deployment. <code>mytrident</code> is used but you can change this to something else.</li><li>The management IP address of the ONTAP storage system</li><li>Login credentials (username and password) of the ONTAP storage system</li></ul><p>The procedure is as follows.</p><ol><li><p>Read the NetApp Astra Trident documentation:</p><ul><li><a href="https://docs.netapp.com/us-en/trident/" target="_blank" rel="noopener noreferrer">https://docs.netapp.com/us-en/trident/</a></li><li><a href="https://docs.netapp.com/us-en/trident/trident-get-started/kubernetes-deploy-operator.html" target="_blank" rel="noopener noreferrer">https://docs.netapp.com/us-en/trident/trident-get-started/kubernetes-deploy-operator.html</a></li><li><a href="https://docs.netapp.com/us-en/trident/trident-get-started/kubernetes-deploy-helm.html#deploy-the-trident-operator-and-install-astra-trident-using-helm" target="_blank" rel="noopener noreferrer">https://docs.netapp.com/us-en/trident/trident-get-started/kubernetes-deploy-helm.html#deploy-the-trident-operator-and-install-astra-trident-using-helm</a></li></ul><p>The simplest method is to install using Helm; that process is described here.</p></li><li><p>Download the KubeConfig from the Harvester cluster.</p><ul><li>Open the web UI for your Harvester cluster</li><li>In the lower left corner, click the "Support" link.  This will take you to a "Harvester Support" page.</li><li>Click the button labeled "Download KubeConfig".  This will download a your cluster config in a file called "local.yaml" by default.</li><li>Move this file to a convenient location and set your <code>KUBECONFIG</code> environment variable to the path of this file.</li></ul></li><li><p>Prepare the cluster for installation of the Helm chart.</p><p>Before starting installation of the helm chart, special authorization must be provided to enable certain modifications to be made during the installation.
This addresses the issue described here: <a href="https://github.com/NetApp/trident/issues/839" target="_blank" rel="noopener noreferrer">https://github.com/NetApp/trident/issues/839</a></p><ul><li><p>Put the following text into a file.  For this example we'll call it <code>authorize_trident.yaml</code>.</p><div class="codeBlockContainer_I0IT language-yaml theme-code-block"><div class="codeBlockContent_wNvx yaml"><pre tabindex="0" class="prism-code language-yaml codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">---</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">apiVersion</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> rbac.authorization.k8s.io/v1</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">kind</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ClusterRole</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">metadata</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> trident</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">operator</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">psa</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">rules</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">apiGroups</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> management.cattle.io</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">resources</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> projects</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">verbs</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> updatepsa</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">---</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">apiVersion</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> rbac.authorization.k8s.io/v1</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">kind</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ClusterRoleBinding</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">metadata</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> trident</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">operator</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">psa</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">roleRef</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">apiGroup</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> rbac.authorization.k8s.io</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">kind</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ClusterRole</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> trident</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">operator</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">psa</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">subjects</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">kind</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ServiceAccount</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> trident</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">operator</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">namespace</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> trident</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div></li><li><p>Apply this manifest via the command <code>kubectl apply -f authorize_trident.yaml</code>.</p></li></ul></li><li><p>Install the helm chart.</p><ul><li><p>First you will need to add the Astra Trident Helm repository:</p><div class="codeBlockContainer_I0IT language-shell theme-code-block"><div class="codeBlockContent_wNvx shell"><pre tabindex="0" class="prism-code language-shell codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">helm repo </span><span class="token function" style="color:#d73a49">add</span><span class="token plain"> netapp-trident https://netapp.github.io/trident-helm-chart</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div></li><li><p>Next, install the Helm chart.  This example uses <code>mytrident</code> as the deployment name, <code>trident</code> as the namespace, and 23.07.0 as the version number to install:</p><div class="codeBlockContainer_I0IT language-shell theme-code-block"><div class="codeBlockContent_wNvx shell"><pre tabindex="0" class="prism-code language-shell codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">helm </span><span class="token function" style="color:#d73a49">install</span><span class="token plain"> mytrident netapp-trident/trident-operator --version </span><span class="token number" style="color:#36acaa">23.07</span><span class="token plain">.0 --create-namespace --namespace trident</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div></li><li><p>The NetApp documentation describes variations on how you can do this.</p></li></ul></li><li><p>Download and extract the tridentctl command, which will be needed for the next few steps.</p><p>This and the next few steps need to be performed logged into a master node of the Harvester cluster, using root access.</p><div class="codeBlockContainer_I0IT language-shell theme-code-block"><div class="codeBlockContent_wNvx shell"><pre tabindex="0" class="prism-code language-shell codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token builtin class-name">cd</span><span class="token plain"> /tmp</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">curl</span><span class="token plain"> -L -o trident-installer-23.07.0.tar.gz https://github.com/NetApp/trident/releases/download/v23.07.0/trident-installer-23.07.0.tar.gz</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">tar</span><span class="token plain"> -xf trident-installer-23.07.0.tar.gz</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token builtin class-name">cd</span><span class="token plain"> trident-installer</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div></li><li><p>Install a backend.</p><p>This part is specific to Harvester.</p><ol><li><p>Put the following into a text file, for example /tmp/backend.yaml</p><div class="codeBlockContainer_I0IT language-yaml theme-code-block"><div class="codeBlockContent_wNvx yaml"><pre tabindex="0" class="prism-code language-yaml codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token key atrule" style="color:#00a4db">version</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">backendName</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> default_backend_san</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">storageDriverName</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ontap</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">san</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">economy</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">managementLIF</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> 172.19.97.114</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">svm</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> default_backend</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">username</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> admin</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">password</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> password1234</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">labels</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> default_backend_san</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>The LIF IP address, username, and password of this file
should be replaced with the management LIF and credentials
for the ONTAP system.</p></li><li><p>Create the backend</p><div class="codeBlockContainer_I0IT language-shell theme-code-block"><div class="codeBlockContent_wNvx shell"><pre tabindex="0" class="prism-code language-shell codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">./tridentctl create backend -f /tmp/backend.yaml -n trident</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div></li><li><p>Check that it is created</p><div class="codeBlockContainer_I0IT language-shell theme-code-block"><div class="codeBlockContent_wNvx shell"><pre tabindex="0" class="prism-code language-shell codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">./tridentctl get backend -n trident</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div></li></ol></li><li><p>Define a StorageClass and SnapshotClass.</p><ol><li><p>Put the following into a file, for example <code>/tmp/storage.yaml</code></p><div class="codeBlockContainer_I0IT language-yaml theme-code-block"><div class="codeBlockContent_wNvx yaml"><pre tabindex="0" class="prism-code language-yaml codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">---</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">apiVersion</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> storage.k8s.io/v1</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">kind</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> StorageClass</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">metadata</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ontap</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">san</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">economy</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">provisioner</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> csi.trident.netapp.io</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">parameters</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">selector</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"name=default_backend_san"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">---</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">apiVersion</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> snapshot.storage.k8s.io/v1</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">kind</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> VolumeSnapshotClass</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">metadata</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> csi</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">snapclass</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">driver</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> csi.trident.netapp.io</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">deletionPolicy</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Delete</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div></li><li><p>Apply the definitions:</p><div class="codeBlockContainer_I0IT language-shell theme-code-block"><div class="codeBlockContent_wNvx shell"><pre tabindex="0" class="prism-code language-shell codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">kubectl apply -f /tmp/storage.yaml</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div></li></ol></li><li><p>Enable multipathd</p><p>The following is required to enable multipathd.
This must be done on every node of the Harvester cluster, using root access.
The preceding steps should only be done once on a single node.</p><ol><li><p>Create this file in <code>/oem/99_multipathd.yaml</code>:</p><div class="codeBlockContainer_I0IT language-yaml theme-code-block"><div class="codeBlockContent_wNvx yaml"><pre tabindex="0" class="prism-code language-yaml codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token key atrule" style="color:#00a4db">stages</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">   </span><span class="token key atrule" style="color:#00a4db">default</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">   </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Setup multipathd"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token key atrule" style="color:#00a4db">systemctl</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">         </span><span class="token key atrule" style="color:#00a4db">enable</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">         </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> multipathd</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">         </span><span class="token key atrule" style="color:#00a4db">start</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">         </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> multipathd</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div></li><li><p>Configure <code>multipathd</code> to exclude pathnames used by Longhorn.</p><p>This part is a little tricky.  <code>multipathd</code> will automatically discover
device names matching a certain pattern, and attempt to set up multipathing on them.
Unfortunately, Longhorn's device names follow the same pattern, and
will not work correctly if <code>multipathd</code> tries to use those devices.</p><p>Therefore the file <code>/etc/multipath.conf</code> must be set up on each node
so as to prevent <code>multipathd</code> from touching any of the devices
that Longhorn will use.  Unfortunately, it is not possible to know
in advance which device names will be used until the volumes are attached
to a VM when the VM is started, or when the volumes are hot-added to a running VM.
The recommended method is to "whitelist" the Trident devices using device
properties rather than device naming.  The properties to allow are the
device vendor and product.  Here is an example of what you'll want in <code>/etc/multipath.conf</code>:</p><div class="codeBlockContainer_I0IT language-text theme-code-block"><div class="codeBlockContent_wNvx text"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">blacklist {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    device {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        vendor "!NETAPP"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        product "!LUN"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    }</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">}</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">blacklist_exceptions {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    device {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        vendor "NETAPP"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        product "LUN"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    }</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">}</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p> This example only works if NetApp is the only storage provider in the system for which <code>multipathd</code> must be used.  More complex environments will require more complex configuration.</p><p> Explicitly putting that content into <code>/etc/multipath.conf</code> will work when you start <code>multipathd</code> as described below, but the change in <code>/etc</code> will not persist across node reboots.  To solve that problem, you should add another file to <code>/oem</code> that will re-generate <code>/etc/multipath.conf</code> when the node reboots.  The following example will create the <code>/etc/multipath.conf</code> given in the example above, but may need to be modified for your environment if you have a more complex iSCSI configuration:</p><div class="codeBlockContainer_I0IT language-text theme-code-block"><div class="codeBlockContent_wNvx text"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">stages:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">   initramfs:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">     - name: "Configure multipath blacklist and whitelist"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">       files:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">       - path: /etc/multipath.conf</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">         permissions: 0644</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">         owner: 0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">         group: 0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">         content: |</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">           blacklist {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">               device {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                   vendor "!NETAPP"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                   product "!LUN"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                }</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            }</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            blacklist_exceptions {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                device {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                    vendor "NETAPP"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                    product "LUN"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                }</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            }</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p> Remember, this has to be done on every node.</p></li><li><p>Enable multipathd.</p><p>Adding the above files to <code>/oem</code> will take effect on the next reboot of the node; <code>multipathd</code> can be enabled immediately without rebooting the node using the following commands:</p><div class="codeBlockContainer_I0IT language-shell theme-code-block"><div class="codeBlockContent_wNvx shell"><pre tabindex="0" class="prism-code language-shell codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">systemctl </span><span class="token builtin class-name">enable</span><span class="token plain"> multipathd</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">systemctl start multipathd</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>  After the above steps, the <code>ontap-san-economy</code> storage class should be available when creating a volume for a Harvester VM.</p></li></ol></li></ol>]]></content>
        <author>
            <name>Jeff Radick</name>
        </author>
        <category label="harvester" term="harvester"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Configure PriorityClass on Longhorn System Components]]></title>
        <id>configure_priority_class_longhorn</id>
        <link href="https://harvesterhci.io/kb/configure_priority_class_longhorn"/>
        <updated>2023-07-25T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Configure priority classes on Longhorn system components]]></summary>
        <content type="html"><![CDATA[<p><strong>Harvester v1.2.0</strong>  introduces a new enhancement where Longhorn system-managed components in newly-deployed clusters are automatically assigned a <code>system-cluster-critical</code> priority class by default. However, when upgrading your Harvester clusters from previous versions, you may notice that Longhorn system-managed components do not have any priority class set.</p><p>This behavior is intentional and aimed at supporting zero-downtime upgrades. Longhorn does not allow changing the <code>priority-class</code> setting when attached volumes exist. For more details, please refer to <a href="https://longhorn.io/docs/1.4.3/advanced-resources/deploy/priority-class/#setting-priority-class-during-longhorn-installation" target="_blank" rel="noopener noreferrer">Setting Priority Class During Longhorn Installation</a>).</p><p>This article explains how to manually configure priority classes for Longhorn system-managed components after upgrading your Harvester cluster, ensuring that your Longhorn components have the appropriate priority class assigned and maintaining the stability and performance of your system.</p><h2 class="anchor anchorWithStickyNavbar_mojV" id="stop-all-virtual-machines">Stop all virtual machines<a class="hash-link" href="#stop-all-virtual-machines" title="Direct link to heading">​</a></h2><p>Stop all virtual machines (VMs) to detach all volumes. Please back up any work before doing this.</p><ol><li><p><a href="https://docs.harvesterhci.io/v1.1/troubleshooting/os#how-to-log-into-a-harvester-node" target="_blank" rel="noopener noreferrer">Login to a Harvester controller node and become root</a>.</p></li><li><p>Get all running VMs and write down their namespaces and names:</p><div class="codeBlockContainer_I0IT language-bash theme-code-block"><div class="codeBlockContent_wNvx bash"><pre tabindex="0" class="prism-code language-bash codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">kubectl get vmi -A</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>Alternatively, you can get this information by backing up the Virtual Machine Instance (VMI) manifests with the following command:</p><div class="codeBlockContainer_I0IT language-bash theme-code-block"><div class="codeBlockContent_wNvx bash"><pre tabindex="0" class="prism-code language-bash codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">kubectl get vmi -A -o json </span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> vmi-backup.json</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div></li><li><p>Shut down all VMs. Log in to all running VMs and shut them down gracefully (recommended). Or use the following command to send shutdown signals to all VMs:</p><div class="codeBlockContainer_I0IT language-bash theme-code-block"><div class="codeBlockContent_wNvx bash"><pre tabindex="0" class="prism-code language-bash codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">kubectl get vmi -A -o json </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> jq -r </span><span class="token string" style="color:#e3116c">'.items[] | [.metadata.name, .metadata.namespace] | @tsv'</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">while</span><span class="token plain"> </span><span class="token assign-left variable environment constant" style="color:#36acaa">IFS</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">$'</span><span class="token string entity" style="color:#36acaa">\t</span><span class="token string" style="color:#e3116c">'</span><span class="token plain"> </span><span class="token builtin class-name">read</span><span class="token plain"> -r name namespace</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">do</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"> -z </span><span class="token string" style="color:#e3116c">"</span><span class="token string variable" style="color:#36acaa">$name</span><span class="token string" style="color:#e3116c">"</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">then</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token builtin class-name">break</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token keyword" style="color:#00009f">fi</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token builtin class-name">echo</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Stop </span><span class="token string variable" style="color:#36acaa">${namespace}</span><span class="token string" style="color:#e3116c">/</span><span class="token string variable" style="color:#36acaa">${name}</span><span class="token string" style="color:#e3116c">"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      virtctl stop </span><span class="token variable" style="color:#36acaa">$name</span><span class="token plain"> -n </span><span class="token variable" style="color:#36acaa">$namespace</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">done</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><div class="admonition admonition-note alert alert--secondary"><div class="admonition-heading"><h5><span class="admonition-icon"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>note</h5></div><div class="admonition-content"><p>  You can also stop all VMs from the Harvester UI:</p><ol><li>Go to the <strong>Virtual Machines</strong> page.</li><li>For each VM, select <strong>⋮</strong> &gt; <strong>Stop</strong>.</li></ol></div></div></li><li><p>Ensure there are no running VMs:</p><p>Run the command:</p><div class="codeBlockContainer_I0IT language-bash theme-code-block"><div class="codeBlockContent_wNvx bash"><pre tabindex="0" class="prism-code language-bash codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">kubectl get vmi -A</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>The above command must return:</p><div class="codeBlockContainer_I0IT language-bash theme-code-block"><div class="codeBlockContent_wNvx bash"><pre tabindex="0" class="prism-code language-bash codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">No resources found</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div></li></ol><h2 class="anchor anchorWithStickyNavbar_mojV" id="scale-down-monitoring-pods">Scale down monitoring pods<a class="hash-link" href="#scale-down-monitoring-pods" title="Direct link to heading">​</a></h2><ol><li><p>Scale down the Prometheus deployment. Run the following command and wait for all Prometheus pods to terminate:</p><div class="codeBlockContainer_I0IT language-bash theme-code-block"><div class="codeBlockContent_wNvx bash"><pre tabindex="0" class="prism-code language-bash codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">kubectl patch -n cattle-monitoring-system prometheus/rancher-monitoring-prometheus --patch </span><span class="token string" style="color:#e3116c">'{"spec": {"replicas": 0}}'</span><span class="token plain"> --type merge </span><span class="token operator" style="color:#393A34">&amp;&amp;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">sleep</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">5</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;&amp;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    kubectl rollout status --watch</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">true -n cattle-monitoring-system statefulset/prometheus-rancher-monitoring-prometheus</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>A sample output looks like this:</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">prometheus.monitoring.coreos.com/rancher-monitoring-prometheus patched</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">statefulset rolling update complete 0 pods at revision prometheus-rancher-monitoring-prometheus-cbf6bd5f7...</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div></li><li><p>Scale down the AlertManager deployment. Run the following command and wait for all AlertManager pods to terminate:</p><div class="codeBlockContainer_I0IT language-bash theme-code-block"><div class="codeBlockContent_wNvx bash"><pre tabindex="0" class="prism-code language-bash codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">kubectl patch -n cattle-monitoring-system alertmanager/rancher-monitoring-alertmanager --patch </span><span class="token string" style="color:#e3116c">'{"spec": {"replicas": 0}}'</span><span class="token plain"> --type merge </span><span class="token operator" style="color:#393A34">&amp;&amp;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">sleep</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">5</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;&amp;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    kubectl rollout status --watch</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">true -n cattle-monitoring-system statefulset/alertmanager-rancher-monitoring-alertmanager</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>A sample output looks like this:</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">alertmanager.monitoring.coreos.com/rancher-monitoring-alertmanager patched</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">statefulset rolling update complete 0 pods at revision alertmanager-rancher-monitoring-alertmanager-c8c459dff...</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div></li><li><p>Scale down the Grafana deployment. Run the following command and wait for all Grafana pods to terminate:</p><div class="codeBlockContainer_I0IT language-bash theme-code-block"><div class="codeBlockContent_wNvx bash"><pre tabindex="0" class="prism-code language-bash codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">kubectl scale --replicas</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">0</span><span class="token plain"> deployment/rancher-monitoring-grafana -n cattle-monitoring-system </span><span class="token operator" style="color:#393A34">&amp;&amp;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">sleep</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">5</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;&amp;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    kubectl rollout status --watch</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">true -n cattle-monitoring-system deployment/rancher-monitoring-grafana</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>A sample output looks like this:</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">deployment.apps/rancher-monitoring-grafana scaled</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">deployment "rancher-monitoring-grafana" successfully rolled out</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div></li></ol><h2 class="anchor anchorWithStickyNavbar_mojV" id="scale-down-vm-import-controller-pods">Scale down vm-import-controller pods<a class="hash-link" href="#scale-down-vm-import-controller-pods" title="Direct link to heading">​</a></h2><ol><li><p>Check if the <a href="https://docs.harvesterhci.io/v1.1/advanced/vmimport" target="_blank" rel="noopener noreferrer"><code>vm-import-controller</code></a> addon is enabled and configured with a persistent volume with the following command:</p><div class="codeBlockContainer_I0IT language-bash theme-code-block"><div class="codeBlockContent_wNvx bash"><pre tabindex="0" class="prism-code language-bash codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">kubectl get pvc -n harvester-system harvester-vm-import-controller</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>If the above command returns an output like this, you must scale down the <code>vm-import-controller</code> pod. Otherwise, you can skip the following step.</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">NAME                             STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS         AGE</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">harvester-vm-import-controller   Bound    pvc-eb23e838-4c64-4650-bd8f-ba7075ab0559   200Gi      RWO            harvester-longhorn   2m53s</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div></li><li><p>Scale down the <code>vm-import-controller</code> pods with the following command:</p><div class="codeBlockContainer_I0IT language-bash theme-code-block"><div class="codeBlockContent_wNvx bash"><pre tabindex="0" class="prism-code language-bash codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">kubectl scale --replicas</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">0</span><span class="token plain"> deployment/harvester-vm-import-controller -n harvester-system </span><span class="token operator" style="color:#393A34">&amp;&amp;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">sleep</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">5</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;&amp;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    kubectl rollout status --watch</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">true -n harvester-system deployment/harvester-vm-import-controller</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>A sample output looks like this:</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">deployment.apps/harvester-vm-import-controller scaled</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">deployment "harvester-vm-import-controller" successfully rolled out</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div></li></ol><h2 class="anchor anchorWithStickyNavbar_mojV" id="set-the-priority-class-setting">Set the <code>priority-class</code> setting<a class="hash-link" href="#set-the-priority-class-setting" title="Direct link to heading">​</a></h2><ol><li><p>Before applying the <code>priority-class</code> setting, you need to verify all volumes are detached. Run the following command to verify the <code>STATE</code> of each volume is <code>detached</code>:</p><div class="codeBlockContainer_I0IT language-bash theme-code-block"><div class="codeBlockContent_wNvx bash"><pre tabindex="0" class="prism-code language-bash codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">kubectl get volumes.longhorn.io -A</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>Verify the output looks like this:</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">NAMESPACE         NAME                                       STATE      ROBUSTNESS   SCHEDULED   SIZE           NODE   AGE</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">longhorn-system   pvc-5743fd02-17a3-4403-b0d3-0e9b401cceed   detached   unknown                  5368709120            15d</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">longhorn-system   pvc-7e389fe8-984c-4049-9ba8-5b797cb17278   detached   unknown                  53687091200           15d</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">longhorn-system   pvc-8df64e54-ecdb-4d4e-8bab-28d81e316b8b   detached   unknown                  2147483648            15d</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">longhorn-system   pvc-eb23e838-4c64-4650-bd8f-ba7075ab0559   detached   unknown                  214748364800          11m</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div></li><li><p>Set the <code>priority-class</code> setting with the following command:</p><div class="codeBlockContainer_I0IT language-bash theme-code-block"><div class="codeBlockContent_wNvx bash"><pre tabindex="0" class="prism-code language-bash codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">kubectl patch -n longhorn-system settings.longhorn.io priority-class --patch </span><span class="token string" style="color:#e3116c">'{"value": "system-cluster-critical"}'</span><span class="token plain"> --type merge</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>Longhorn system-managed pods will restart and then you need to check if all the system-managed components have a priority class set:</p><p>Get the value of the priority class <code>system-cluster-critical</code>:</p><div class="codeBlockContainer_I0IT language-bash theme-code-block"><div class="codeBlockContent_wNvx bash"><pre tabindex="0" class="prism-code language-bash codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">kubectl get priorityclass system-cluster-critical</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>Verify the output looks like this:</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">NAME                      VALUE        GLOBAL-DEFAULT   AGE</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">system-cluster-critical   2000000000   false            15d</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div></li><li><p>Use the following command to get pods' priority in the <code>longhorn-system</code> namespace:</p><div class="codeBlockContainer_I0IT language-bash theme-code-block"><div class="codeBlockContent_wNvx bash"><pre tabindex="0" class="prism-code language-bash codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">kubectl get pods -n longhorn-system -o custom-columns</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"Name"</span><span class="token plain">:metadata.name,</span><span class="token string" style="color:#e3116c">"Priority"</span><span class="token plain">:.spec.priority</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div></li><li><p>Verify all system-managed components' pods have the correct priority. System-managed components include:</p><ul><li><code>csi-attacher</code></li><li><code>csi-provisioner</code></li><li><code>csi-resizer</code></li><li><code>csi-snapshotter</code></li><li><code>engine-image-ei</code></li><li><code>instance-manager-e</code></li><li><code>instance-manager-r</code></li><li><code>longhorn-csi-plugin</code></li></ul></li></ol><h2 class="anchor anchorWithStickyNavbar_mojV" id="scale-up-vm-import-controller-pods">Scale up vm-import-controller pods<a class="hash-link" href="#scale-up-vm-import-controller-pods" title="Direct link to heading">​</a></h2><p>If you scale down the <code>vm-import-controller</code> pods, you must scale it up again. </p><ol><li><p>Scale up the <code>vm-import-controller</code> pod. Run the command: </p><div class="codeBlockContainer_I0IT language-bash theme-code-block"><div class="codeBlockContent_wNvx bash"><pre tabindex="0" class="prism-code language-bash codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">kubectl scale --replicas</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">1</span><span class="token plain"> deployment/harvester-vm-import-controller -n harvester-system </span><span class="token operator" style="color:#393A34">&amp;&amp;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">sleep</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">5</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;&amp;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    kubectl rollout status --watch</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">true -n harvester-system deployment/harvester-vm-import-controller</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>A sample output looks like this:</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">deployment.apps/harvester-vm-import-controller scaled</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Waiting for deployment "harvester-vm-import-controller" rollout to finish: 0 of 1 updated replicas are available...</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">deployment "harvester-vm-import-controller" successfully rolled out</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div></li><li><p>Verify <code>vm-import-controller</code> is running using the following command:</p><div class="codeBlockContainer_I0IT language-bash theme-code-block"><div class="codeBlockContent_wNvx bash"><pre tabindex="0" class="prism-code language-bash codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">kubectl get pods --selector app.kubernetes.io/instance</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">vm-import-controller -A</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>A sample output looks like this, the pod's <code>STATUS</code> must be <code>Running</code>:</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">NAMESPACE          NAME                                              READY   STATUS    RESTARTS   AGE</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">harvester-system   harvester-vm-import-controller-6bd8f44f55-m9k86   1/1     Running   0          4m53s</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div></li></ol><h2 class="anchor anchorWithStickyNavbar_mojV" id="scale-up-monitoring-pods">Scale up monitoring pods<a class="hash-link" href="#scale-up-monitoring-pods" title="Direct link to heading">​</a></h2><ol><li><p>Scale up the Prometheus deployment. Run the following command and wait for all Prometheus pods to roll out:</p><div class="codeBlockContainer_I0IT language-bash theme-code-block"><div class="codeBlockContent_wNvx bash"><pre tabindex="0" class="prism-code language-bash codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">kubectl patch -n cattle-monitoring-system prometheus/rancher-monitoring-prometheus --patch </span><span class="token string" style="color:#e3116c">'{"spec": {"replicas": 1}}'</span><span class="token plain"> --type merge </span><span class="token operator" style="color:#393A34">&amp;&amp;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">sleep</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">5</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;&amp;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    kubectl rollout status --watch</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">true -n cattle-monitoring-system statefulset/prometheus-rancher-monitoring-prometheus</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>A sample output looks like:</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">prometheus.monitoring.coreos.com/rancher-monitoring-prometheus patched</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Waiting for 1 pods to be ready...</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">statefulset rolling update complete 1 pods at revision prometheus-rancher-monitoring-prometheus-cbf6bd5f7...</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div></li><li><p>Scale down the AlertManager deployment. Run the following command and wait for all AlertManager pods to roll out:</p><div class="codeBlockContainer_I0IT language-bash theme-code-block"><div class="codeBlockContent_wNvx bash"><pre tabindex="0" class="prism-code language-bash codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">kubectl patch -n cattle-monitoring-system alertmanager/rancher-monitoring-alertmanager --patch </span><span class="token string" style="color:#e3116c">'{"spec": {"replicas": 1}}'</span><span class="token plain"> --type merge </span><span class="token operator" style="color:#393A34">&amp;&amp;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">sleep</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">5</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;&amp;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    kubectl rollout status --watch</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">true -n cattle-monitoring-system statefulset/alertmanager-rancher-monitoring-alertmanager</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>A sample output looks like this:</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">alertmanager.monitoring.coreos.com/rancher-monitoring-alertmanager patched</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Waiting for 1 pods to be ready...</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">statefulset rolling update complete 1 pods at revision alertmanager-rancher-monitoring-alertmanager-c8bd4466c...</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div></li><li><p>Scale down the Grafana deployment. Run the following command and wait for all Grafana pods to roll out:</p><div class="codeBlockContainer_I0IT language-bash theme-code-block"><div class="codeBlockContent_wNvx bash"><pre tabindex="0" class="prism-code language-bash codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">kubectl scale --replicas</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">1</span><span class="token plain"> deployment/rancher-monitoring-grafana -n cattle-monitoring-system </span><span class="token operator" style="color:#393A34">&amp;&amp;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">sleep</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">5</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;&amp;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    kubectl rollout status --watch</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">true -n cattle-monitoring-system deployment/rancher-monitoring-grafana</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>A sample output looks like this:</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">deployment.apps/rancher-monitoring-grafana scaled</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Waiting for deployment "rancher-monitoring-grafana" rollout to finish: 0 of 1 updated replicas are available...</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">deployment "rancher-monitoring-grafana" successfully rolled out</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div></li></ol><h2 class="anchor anchorWithStickyNavbar_mojV" id="start-virtual-machines">Start virtual machines<a class="hash-link" href="#start-virtual-machines" title="Direct link to heading">​</a></h2><ol><li><p>Start a VM with the command:</p><div class="codeBlockContainer_I0IT language-bash theme-code-block"><div class="codeBlockContent_wNvx bash"><pre tabindex="0" class="prism-code language-bash codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">virtctl start </span><span class="token variable" style="color:#36acaa">$name</span><span class="token plain"> -n </span><span class="token variable" style="color:#36acaa">$namespace</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>Replace <code>$name</code> with the VM's name and <code>$namespace</code> with the VM's namespace. You can list all virtual machines with the command:</p><div class="codeBlockContainer_I0IT language-bash theme-code-block"><div class="codeBlockContent_wNvx bash"><pre tabindex="0" class="prism-code language-bash codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">kubectl get vms -A</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><div class="admonition admonition-note alert alert--secondary"><div class="admonition-heading"><h5><span class="admonition-icon"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>note</h5></div><div class="admonition-content"><p> You can also stop all VMs from the Harvester UI:</p><ol><li>Go to the <strong>Virtual Machines</strong> page.</li><li>For each VM, select <strong>⋮</strong> &gt; <strong>Start</strong>.</li></ol></div></div><p>Alternatively, you can start all running VMs with the following command:</p><div class="codeBlockContainer_I0IT language-bash theme-code-block"><div class="codeBlockContent_wNvx bash"><pre tabindex="0" class="prism-code language-bash codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">cat</span><span class="token plain"> vmi-backup.json </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> jq -r </span><span class="token string" style="color:#e3116c">'.items[] | [.metadata.name, .metadata.namespace] | @tsv'</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">while</span><span class="token plain"> </span><span class="token assign-left variable environment constant" style="color:#36acaa">IFS</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">$'</span><span class="token string entity" style="color:#36acaa">\t</span><span class="token string" style="color:#e3116c">'</span><span class="token plain"> </span><span class="token builtin class-name">read</span><span class="token plain"> -r name namespace</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">do</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"> -z </span><span class="token string" style="color:#e3116c">"</span><span class="token string variable" style="color:#36acaa">$name</span><span class="token string" style="color:#e3116c">"</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">then</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token builtin class-name">break</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token keyword" style="color:#00009f">fi</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token builtin class-name">echo</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Start </span><span class="token string variable" style="color:#36acaa">${namespace}</span><span class="token string" style="color:#e3116c">/</span><span class="token string variable" style="color:#36acaa">${name}</span><span class="token string" style="color:#e3116c">"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      virtctl start </span><span class="token variable" style="color:#36acaa">$name</span><span class="token plain"> -n </span><span class="token variable" style="color:#36acaa">$namespace</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">||</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">done</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div></li></ol>]]></content>
        <author>
            <name>Kiefer Chang</name>
            <uri>https://github.com/bk201</uri>
        </author>
        <category label="harvester" term="harvester"/>
        <category label="longhorn" term="longhorn"/>
        <category label="priority class" term="priority class"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Package your own Toolbox Image]]></title>
        <id>package_your_own_toolbox_image</id>
        <link href="https://harvesterhci.io/kb/package_your_own_toolbox_image"/>
        <updated>2023-07-06T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[How to package your own toolbox image]]></summary>
        <content type="html"><![CDATA[<p>Harvester OS is designed as an immutable operating system, which means you cannot directly install additional packages on it. While there is a way to <a href="https://docs.harvesterhci.io/dev/troubleshooting/os#how-can-i-install-packages-why-are-some-paths-read-only" target="_blank" rel="noopener noreferrer">install packages</a>, it is strongly advised against doing so, as it may lead to system instability.</p><p>If you only want to debug with the system, the preferred way is to package the toolbox image with all the needed packages. </p><p>This article shares how to package your toolbox image and how to install any packages on the toolbox image that help you debug the system.</p><p>For example, if you want to analyze a storage performance issue, you can install <code>blktrace</code> on the toolbox image.</p><h2 class="anchor anchorWithStickyNavbar_mojV" id="create-a-dockerfile">Create a Dockerfile<a class="hash-link" href="#create-a-dockerfile" title="Direct link to heading">​</a></h2><div class="codeBlockContainer_I0IT language-bash theme-code-block"><div class="codeBlockContent_wNvx bash"><pre tabindex="0" class="prism-code language-bash codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">FROM opensuse/leap:15.4</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># Install blktrace</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">RUN </span><span class="token function" style="color:#d73a49">zypper</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">in</span><span class="token plain"> -y </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    blktrace</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">RUN </span><span class="token function" style="color:#d73a49">zypper</span><span class="token plain"> clean --all</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><h2 class="anchor anchorWithStickyNavbar_mojV" id="build-the-image-and-push">Build the image and push<a class="hash-link" href="#build-the-image-and-push" title="Direct link to heading">​</a></h2><div class="codeBlockContainer_I0IT language-bash theme-code-block"><div class="codeBlockContent_wNvx bash"><pre tabindex="0" class="prism-code language-bash codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic"># assume you are in the directory of Dockerfile</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">$ </span><span class="token function" style="color:#d73a49">docker</span><span class="token plain"> build -t harvester/toolbox:dev </span><span class="token builtin class-name">.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token builtin class-name">.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token builtin class-name">.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token builtin class-name">.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">naming to docker.io/harvester/toolbox:dev </span><span class="token punctuation" style="color:#393A34">..</span><span class="token plain">.</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">$ </span><span class="token function" style="color:#d73a49">docker</span><span class="token plain"> push harvester/toolbox:dev</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token builtin class-name">.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token builtin class-name">.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">d4b76d0683d4: Pushed </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">a605baa225e2: Pushed </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">9e9058bdf63c: Layer already exists </span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>After you build and push the image, you can run the toolbox using this image to trace storage performance.</p><h2 class="anchor anchorWithStickyNavbar_mojV" id="run-the-toolbox">Run the toolbox<a class="hash-link" href="#run-the-toolbox" title="Direct link to heading">​</a></h2><div class="codeBlockContainer_I0IT language-bash theme-code-block"><div class="codeBlockContent_wNvx bash"><pre tabindex="0" class="prism-code language-bash codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic"># use `privileged` flag only when you needed. blktrace need debugfs, so I add extra mountpoint.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">docker</span><span class="token plain"> run -it --privileged -v /sys/kernel/debug/:/sys/kernel/debug/ --rm harvester/toolbox:dev </span><span class="token function" style="color:#d73a49">bash</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># test blktrace</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">6ffa8eda3aaf:/ $ blktrace -d /dev/nvme0n1 -o - </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> blkparse -i -</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token number" style="color:#36acaa">259,0</span><span class="token plain">   </span><span class="token number" style="color:#36acaa">10</span><span class="token plain">     </span><span class="token number" style="color:#36acaa">3414</span><span class="token plain">     </span><span class="token number" style="color:#36acaa">0.020814875</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">34084</span><span class="token plain">  Q  WS </span><span class="token number" style="color:#36acaa">2414127984</span><span class="token plain"> + </span><span class="token number" style="color:#36acaa">8</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">fio</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token number" style="color:#36acaa">259,0</span><span class="token plain">   </span><span class="token number" style="color:#36acaa">10</span><span class="token plain">     </span><span class="token number" style="color:#36acaa">3415</span><span class="token plain">     </span><span class="token number" style="color:#36acaa">0.020815190</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">34084</span><span class="token plain">  G  WS </span><span class="token number" style="color:#36acaa">2414127984</span><span class="token plain"> + </span><span class="token number" style="color:#36acaa">8</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">fio</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token number" style="color:#36acaa">259,0</span><span class="token plain">   </span><span class="token number" style="color:#36acaa">10</span><span class="token plain">     </span><span class="token number" style="color:#36acaa">3416</span><span class="token plain">     </span><span class="token number" style="color:#36acaa">0.020815989</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">34084</span><span class="token plain">  C  WS </span><span class="token number" style="color:#36acaa">3206896544</span><span class="token plain"> + </span><span class="token number" style="color:#36acaa">8</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token number" style="color:#36acaa">259,0</span><span class="token plain">   </span><span class="token number" style="color:#36acaa">10</span><span class="token plain">     </span><span class="token number" style="color:#36acaa">3417</span><span class="token plain">     </span><span class="token number" style="color:#36acaa">0.020816652</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">34084</span><span class="token plain">  C  WS </span><span class="token number" style="color:#36acaa">2140319184</span><span class="token plain"> + </span><span class="token number" style="color:#36acaa">8</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token number" style="color:#36acaa">259,0</span><span class="token plain">   </span><span class="token number" style="color:#36acaa">10</span><span class="token plain">     </span><span class="token number" style="color:#36acaa">3418</span><span class="token plain">     </span><span class="token number" style="color:#36acaa">0.020817992</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">34084</span><span class="token plain">  P   N </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">fio</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token number" style="color:#36acaa">259,0</span><span class="token plain">   </span><span class="token number" style="color:#36acaa">10</span><span class="token plain">     </span><span class="token number" style="color:#36acaa">3419</span><span class="token plain">     </span><span class="token number" style="color:#36acaa">0.020818227</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">34084</span><span class="token plain">  U   N </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">fio</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token number" style="color:#36acaa">259,0</span><span class="token plain">   </span><span class="token number" style="color:#36acaa">10</span><span class="token plain">     </span><span class="token number" style="color:#36acaa">3420</span><span class="token plain">     </span><span class="token number" style="color:#36acaa">0.020818437</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">34084</span><span class="token plain">  D  WS </span><span class="token number" style="color:#36acaa">2414127984</span><span class="token plain"> + </span><span class="token number" style="color:#36acaa">8</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">fio</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token number" style="color:#36acaa">259,0</span><span class="token plain">   </span><span class="token number" style="color:#36acaa">10</span><span class="token plain">     </span><span class="token number" style="color:#36acaa">3421</span><span class="token plain">     </span><span class="token number" style="color:#36acaa">0.020821826</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">34084</span><span class="token plain">  Q  WS </span><span class="token number" style="color:#36acaa">1743934904</span><span class="token plain"> + </span><span class="token number" style="color:#36acaa">8</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">fio</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token number" style="color:#36acaa">259,0</span><span class="token plain">   </span><span class="token number" style="color:#36acaa">10</span><span class="token plain">     </span><span class="token number" style="color:#36acaa">3422</span><span class="token plain">     </span><span class="token number" style="color:#36acaa">0.020822150</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">34084</span><span class="token plain">  G  WS </span><span class="token number" style="color:#36acaa">1743934904</span><span class="token plain"> + </span><span class="token number" style="color:#36acaa">8</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">fio</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div>]]></content>
        <author>
            <name>Vicente Cheng</name>
            <uri>https://github.com/Vicente-Cheng</uri>
        </author>
        <category label="debug" term="debug"/>
        <category label="harvester" term="harvester"/>
        <category label="container" term="container"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Scan and Repair Root Filesystem of VirtualMachine]]></title>
        <id>scan-and-repair-vm-root-filesystem</id>
        <link href="https://harvesterhci.io/kb/scan-and-repair-vm-root-filesystem"/>
        <updated>2023-02-01T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Scan and repair root filesystem of VM]]></summary>
        <content type="html"><![CDATA[<p>In earlier versions of Harvester (v1.0.3 and prior), Longhorn volumes may get corrupted during the replica rebuilding process (reference: <a href="https://longhorn.io/kb/troubleshooting-volume-filesystem-corruption/#solution" target="_blank" rel="noopener noreferrer">Analysis: Potential Data/Filesystem Corruption</a>). In Harvester v1.1.0 and later versions, the Longhorn team has fixed this issue. This article covers manual steps you can take to scan the VM's filesystem and repair it if needed.</p><h2 class="anchor anchorWithStickyNavbar_mojV" id="stop-the-vm-and-backup-volume">Stop The VM And Backup Volume<a class="hash-link" href="#stop-the-vm-and-backup-volume" title="Direct link to heading">​</a></h2><p>Before you scan the filesystem, it is recommend you back up the volume first. For an example, refer to the following steps to stop the VM and backup the volume.</p><ul><li>Find the target VM.</li></ul><p><img loading="lazy" alt="finding the target VM" src="/assets/images/finding_the_target_vm-c3f5c227fdeda94499a32e880a302e80.png" width="2560" height="880"></p><ul><li>Stop the target VM.</li></ul><p><img loading="lazy" alt="Stop the target VM" src="/assets/images/stop_the_target_vm-35b68914885fd42f4b7310aa849f944f.png" width="2546" height="856"></p><p>The target VM is stopped and the related volumes are detached. Now go to the Longhorn UI to backup this volume.</p><ul><li>Enable <code>Developer Tools &amp; Features</code> (Preferences -&gt; Enable Developer Tools &amp; Features).</li></ul><p><img loading="lazy" alt="Preferences then enable developer mode" src="/assets/images/preferences_enable_developer_mode-1379680f02f9980091177736ed7ce523.png" width="2570" height="1090">
<img loading="lazy" alt="Enable the developer mode" src="/assets/images/enable_the_developer_mode-8dffb1796b8e5da9863d6c69ad7f0209.png" width="2760" height="350"></p><ul><li>Click the <code>⋮</code> button and select <strong>Edit Config</strong> to edit the config page of the VM.</li></ul><p><img loading="lazy" alt="goto edit config page of VM" src="/assets/images/goto_vm_edit_config_page-52e958d3a5e04c912e77615d3ab05616.png" width="2526" height="964"></p><ul><li>Go to the <code>Volumes</code> tab and select <code>Check volume details.</code></li></ul><p><img loading="lazy" alt="link to longhorn volume page" src="/assets/images/link_to_longhorn_volume-ced67ce270fd55fa7ff5a73c651ae940.png" width="2522" height="1372"></p><ul><li>Click the dropdown menu on the right side and select 'Attach' to attach the volume again. </li></ul><p><img loading="lazy" alt="attach this volume again" src="/assets/images/attach_this_volume_again-f008c1d56b9cdfa2b141e30093cc51fe.png" width="2972" height="1358"></p><ul><li>Select the attached node. </li></ul><p><img loading="lazy" alt="choose the attached node" src="/assets/images/choose_the_attached_node-cde38647a09abf50189b40f5a37da9cb.png" width="2964" height="1362"></p><ul><li>Check the volume attached under <code>Volume Details</code> and select <code>Take Snapshot</code> on this volume page.</li></ul><p><img loading="lazy" alt="take snapshot on volume page" src="/assets/images/take_snapshot_on_volume_page-fe966d238b47aea3360b6f5c55664846.png" width="2976" height="1358"></p><ul><li>Confirm that the snapshot is ready.</li></ul><p><img loading="lazy" alt="check the snapshot is ready" src="/assets/images/check_the_snapshot_is_ready-7f0716b1b699c668c11ad5b5b46596b0.png" width="2968" height="1356"></p><p>Now that you completed the volume backup, you need to scan and repair the root filesystem.</p><h2 class="anchor anchorWithStickyNavbar_mojV" id="scanning-the-root-filesystem-and-repairing">Scanning the root filesystem and repairing<a class="hash-link" href="#scanning-the-root-filesystem-and-repairing" title="Direct link to heading">​</a></h2><p>This section will introduce how to scan the filesystem (e.g., XFS, EXT4) using related tools.</p><p>Before scanning, you need to know the filesystem's device/partition.</p><ul><li>Identify the filesystem's device by checking the major and minor numbers of that device.</li></ul><ol><li><p>Obtain the major and minor numbers from the listed volume information.</p><p>In the following example, the volume name is <code>pvc-ea7536c0-301f-479e-b2a2-e40ddc864b58</code>.</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">harvester-node-0:~ # ls /dev/longhorn/pvc-ea7536c0-301f-479e-b2a2-e40ddc864b58 -al</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">brw-rw---- 1 root root 8, 0 Oct 23 14:43 /dev/longhorn/pvc-ea7536c0-301f-479e-b2a2-e40ddc864b58</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>The output indicates that the major and minor numbers are <code>8:0</code>.</p></li><li><p>Obtain the device name from the output of the <code>lsblk</code> command.</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">harvester-node-0:~ # lsblk</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">loop0    7:0    0     3G  1 loop /</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">sda      8:0    0    40G  0 disk</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">├─sda1   8:1    0     2M  0 part</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">├─sda2   8:2    0    20M  0 part</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">└─sda3   8:3    0    40G  0 part</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>The output indicates that <code>8:0</code> are the major and minor numbers of the device named <code>sda</code>. Therefore, <code>/dev/sda</code> is related to the volume named <code>pvc-ea7536c0-301f-479e-b2a2-e40ddc864b58</code>.</p></li></ol><ul><li>You should now know the filesystem's partition. In the example below, sda3 is the filesystem's partition.</li><li>Use the Filesystem toolbox image to scan and repair.</li></ul><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain"># docker run -it --rm --privileged registry.opensuse.org/isv/rancher/harvester/toolbox/main/fs-toolbox:latest -- bash</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>Then we try to scan with this target device.</p><h3 class="anchor anchorWithStickyNavbar_mojV" id="xfs">XFS<a class="hash-link" href="#xfs" title="Direct link to heading">​</a></h3><p>When scanning an XFS filesystem, use the <code>xfs_repair</code> command and specify the problematic partition of the device.</p><p>In the following example, <code>/dev/sda3</code> is the problematic partition.</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain"># xfs_repair -n /dev/sda3</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>To repair the corrupted partition, run the following command.</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain"># xfs_repair /dev/sda3</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><h3 class="anchor anchorWithStickyNavbar_mojV" id="ext4">EXT4<a class="hash-link" href="#ext4" title="Direct link to heading">​</a></h3><p>When scanning a EXT4 filesystem, use the <code>e2fsck</code> command as follows, where the <code>/dev/sde1</code> is the problematic partition of the device.</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain"># e2fsck -f /dev/sde1</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>To repair the corrupted partition, run the following command.</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain"># e2fsck -fp /dev/sde1</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>After using the 'e2fsck' command, you should also see logs related to scanning and repairing the partition. Scanning and repairing the corrupted partition is successful if there are no errors in these logs. </p><h2 class="anchor anchorWithStickyNavbar_mojV" id="detach-and-start-vm-again">Detach and Start VM again.<a class="hash-link" href="#detach-and-start-vm-again" title="Direct link to heading">​</a></h2><p>After the corrupted partition is scanned and repaired, detach the volume and try to start the related VM again.</p><ul><li>Detach the volume from the Longhorn UI.</li></ul><p><img loading="lazy" alt="detach volume on longhorn UI" src="/assets/images/detach_volume-a71a0c79f0a6052fd5ecb562bf532b71.png" width="2964" height="1364"></p><ul><li>Start the related VM again from the Harvester UI.</li></ul><p><img loading="lazy" alt="Start VM again" src="/assets/images/start_vm_again-6ce38c23de061f1587da9e4f8698b7e8.png" width="2540" height="854"></p><p>Your VM should now work normally.</p>]]></content>
        <author>
            <name>Vicente Cheng</name>
            <uri>https://github.com/Vicente-Cheng</uri>
        </author>
        <category label="storage" term="storage"/>
        <category label="longhorn" term="longhorn"/>
        <category label="root" term="root"/>
        <category label="filesystem" term="filesystem"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Evicting Replicas From a Disk (the CLI way)]]></title>
        <id>evicting-replicas-from-a-disk-the-cli-way</id>
        <link href="https://harvesterhci.io/kb/evicting-replicas-from-a-disk-the-cli-way"/>
        <updated>2023-01-12T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Evicting replicas from a disk (the CLI way)]]></summary>
        <content type="html"><![CDATA[<p>Harvester replicates volumes data across disks in a cluster. Before removing a disk, the user needs to evict replicas on the disk to other disks to preserve the volumes' configured availability. For more information about eviction in Longhorn, please check <a href="https://longhorn.io/docs/1.3.2/volumes-and-nodes/disks-or-nodes-eviction/" target="_blank" rel="noopener noreferrer">Evicting Replicas on Disabled Disks or Nodes</a>.</p><h2 class="anchor anchorWithStickyNavbar_mojV" id="preparation">Preparation<a class="hash-link" href="#preparation" title="Direct link to heading">​</a></h2><p>This document describes how to evict Longhorn disks using the <code>kubectl</code> command. Before that, users must ensure the environment is set up correctly.
There are two recommended ways to do this:</p><ol><li>Log in to any management node and switch to root (<code>sudo -i</code>).</li><li>Download Kubeconfig file and use it locally<ul><li>Install <code>kubectl</code> and <code>yq</code> program manually.</li><li>Open Harvester GUI,  click <code>support</code> at the bottom left of the page and click <code>Download KubeConfig</code> to download the Kubeconfig file.</li><li>Set the Kubeconfig file's path to <code>KUBECONFIG</code> environment variable. For example, <code>export KUBECONFIG=/path/to/kubeconfig</code>.</li></ul></li></ol><h2 class="anchor anchorWithStickyNavbar_mojV" id="evicting-replicas-from-a-disk">Evicting replicas from a disk<a class="hash-link" href="#evicting-replicas-from-a-disk" title="Direct link to heading">​</a></h2><ol><li><p>List Longhorn nodes (names are identical to Kubernetes nodes):</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">kubectl get -n longhorn-system nodes.longhorn.io</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>Sample output:</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">NAME    READY   ALLOWSCHEDULING   SCHEDULABLE   AGE</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">node1   True    true              True          24d</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">node2   True    true              True          24d</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">node3   True    true              True          24d</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div></li><li><p>List disks on a node. Assume we want to evict replicas of a disk on <code>node1</code>:</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">kubectl get -n longhorn-system nodes.longhorn.io node1 -o yaml | yq e '.spec.disks'</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>Sample output:</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">default-disk-ed7af10f5b8356be:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  allowScheduling: true</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  evictionRequested: false</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  path: /var/lib/harvester/defaultdisk</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  storageReserved: 36900254515</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  tags: []</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div></li><li><p>Assume disk <code>default-disk-ed7af10f5b8356be</code> is the target we want to evict replicas out of.</p><p>Edit the node:</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">kubectl edit -n longhorn-system nodes.longhorn.io node1 </span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>Update these two fields and save:</p><ul><li><code>spec.disks.&lt;disk_name&gt;.allowScheduling</code> to <code>false</code></li><li><code>spec.disks.&lt;disk_name&gt;.evictionRequested</code> to <code>true</code></li></ul><p>Sample editing:</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">default-disk-ed7af10f5b8356be:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  allowScheduling: false</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  evictionRequested: true</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  path: /var/lib/harvester/defaultdisk</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  storageReserved: 36900254515</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  tags: []</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div></li><li><p>Wait for all replicas on the disk to be evicted.</p><p>Get current scheduled replicas on the disk:</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">kubectl get -n longhorn-system nodes.longhorn.io node1 -o yaml | yq e '.status.diskStatus.default-disk-ed7af10f5b8356be.scheduledReplica'</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>Sample output:</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">pvc-86d3d212-d674-4c64-b69b-4a2eb1df2272-r-7b422db7: 5368709120</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">pvc-b06f0b09-f30c-4936-8a2a-425b993dd6cb-r-bb0fa6b3: 2147483648</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">pvc-b844bcc6-3b06-4367-a136-3909251cb560-r-08d1ab3c: 53687091200</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">pvc-ea6e0dff-f446-4a38-916a-b3bea522f51c-r-193ca5c6: 10737418240</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>Run the command repeatedly, and the output should eventually become an empty map:</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">{}</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>This means Longhorn evicts replicas on the disk to other disks.</p><div class="admonition admonition-note alert alert--secondary"><div class="admonition-heading"><h5><span class="admonition-icon"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>note</h5></div><div class="admonition-content"><p>If a replica always stays in a disk, please open the <a href="https://docs.harvesterhci.io/v1.1/troubleshooting/harvester#access-embedded-rancher-and-longhorn-dashboards" target="_blank" rel="noopener noreferrer">Longhorn GUI</a> and check if there is free space on other disks.</p></div></div></li></ol>]]></content>
        <author>
            <name>Kiefer Chang</name>
            <uri>https://github.com/bk201</uri>
        </author>
        <category label="storage" term="storage"/>
        <category label="longhorn" term="longhorn"/>
        <category label="disk" term="disk"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[NIC Naming Scheme]]></title>
        <id>nic-naming-scheme</id>
        <link href="https://harvesterhci.io/kb/nic-naming-scheme"/>
        <updated>2022-04-06T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[NIC Naming Scheme changed after upgrading to v1.0.1]]></summary>
        <content type="html"><![CDATA[<h2 class="anchor anchorWithStickyNavbar_mojV" id="nic-naming-scheme-changed-after-upgrading-to-v101">NIC Naming Scheme changed after upgrading to v1.0.1<a class="hash-link" href="#nic-naming-scheme-changed-after-upgrading-to-v101" title="Direct link to heading">​</a></h2><p><code>systemd</code> in OpenSUSE Leap 15.3 which is the base OS of Harvester is upgraded to <code>246.16-150300.7.39.1</code>. In this version, <code>systemd</code> will enable additional naming scheme <code>sle15-sp3</code> which is <code>v238</code> with <code>bridge_no_slot</code>. When there is a PCI bridge associated with NIC, <code>systemd</code> will never generate <code>ID_NET_NAME_SLOT</code> and naming policy in <code>/usr/lib/systemd/network/99-default.link</code> will fallback to <code>ID_NET_NAME_PATH</code>. According to this change, NIC names might be changed in your Harvester nodes during the upgrade process from <code>v1.0.0</code> to <code>v1.0.1-rc1</code> or above, and it will cause network issues that are associated with NIC names.</p><h2 class="anchor anchorWithStickyNavbar_mojV" id="effect-settings-and-workaround">Effect Settings and Workaround<a class="hash-link" href="#effect-settings-and-workaround" title="Direct link to heading">​</a></h2><h3 class="anchor anchorWithStickyNavbar_mojV" id="startup-network-configuration">Startup Network Configuration<a class="hash-link" href="#startup-network-configuration" title="Direct link to heading">​</a></h3><p>NIC name changes will need to update the name in <code>/oem/99_custom.yaml</code>. You could use <a href="https://github.com/harvester/upgrade-helpers/blob/main/hack/udev_v238_sle15-sp3.py" target="_blank" rel="noopener noreferrer">migration script</a> to change the NIC names which are associated with a PCI bridge.</p><div class="admonition admonition-tip alert alert--success"><div class="admonition-heading"><h5><span class="admonition-icon"><svg xmlns="http://www.w3.org/2000/svg" width="12" height="16" viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>tip</h5></div><div class="admonition-content"><p>You could find an identical machine to test naming changes before applying the configuration to production machines</p></div></div><p>You could simply execute the script with root account in <code>v1.0.0</code> via</p><div class="codeBlockContainer_I0IT language-bash theme-code-block"><div class="codeBlockContent_wNvx bash"><pre tabindex="0" class="prism-code language-bash codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic"># python3 udev_v238_sle15-sp3.py</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>It will output the patched configuration to the screen and you could compare it to the original one to ensure there is no exception. (e.g. We could use <code>vimdiff</code> to check the configuration)</p><div class="codeBlockContainer_I0IT language-bash theme-code-block"><div class="codeBlockContent_wNvx bash"><pre tabindex="0" class="prism-code language-bash codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic"># python3 udev_v238_sle15-spe3.py &gt; /oem/test</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># vimdiff /oem/test /oem/99_custom.yaml</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>After checking the result, we could execute the script with <code>--really-want-to-do</code> to override the configuration. It will also back up the original configuration file with a timestamp before patching it.</p><div class="codeBlockContainer_I0IT language-bash theme-code-block"><div class="codeBlockContent_wNvx bash"><pre tabindex="0" class="prism-code language-bash codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic"># python3 udev_v238_sle15-sp3.py --really-want-to-do</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><h3 class="anchor anchorWithStickyNavbar_mojV" id="harvester-vlan-network-configuration">Harvester VLAN Network Configuration<a class="hash-link" href="#harvester-vlan-network-configuration" title="Direct link to heading">​</a></h3><p>If your VLAN network is associated with NIC name directly without <code>bonding</code>, you will need to migrate <code>ClusterNetwork</code> and <code>NodeNetwork</code> with the previous section together.</p><div class="admonition admonition-note alert alert--secondary"><div class="admonition-heading"><h5><span class="admonition-icon"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>note</h5></div><div class="admonition-content"><p>If your VLAN network is associated with the <code>bonding</code> name in <code>/oem/99_custom.yaml</code>, you could skip this section.</p></div></div><h4 class="anchor anchorWithStickyNavbar_mojV" id="modify-clusternetworks">Modify ClusterNetworks<a class="hash-link" href="#modify-clusternetworks" title="Direct link to heading">​</a></h4><p>You need to modify <code>ClusterNetworks</code> via </p><div class="codeBlockContainer_I0IT language-bash theme-code-block"><div class="codeBlockContent_wNvx bash"><pre tabindex="0" class="prism-code language-bash codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">$ kubectl edit clusternetworks vlan</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>search this pattern</p><div class="codeBlockContainer_I0IT language-yaml theme-code-block"><div class="codeBlockContent_wNvx yaml"><pre tabindex="0" class="prism-code language-yaml codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token key atrule" style="color:#00a4db">config</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">defaultPhysicalNIC</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> &lt;Your NIC name</span><span class="token punctuation" style="color:#393A34">&gt;</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>and change to new NIC name</p><h4 class="anchor anchorWithStickyNavbar_mojV" id="modify-nodenetworks">Modify NodeNetworks<a class="hash-link" href="#modify-nodenetworks" title="Direct link to heading">​</a></h4><p>You need to modify <code>NodeNetworks</code> via</p><div class="codeBlockContainer_I0IT language-bash theme-code-block"><div class="codeBlockContent_wNvx bash"><pre tabindex="0" class="prism-code language-bash codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">$ kubectl edit nodenetworks </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain">Node name</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain">-vlan</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>search this pattern</p><div class="codeBlockContainer_I0IT language-yaml theme-code-block"><div class="codeBlockContent_wNvx yaml"><pre tabindex="0" class="prism-code language-yaml codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token key atrule" style="color:#00a4db">spec</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">nic</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> &lt;Your NIC name</span><span class="token punctuation" style="color:#393A34">&gt;</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>and change to new NIC name</p>]]></content>
        <author>
            <name>Date Huang</name>
            <uri>https://github.com/tjjh89017</uri>
        </author>
        <category label="network" term="network"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Multiple NICs VM Connectivity]]></title>
        <id>multiple-nics-vm-connectivity</id>
        <link href="https://harvesterhci.io/kb/multiple-nics-vm-connectivity"/>
        <updated>2022-03-10T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[What is the default behavior of a VM with multiple NICs]]></summary>
        <content type="html"><![CDATA[<h2 class="anchor anchorWithStickyNavbar_mojV" id="what-is-the-default-behavior-of-a-vm-with-multiple-nics">What is the default behavior of a VM with multiple NICs<a class="hash-link" href="#what-is-the-default-behavior-of-a-vm-with-multiple-nics" title="Direct link to heading">​</a></h2><p>In <a href="https://github.com/harvester/harvester/issues/1059" target="_blank" rel="noopener noreferrer">some scenarios</a>, you'll setup two or more NICs in your VM to serve different networking purposes. If all networks are setup by default with DHCP, you might get random connectivity issues. And while it might get fixed after rebooting the VM, it still will lose connection randomly after some period.</p><h2 class="anchor anchorWithStickyNavbar_mojV" id="how-to-identify-connectivity-issues">How-to identify connectivity issues<a class="hash-link" href="#how-to-identify-connectivity-issues" title="Direct link to heading">​</a></h2><p>In a Linux VM, you can use commands from the <code>iproute2</code> package to identify the default route.</p><p>In your VM, execute the following command:</p><div class="codeBlockContainer_I0IT language-bash theme-code-block"><div class="codeBlockContent_wNvx bash"><pre tabindex="0" class="prism-code language-bash codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">ip</span><span class="token plain"> route show default</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><div class="admonition admonition-tip alert alert--success"><div class="admonition-heading"><h5><span class="admonition-icon"><svg xmlns="http://www.w3.org/2000/svg" width="12" height="16" viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>tip</h5></div><div class="admonition-content"><p>If you get the <code>access denied</code> error, please run the command using <code>sudo</code></p></div></div><p>The output of this command will only show the default route with the gateway and VM IP of the primary network interface (<code>eth0</code> in the example below).</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">default via &lt;Gateway IP&gt; dev eth0 proto dhcp src &lt;VM IP&gt; metric 100</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>Here is the full example:</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">$ ip route show default</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">default via 192.168.0.254 dev eth0 proto dhcp src 192.168.0.100 metric 100</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>However, if the issue covered in this KB occurs, you'll only be able to connect to the VM via the VNC or serial console.</p><p>Once connected, you can run again the same command as before:</p><div class="codeBlockContainer_I0IT language-bash theme-code-block"><div class="codeBlockContent_wNvx bash"><pre tabindex="0" class="prism-code language-bash codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">$ </span><span class="token function" style="color:#d73a49">ip</span><span class="token plain"> route show default</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>However, this time you'll get a default route with an incorrect gateway IP.
For example:</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">default via &lt;Incorrect Gateway IP&gt; dev eth0 proto dhcp src &lt;VM's IP&gt; metric 100</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><h2 class="anchor anchorWithStickyNavbar_mojV" id="why-do-connectivity-issues-occur-randomly">Why do connectivity issues occur randomly<a class="hash-link" href="#why-do-connectivity-issues-occur-randomly" title="Direct link to heading">​</a></h2><p>In a standard setup, cloud-based VMs typically use DHCP for their NICs configuration. It will set an IP and a gateway for each NIC. Lastly, a default route to the gateway IP will also be added, so you can use its IP to connect to the VM.</p><p>However, Linux distributions start multiple DHCP clients at the same time and do not have a <strong>priority</strong> system. This means that if you have two or more NICs configured with DHCP, the client will enter a <strong>race condition</strong> to configure the default route. And depending on the currently running Linux distribution DHCP script, there is no guarantee which default route will be configured.</p><p>As the default route might change in every DHCP renewing process or after every OS reboot, this will create network connectivity issues.</p><h2 class="anchor anchorWithStickyNavbar_mojV" id="how-to-avoid-the-random-connectivity-issues">How to avoid the random connectivity issues<a class="hash-link" href="#how-to-avoid-the-random-connectivity-issues" title="Direct link to heading">​</a></h2><p>You can easily avoid these connectivity issues by having only one NIC attached to the VM and having only one IP and one gateway configured.</p><p>However, for VMs in more complex infrastructures, it is often not possible to use just one NIC. For example, if your infrastructure has a storage network and a service network. For security reasons, the storage network will be isolated from the service network and have a separate subnet. In this case, you must have two NICs to connect to both the service and storage networks.</p><p>You can choose a solution below that meets your requirements and security policy.</p><h3 class="anchor anchorWithStickyNavbar_mojV" id="disable-dhcp-on-secondary-nic">Disable DHCP on secondary NIC<a class="hash-link" href="#disable-dhcp-on-secondary-nic" title="Direct link to heading">​</a></h3><p>As mentioned above, the problem is caused by a <code>race condition</code> between two DHCP clients. One solution to avoid this problem is to disable DHCP for all NICs and configure them with static IPs only. Likewise, you can configure the secondary NIC with a static IP and keep the primary NIC enabled with DHCP.</p><ol><li>To configure the primary NIC with a static IP (<code>eth0</code> in this example), you can edit the file <code>/etc/sysconfig/network/ifcfg-eth0</code> with the following values:</li></ol><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">BOOTPROTO='static'</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">IPADDR='192.168.0.100'</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">NETMASK='255.255.255.0'</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><p>Alternatively, if you want to reserve the primary NIC using DHCP (<code>eth0</code> in this example), use the following values instead:</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">BOOTPROTO='dhcp'</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">DHCLIENT_SET_DEFAULT_ROUTE='yes'</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><ol start="2"><li>You need to configure the default route by editing the file <code>/etc/sysconfig/network/ifroute-eth0</code> (if you configured the primary NIC using DHCP, skip this step):</li></ol><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain"># Destination  Dummy/Gateway  Netmask  Interface</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">default        192.168.0.254  -        eth0</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><div class="admonition admonition-warning alert alert--danger"><div class="admonition-heading"><h5><span class="admonition-icon"><svg xmlns="http://www.w3.org/2000/svg" width="12" height="16" viewBox="0 0 12 16"><path fill-rule="evenodd" d="M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z"></path></svg></span>warning</h5></div><div class="admonition-content"><p>Do not put other default route for your secondary NIC</p></div></div><ol start="3"><li>Finally, configure a static IP for the secondary NIC by editing the file <code>/etc/sysconfig/network/ifcfg-eth1</code>:</li></ol><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">BOOTPROTO='static'</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">IPADDR='10.0.0.100'</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">NETMASK='255.255.255.0'</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><h4 class="anchor anchorWithStickyNavbar_mojV" id="cloud-init-config">Cloud-Init config<a class="hash-link" href="#cloud-init-config" title="Direct link to heading">​</a></h4><div class="codeBlockContainer_I0IT language-yaml theme-code-block"><div class="codeBlockContent_wNvx yaml"><pre tabindex="0" class="prism-code language-yaml codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token key atrule" style="color:#00a4db">network</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">version</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">config</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">type</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> physical</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> eth0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token key atrule" style="color:#00a4db">subnets</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">type</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> dhcp</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">type</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> physical</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> eth1</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token key atrule" style="color:#00a4db">subnets</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">type</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> static</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token key atrule" style="color:#00a4db">address</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> 10.0.0.100/24</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><h3 class="anchor anchorWithStickyNavbar_mojV" id="disable-secondary-nic-default-route-from-dhcp">Disable secondary NIC default route from DHCP<a class="hash-link" href="#disable-secondary-nic-default-route-from-dhcp" title="Direct link to heading">​</a></h3><p>If your secondary NIC requires to get its IP from DHCP, you'll need to disable the secondary NIC default route configuration.</p><ol><li>Confirm that the primary NIC configures its default route in the file <code>/etc/sysconfig/network/ifcfg-eth0</code>:</li></ol><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">BOOTPROTO='dhcp'</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">DHCLIENT_SET_DEFAULT_ROUTE='yes'</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><ol start="2"><li>Disable the secondary NIC default route configuration by editing the file <code>/etc/sysconfig/network/ifcfg-eth1</code>:</li></ol><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">BOOTPROTO='dhcp'</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">DHCLIENT_SET_DEFAULT_ROUTE='no'</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><h4 class="anchor anchorWithStickyNavbar_mojV" id="cloud-init-config-1">Cloud-Init config<a class="hash-link" href="#cloud-init-config-1" title="Direct link to heading">​</a></h4><p>This solution is not available in Cloud-Init. Cloud-Init didn't allow any option for DHCP.</p>]]></content>
        <author>
            <name>Date Huang</name>
            <uri>https://github.com/tjjh89017</uri>
        </author>
        <category label="vm" term="vm"/>
        <category label="network" term="network"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[VM Scheduling]]></title>
        <id>vm-scheduling</id>
        <link href="https://harvesterhci.io/kb/vm-scheduling"/>
        <updated>2022-03-07T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[How does Harvester schedule VMs?]]></summary>
        <content type="html"><![CDATA[<h2 class="anchor anchorWithStickyNavbar_mojV" id="how-does-harvester-schedule-a-vm">How does Harvester schedule a VM?<a class="hash-link" href="#how-does-harvester-schedule-a-vm" title="Direct link to heading">​</a></h2><p>Harvester doesn't directly schedule a VM in Kubernetes, it relies on <a href="http://kubevirt.io/" target="_blank" rel="noopener noreferrer">KubeVirt</a> to create the custom resource <code>VirtualMachine</code>. When the request to create a new VM is sent, a <code>VirtualMachineInstance</code> object is created and it creates the corresponding <code>Pod</code>.</p><p>The whole VM creation processt leverages <code>kube-scheduler</code>, which allows Harvester to use <code>nodeSelector</code>, <code>affinity</code>, and resources request/limitation to influence where a VM will be deployed.</p><h2 class="anchor anchorWithStickyNavbar_mojV" id="how-does-kube-scheduler-decide-where-to-deploy-a-vm">How does kube-scheduler decide where to deploy a VM?<a class="hash-link" href="#how-does-kube-scheduler-decide-where-to-deploy-a-vm" title="Direct link to heading">​</a></h2><p>First, <code>kube-scheduler</code> finds Nodes available to run a pod. After that, <code>kube-scheduler</code> scores each available Node by a list of <a href="https://github.com/kubernetes/kubernetes/tree/v1.22.7/pkg/scheduler/framework/plugins" target="_blank" rel="noopener noreferrer">plugins</a> like <a href="https://github.com/kubernetes/kubernetes/blob/v1.22.7/pkg/scheduler/framework/plugins/imagelocality/image_locality.go" target="_blank" rel="noopener noreferrer">ImageLocality</a>, <a href="https://github.com/kubernetes/kubernetes/tree/v1.22.7/pkg/scheduler/framework/plugins/interpodaffinity" target="_blank" rel="noopener noreferrer">InterPodAffinity</a>, <a href="https://github.com/kubernetes/kubernetes/tree/v1.22.7/pkg/scheduler/framework/plugins/nodeaffinity" target="_blank" rel="noopener noreferrer">NodeAffinity</a>, etc. </p><p>Finally, <code>kube-scheduler</code> calculates the scores from the plugins results for each Node, and select the Node with the highest score to deploy the Pod.</p><p>For example, let's say  we have a three nodes Harvester cluster with 6 cores CPU and 16G RAM each, and we want to deploy a VM with 1 CPU and 1G RAM (without resources overcommit). </p><p><code>kube-scheduler</code> will summarize the scores, as displayed in  <em>Table 1</em> below, and will select the node with the highest score, <code>harvester-node-2</code> in this case, to deploy the VM.</p><details class="details_lb9f alert alert--info details_BAp3" data-collapsed="true"><summary>kube-scheduler logs</summary><div><div class="collapsibleContent_i85q"><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">virt-launcher-vm-without-overcommit-75q9b -&gt; harvester-node-0: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:9960 memory:15166603264] ,score 0,</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">virt-launcher-vm-without-overcommit-75q9b -&gt; harvester-node-1: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:5560 memory:6352273408] ,score 45,</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">virt-launcher-vm-without-overcommit-75q9b -&gt; harvester-node-2: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:5350 memory:5941231616] ,score 46,</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">virt-launcher-vm-without-overcommit-75q9b -&gt; harvester-node-0: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:9960 memory:15166603264] ,score 4,</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">virt-launcher-vm-without-overcommit-75q9b -&gt; harvester-node-1: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:5560 memory:6352273408] ,score 34,</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">virt-launcher-vm-without-overcommit-75q9b -&gt; harvester-node-2: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:5350 memory:5941231616] ,score 37,</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm-without-overcommit-75q9b" plugin="ImageLocality" node="harvester-node-0" score=54</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm-without-overcommit-75q9b" plugin="ImageLocality" node="harvester-node-1" score=54</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm-without-overcommit-75q9b" plugin="ImageLocality" node="harvester-node-2" score=54</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm-without-overcommit-75q9b" plugin="InterPodAffinity" node="harvester-node-0" score=0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm-without-overcommit-75q9b" plugin="InterPodAffinity" node="harvester-node-1" score=0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm-without-overcommit-75q9b" plugin="InterPodAffinity" node="harvester-node-2" score=0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm-without-overcommit-75q9b" plugin="NodeResourcesLeastAllocated" node="harvester-node-0" score=4</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm-without-overcommit-75q9b" plugin="NodeResourcesLeastAllocated" node="harvester-node-1" score=34</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm-without-overcommit-75q9b" plugin="NodeResourcesLeastAllocated" node="harvester-node-2" score=37</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm-without-overcommit-75q9b" plugin="NodeAffinity" node="harvester-node-0" score=0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm-without-overcommit-75q9b" plugin="NodeAffinity" node="harvester-node-1" score=0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm-without-overcommit-75q9b" plugin="NodeAffinity" node="harvester-node-2" score=0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm-without-overcommit-75q9b" plugin="NodePreferAvoidPods" node="harvester-node-0" score=1000000</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm-without-overcommit-75q9b" plugin="NodePreferAvoidPods" node="harvester-node-2" score=1000000</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm-without-overcommit-75q9b" plugin="NodePreferAvoidPods" node="harvester-node-1" score=1000000</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm-without-overcommit-75q9b" plugin="PodTopologySpread" node="harvester-node-0" score=200</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm-without-overcommit-75q9b" plugin="PodTopologySpread" node="harvester-node-1" score=200</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm-without-overcommit-75q9b" plugin="PodTopologySpread" node="harvester-node-2" score=200</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm-without-overcommit-75q9b" plugin="TaintToleration" node="harvester-node-0" score=100</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm-without-overcommit-75q9b" plugin="TaintToleration" node="harvester-node-1" score=100</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm-without-overcommit-75q9b" plugin="TaintToleration" node="harvester-node-2" score=100</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm-without-overcommit-75q9b" plugin="NodeResourcesBalancedAllocation" node="harvester-node-0" score=0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm-without-overcommit-75q9b" plugin="NodeResourcesBalancedAllocation" node="harvester-node-1" score=45</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm-without-overcommit-75q9b" plugin="NodeResourcesBalancedAllocation" node="harvester-node-2" score=46</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Calculated node's final score for pod" pod="default/virt-launcher-vm-without-overcommit-75q9b" node="harvester-node-0" score=1000358</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Calculated node's final score for pod" pod="default/virt-launcher-vm-without-overcommit-75q9b" node="harvester-node-1" score=1000433</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Calculated node's final score for pod" pod="default/virt-launcher-vm-without-overcommit-75q9b" node="harvester-node-2" score=1000437</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">AssumePodVolumes for pod "default/virt-launcher-vm-without-overcommit-75q9b", node "harvester-node-2"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">AssumePodVolumes for pod "default/virt-launcher-vm-without-overcommit-75q9b", node "harvester-node-2": all PVCs bound and nothing to do</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Attempting to bind pod to node" pod="default/virt-launcher-vm-without-overcommit-75q9b" node="harvester-node-2"</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div></div></div></details><p><strong>Table 1 - kube-scheduler scores example</strong></p><table><thead><tr><th align="center"></th><th align="center">harvester-node-0</th><th align="center">harvester-node-1</th><th align="center">harvester-node-2</th></tr></thead><tbody><tr><td align="center">ImageLocality</td><td align="center">54</td><td align="center">54</td><td align="center">54</td></tr><tr><td align="center">InterPodAffinity</td><td align="center">0</td><td align="center">0</td><td align="center">0</td></tr><tr><td align="center">NodeResourcesLeastAllocated</td><td align="center">4</td><td align="center">34</td><td align="center">37</td></tr><tr><td align="center">NodeAffinity</td><td align="center">0</td><td align="center">0</td><td align="center">0</td></tr><tr><td align="center">NodePreferAvoidPods</td><td align="center">1000000</td><td align="center">1000000</td><td align="center">1000000</td></tr><tr><td align="center">PodTopologySpread</td><td align="center">200</td><td align="center">200</td><td align="center">200</td></tr><tr><td align="center">TaintToleration</td><td align="center">100</td><td align="center">100</td><td align="center">100</td></tr><tr><td align="center">NodeResourcesBalancedAllocation</td><td align="center">0</td><td align="center">45</td><td align="center">46</td></tr><tr><td align="center">Total</td><td align="center">1000358</td><td align="center">1000433</td><td align="center">1000437</td></tr></tbody></table><h2 class="anchor anchorWithStickyNavbar_mojV" id="why-vms-are-distributed-unevenly-with-overcommit">Why VMs are distributed unevenly with overcommit?<a class="hash-link" href="#why-vms-are-distributed-unevenly-with-overcommit" title="Direct link to heading">​</a></h2><p>With resources overcommit, Harvester modifies the resources request. By default, the <code>overcommit</code> configuration is <code>{"cpu": 1600, "memory": 150, "storage":  200}</code>. This means that if we request a VM with 1 CPU and 1G RAM, its <code>resources.requests.cpu</code> will become <code>62m</code>. </p><p>!!! note
The unit suffix <code>m</code> stands for "thousandth of a core."</p><p>To explain it, let's take the case of CPU overcommit. The default value of 1 CPU is equal to 1000m CPU, and with the default overcommit configuration of <code>"cpu": 1600</code>, the CPU resource will be 16x smaller. Here is the calculation: <code>1000m * 100 / 1600 = 62m</code>.</p><p>Now, we can see how overcommitting influences <code>kube-scheduler</code> scores.</p><p>In this example, we use a three nodes Harvester cluster with 6 cores and 16G RAM each. We will deploy two VMs with 1 CPU and 1G RAM, and we will compare the scores for both cases of "with-overcommit" and "without-overcommit" resources. </p><p>The results of both tables <em>Table 2</em> and <em>Table 3</em> can be explained as follow:</p><p>In the "with-overcommit" case, both VMs are deployed on <code>harvester-node-2</code>, however in the "without-overcommit" case, the VM1 is deployed on <code>harvester-node-2</code>, and VM2 is deployed on <code>harvester-node-1</code>. </p><p>If we look at the detailed scores, we'll see a variation of <code>Total Score</code> for <code>harvester-node-2</code> from <code>1000459</code> to <code>1000461</code> in the "with-overcommit" case, and <code>1000437</code> to <code>1000382</code> in the "without-overcommit case". It's because resources overcommit influences <code>request-cpu</code> and <code>request-memory</code>. </p><p>In the "with-overcommit" case, the <code>request-cpu</code> changes from <code>4412m</code> to <code>4474m</code>. The difference between the two numbers is <code>62m</code>, which is what we calculated above. However, in the "without-overcommit" case, we send <strong>real</strong> requests to <code>kube-scheduler</code>, so the <code>request-cpu</code> changes from <code>5350m</code> to <code>6350m</code>.</p><p>Finally, since most plugins give the same scores for each node except <code>NodeResourcesBalancedAllocation</code> and <code>NodeResourcesLeastAllocated</code>, we'll see a difference of these two scores for each node.</p><p>From the results, we can see the overcommit feature influences the final score of each Node, so VMs are distributed unevenly. Although the <code>harvester-node-2</code> score for VM 2 is higher than VM 1, it's not always increasing. In <em>Table 4</em>, we keep deploying VM with 1 CPU and 1G RAM, and we can see the score of <code>harvester-node-2</code> starts decreasing from 11th VM. The behavior of <code>kube-scheduler</code> depends on your cluster resources and the workload you deployed.</p><details class="details_lb9f alert alert--info details_BAp3" data-collapsed="true"><summary>kube-scheduler logs for vm1-with-overcommit</summary><div><div class="collapsibleContent_i85q"><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">virt-launcher-vm1-with-overcommit-ljlmq -&gt; harvester-node-0: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:9022 memory:14807289856] ,score 0,</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">virt-launcher-vm1-with-overcommit-ljlmq -&gt; harvester-node-1: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:4622 memory:5992960000] ,score 58,</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">virt-launcher-vm1-with-overcommit-ljlmq -&gt; harvester-node-2: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:4412 memory:5581918208] ,score 59,</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">virt-launcher-vm1-with-overcommit-ljlmq -&gt; harvester-node-0: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:9022 memory:14807289856] ,score 5,</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">virt-launcher-vm1-with-overcommit-ljlmq -&gt; harvester-node-1: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:4622 memory:5992960000] ,score 43,</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">virt-launcher-vm1-with-overcommit-ljlmq -&gt; harvester-node-2: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:4412 memory:5581918208] ,score 46,</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-ljlmq" plugin="InterPodAffinity" node="harvester-node-0" score=0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-ljlmq" plugin="InterPodAffinity" node="harvester-node-1" score=0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-ljlmq" plugin="InterPodAffinity" node="harvester-node-2" score=0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-ljlmq" plugin="NodeResourcesLeastAllocated" node="harvester-node-0" score=5</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-ljlmq" plugin="NodeResourcesLeastAllocated" node="harvester-node-1" score=43</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-ljlmq" plugin="NodeResourcesLeastAllocated" node="harvester-node-2" score=46</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-ljlmq" plugin="NodeAffinity" node="harvester-node-0" score=0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-ljlmq" plugin="NodeAffinity" node="harvester-node-1" score=0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-ljlmq" plugin="NodeAffinity" node="harvester-node-2" score=0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-ljlmq" plugin="NodePreferAvoidPods" node="harvester-node-0" score=1000000</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-ljlmq" plugin="NodePreferAvoidPods" node="harvester-node-1" score=1000000</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-ljlmq" plugin="NodePreferAvoidPods" node="harvester-node-2" score=1000000</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-ljlmq" plugin="PodTopologySpread" node="harvester-node-0" score=200</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-ljlmq" plugin="PodTopologySpread" node="harvester-node-1" score=200</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-ljlmq" plugin="PodTopologySpread" node="harvester-node-2" score=200</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-ljlmq" plugin="TaintToleration" node="harvester-node-0" score=100</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-ljlmq" plugin="TaintToleration" node="harvester-node-1" score=100</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-ljlmq" plugin="TaintToleration" node="harvester-node-2" score=100</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-ljlmq" plugin="NodeResourcesBalancedAllocation" node="harvester-node-0" score=0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-ljlmq" plugin="NodeResourcesBalancedAllocation" node="harvester-node-1" score=58</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-ljlmq" plugin="NodeResourcesBalancedAllocation" node="harvester-node-2" score=59</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-ljlmq" plugin="ImageLocality" node="harvester-node-0" score=54</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-ljlmq" plugin="ImageLocality" node="harvester-node-1" score=54</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-ljlmq" plugin="ImageLocality" node="harvester-node-2" score=54</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Calculated node's final score for pod" pod="default/virt-launcher-vm1-with-overcommit-ljlmq" node="harvester-node-0" score=1000359</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Calculated node's final score for pod" pod="default/virt-launcher-vm1-with-overcommit-ljlmq" node="harvester-node-1" score=1000455</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Calculated node's final score for pod" pod="default/virt-launcher-vm1-with-overcommit-ljlmq" node="harvester-node-2" score=1000459</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">AssumePodVolumes for pod "default/virt-launcher-vm1-with-overcommit-ljlmq", node "harvester-node-2"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">AssumePodVolumes for pod "default/virt-launcher-vm1-with-overcommit-ljlmq", node "harvester-node-2": all PVCs bound and nothing to do</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Attempting to bind pod to node" pod="default/virt-launcher-vm1-with-overcommit-ljlmq" node="harvester-node-2"</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div></div></div></details><details class="details_lb9f alert alert--info details_BAp3" data-collapsed="true"><summary>kube-scheduler logs for vm2-with-overcommit</summary><div><div class="collapsibleContent_i85q"><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">virt-launcher-vm2-with-overcommit-pwrx4 -&gt; harvester-node-0: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:9022 memory:14807289856] ,score 0,</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">virt-launcher-vm2-with-overcommit-pwrx4 -&gt; harvester-node-1: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:4622 memory:5992960000] ,score 58,</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">virt-launcher-vm2-with-overcommit-pwrx4 -&gt; harvester-node-2: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:4474 memory:6476701696] ,score 64,</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">virt-launcher-vm2-with-overcommit-pwrx4 -&gt; harvester-node-0: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:9022 memory:14807289856] ,score 5,</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">virt-launcher-vm2-with-overcommit-pwrx4 -&gt; harvester-node-1: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:4622 memory:5992960000] ,score 43,</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">virt-launcher-vm2-with-overcommit-pwrx4 -&gt; harvester-node-2: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:4474 memory:6476701696] ,score 43,</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-with-overcommit-pwrx4" plugin="NodeAffinity" node="harvester-node-0" score=0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-with-overcommit-pwrx4" plugin="NodeAffinity" node="harvester-node-1" score=0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-with-overcommit-pwrx4" plugin="NodeAffinity" node="harvester-node-2" score=0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-with-overcommit-pwrx4" plugin="NodePreferAvoidPods" node="harvester-node-0" score=1000000</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-with-overcommit-pwrx4" plugin="NodePreferAvoidPods" node="harvester-node-1" score=1000000</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-with-overcommit-pwrx4" plugin="NodePreferAvoidPods" node="harvester-node-2" score=1000000</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-with-overcommit-pwrx4" plugin="PodTopologySpread" node="harvester-node-0" score=200</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-with-overcommit-pwrx4" plugin="PodTopologySpread" node="harvester-node-1" score=200</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-with-overcommit-pwrx4" plugin="PodTopologySpread" node="harvester-node-2" score=200</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-with-overcommit-pwrx4" plugin="TaintToleration" node="harvester-node-0" score=100</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-with-overcommit-pwrx4" plugin="TaintToleration" node="harvester-node-1" score=100</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-with-overcommit-pwrx4" plugin="TaintToleration" node="harvester-node-2" score=100</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-with-overcommit-pwrx4" plugin="NodeResourcesBalancedAllocation" node="harvester-node-0" score=0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-with-overcommit-pwrx4" plugin="NodeResourcesBalancedAllocation" node="harvester-node-1" score=58</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-with-overcommit-pwrx4" plugin="NodeResourcesBalancedAllocation" node="harvester-node-2" score=64</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-with-overcommit-pwrx4" plugin="ImageLocality" node="harvester-node-0" score=54</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-with-overcommit-pwrx4" plugin="ImageLocality" node="harvester-node-1" score=54</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-with-overcommit-pwrx4" plugin="ImageLocality" node="harvester-node-2" score=54</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-with-overcommit-pwrx4" plugin="InterPodAffinity" node="harvester-node-0" score=0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-with-overcommit-pwrx4" plugin="InterPodAffinity" node="harvester-node-1" score=0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-with-overcommit-pwrx4" plugin="InterPodAffinity" node="harvester-node-2" score=0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-with-overcommit-pwrx4" plugin="NodeResourcesLeastAllocated" node="harvester-node-0" score=5</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-with-overcommit-pwrx4" plugin="NodeResourcesLeastAllocated" node="harvester-node-1" score=43</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-with-overcommit-pwrx4" plugin="NodeResourcesLeastAllocated" node="harvester-node-2" score=43</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Calculated node's final score for pod" pod="default/virt-launcher-vm2-with-overcommit-pwrx4" node="harvester-node-0" score=1000359</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Calculated node's final score for pod" pod="default/virt-launcher-vm2-with-overcommit-pwrx4" node="harvester-node-1" score=1000455</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Calculated node's final score for pod" pod="default/virt-launcher-vm2-with-overcommit-pwrx4" node="harvester-node-2" score=1000461</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">AssumePodVolumes for pod "default/virt-launcher-vm2-with-overcommit-pwrx4", node "harvester-node-2"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">AssumePodVolumes for pod "default/virt-launcher-vm2-with-overcommit-pwrx4", node "harvester-node-2": all PVCs bound and nothing to do</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Attempting to bind pod to node" pod="default/virt-launcher-vm2-with-overcommit-pwrx4" node="harvester-node-2"</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div></div></div></details><details class="details_lb9f alert alert--info details_BAp3" data-collapsed="true"><summary>kube-scheduler logs for vm1-without-overcommit</summary><div><div class="collapsibleContent_i85q"><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">virt-launcher-vm1-with-overcommit-6xqmq -&gt; harvester-node-0: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:9960 memory:15166603264] ,score 0,</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">virt-launcher-vm1-with-overcommit-6xqmq -&gt; harvester-node-1: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:5560 memory:6352273408] ,score 45,</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">virt-launcher-vm1-with-overcommit-6xqmq -&gt; harvester-node-2: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:5350 memory:5941231616] ,score 46,</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">virt-launcher-vm1-with-overcommit-6xqmq -&gt; harvester-node-0: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:9960 memory:15166603264] ,score 4,</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">virt-launcher-vm1-with-overcommit-6xqmq -&gt; harvester-node-1: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:5560 memory:6352273408] ,score 34,</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">virt-launcher-vm1-with-overcommit-6xqmq -&gt; harvester-node-2: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:5350 memory:5941231616] ,score 37,</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-6xqmq" plugin="InterPodAffinity" node="harvester-node-0" score=0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-6xqmq" plugin="InterPodAffinity" node="harvester-node-1" score=0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-6xqmq" plugin="InterPodAffinity" node="harvester-node-2" score=0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-6xqmq" plugin="NodeResourcesLeastAllocated" node="harvester-node-0" score=4</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-6xqmq" plugin="NodeResourcesLeastAllocated" node="harvester-node-1" score=34</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-6xqmq" plugin="NodeResourcesLeastAllocated" node="harvester-node-2" score=37</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-6xqmq" plugin="NodeAffinity" node="harvester-node-0" score=0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-6xqmq" plugin="NodeAffinity" node="harvester-node-1" score=0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-6xqmq" plugin="NodeAffinity" node="harvester-node-2" score=0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-6xqmq" plugin="NodePreferAvoidPods" node="harvester-node-0" score=1000000</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-6xqmq" plugin="NodePreferAvoidPods" node="harvester-node-1" score=1000000</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-6xqmq" plugin="NodePreferAvoidPods" node="harvester-node-2" score=1000000</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-6xqmq" plugin="PodTopologySpread" node="harvester-node-0" score=200</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-6xqmq" plugin="PodTopologySpread" node="harvester-node-1" score=200</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-6xqmq" plugin="PodTopologySpread" node="harvester-node-2" score=200</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-6xqmq" plugin="TaintToleration" node="harvester-node-0" score=100</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-6xqmq" plugin="TaintToleration" node="harvester-node-1" score=100</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-6xqmq" plugin="TaintToleration" node="harvester-node-2" score=100</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-6xqmq" plugin="NodeResourcesBalancedAllocation" node="harvester-node-0" score=0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-6xqmq" plugin="NodeResourcesBalancedAllocation" node="harvester-node-1" score=45</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-6xqmq" plugin="NodeResourcesBalancedAllocation" node="harvester-node-2" score=46</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-6xqmq" plugin="ImageLocality" node="harvester-node-0" score=54</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-6xqmq" plugin="ImageLocality" node="harvester-node-1" score=54</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm1-with-overcommit-6xqmq" plugin="ImageLocality" node="harvester-node-2" score=54</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Calculated node's final score for pod" pod="default/virt-launcher-vm1-with-overcommit-6xqmq" node="harvester-node-0" score=1000358</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Calculated node's final score for pod" pod="default/virt-launcher-vm1-with-overcommit-6xqmq" node="harvester-node-1" score=1000433</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Calculated node's final score for pod" pod="default/virt-launcher-vm1-with-overcommit-6xqmq" node="harvester-node-2" score=1000437</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">AssumePodVolumes for pod "default/virt-launcher-vm1-with-overcommit-6xqmq", node "harvester-node-2"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">AssumePodVolumes for pod "default/virt-launcher-vm1-with-overcommit-6xqmq", node "harvester-node-2": all PVCs bound and nothing to do</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Attempting to bind pod to node" pod="default/virt-launcher-vm1-with-overcommit-6xqmq" node="harvester-node-2"</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div></div></div></details><details class="details_lb9f alert alert--info details_BAp3" data-collapsed="true"><summary>kube-scheduler logs for vm2-without-overcommit</summary><div><div class="collapsibleContent_i85q"><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">virt-launcher-vm2-without-overcommit-mf5vk -&gt; harvester-node-0: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:9960 memory:15166603264] ,score 0,</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">virt-launcher-vm2-without-overcommit-mf5vk -&gt; harvester-node-1: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:5560 memory:6352273408] ,score 45,</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">virt-launcher-vm2-without-overcommit-mf5vk -&gt; harvester-node-2: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:6350 memory:7195328512] ,score 0,</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">virt-launcher-vm2-without-overcommit-mf5vk -&gt; harvester-node-0: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:9960 memory:15166603264] ,score 4,</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">virt-launcher-vm2-without-overcommit-mf5vk -&gt; harvester-node-1: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:5560 memory:6352273408] ,score 34,</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">virt-launcher-vm2-without-overcommit-mf5vk -&gt; harvester-node-2: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:6350 memory:7195328512] ,score 28,</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-without-overcommit-mf5vk" plugin="PodTopologySpread" node="harvester-node-0" score=200</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-without-overcommit-mf5vk" plugin="PodTopologySpread" node="harvester-node-1" score=200</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-without-overcommit-mf5vk" plugin="PodTopologySpread" node="harvester-node-2" score=200</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-without-overcommit-mf5vk" plugin="TaintToleration" node="harvester-node-0" score=100</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-without-overcommit-mf5vk" plugin="TaintToleration" node="harvester-node-1" score=100</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-without-overcommit-mf5vk" plugin="TaintToleration" node="harvester-node-2" score=100</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-without-overcommit-mf5vk" plugin="NodeResourcesBalancedAllocation" node="harvester-node-0" score=0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-without-overcommit-mf5vk" plugin="NodeResourcesBalancedAllocation" node="harvester-node-1" score=45</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-without-overcommit-mf5vk" plugin="NodeResourcesBalancedAllocation" node="harvester-node-2" score=0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-without-overcommit-mf5vk" plugin="ImageLocality" node="harvester-node-0" score=54</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-without-overcommit-mf5vk" plugin="ImageLocality" node="harvester-node-1" score=54</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-without-overcommit-mf5vk" plugin="ImageLocality" node="harvester-node-2" score=54</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-without-overcommit-mf5vk" plugin="InterPodAffinity" node="harvester-node-0" score=0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-without-overcommit-mf5vk" plugin="InterPodAffinity" node="harvester-node-1" score=0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-without-overcommit-mf5vk" plugin="InterPodAffinity" node="harvester-node-2" score=0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-without-overcommit-mf5vk" plugin="NodeResourcesLeastAllocated" node="harvester-node-0" score=4</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-without-overcommit-mf5vk" plugin="NodeResourcesLeastAllocated" node="harvester-node-1" score=34</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-without-overcommit-mf5vk" plugin="NodeResourcesLeastAllocated" node="harvester-node-2" score=28</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-without-overcommit-mf5vk" plugin="NodeAffinity" node="harvester-node-0" score=0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-without-overcommit-mf5vk" plugin="NodeAffinity" node="harvester-node-1" score=0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-without-overcommit-mf5vk" plugin="NodeAffinity" node="harvester-node-2" score=0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-without-overcommit-mf5vk" plugin="NodePreferAvoidPods" node="harvester-node-0" score=1000000</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-without-overcommit-mf5vk" plugin="NodePreferAvoidPods" node="harvester-node-1" score=1000000</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Plugin scored node for pod" pod="default/virt-launcher-vm2-without-overcommit-mf5vk" plugin="NodePreferAvoidPods" node="harvester-node-2" score=1000000</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Calculated node's final score for pod" pod="default/virt-launcher-vm2-without-overcommit-mf5vk" node="harvester-node-0" score=1000358</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Calculated node's final score for pod" pod="default/virt-launcher-vm2-without-overcommit-mf5vk" node="harvester-node-1" score=1000433</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Calculated node's final score for pod" pod="default/virt-launcher-vm2-without-overcommit-mf5vk" node="harvester-node-2" score=1000382</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">AssumePodVolumes for pod "default/virt-launcher-vm2-without-overcommit-mf5vk", node "harvester-node-1"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">AssumePodVolumes for pod "default/virt-launcher-vm2-without-overcommit-mf5vk", node "harvester-node-1": all PVCs bound and nothing to do</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Attempting to bind pod to node" pod="default/virt-launcher-vm2-without-overcommit-mf5vk" node="harvester-node-1"</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div></div></div></details><p><strong>Table 2 - With Overcommit</strong></p><table><thead><tr><th align="center">VM 1 / VM 2</th><th align="right">harvester-node-0</th><th align="right">harvester-node-1</th><th align="right">harvester-node-2</th></tr></thead><tbody><tr><td align="center">request-cpu (m)</td><td align="right">9022 / 9022</td><td align="right">4622 / 4622</td><td align="right"><strong>4412</strong> / <strong>4474</strong></td></tr><tr><td align="center">request-memory</td><td align="right">14807289856 / 14807289856</td><td align="right">5992960000 / 5992960000</td><td align="right"><strong>5581918208</strong> / <strong>6476701696</strong></td></tr><tr><td align="center">NodeResourcesBalancedAllocation Score</td><td align="right">0 / 0</td><td align="right">58 / 58</td><td align="right"><strong>59</strong> / <strong>64</strong></td></tr><tr><td align="center">NodeResourcesLeastAllocated Score</td><td align="right">5 / 5</td><td align="right">43 / 43</td><td align="right"><strong>46</strong> / <strong>43</strong></td></tr><tr><td align="center">Other Scores</td><td align="right">1000354 / 1000354</td><td align="right">1000354 / 1000354</td><td align="right">1000354 / 1000354</td></tr><tr><td align="center">Total Score</td><td align="right">1000359 / 1000359</td><td align="right">1000455 / 1000455</td><td align="right"><strong>1000459</strong> / <strong>1000461</strong></td></tr></tbody></table><p><strong>Table 3 - Without Overcommit</strong></p><table><thead><tr><th align="center">VM 1 / VM 2</th><th align="right">harvester-node-0</th><th align="right">harvester-node-1</th><th align="right">harvester-node-2</th></tr></thead><tbody><tr><td align="center">request-cpu (m)</td><td align="right">9960 / 9960</td><td align="right">5560 / <strong>5560</strong></td><td align="right"><strong>5350</strong> / 6350</td></tr><tr><td align="center">request-memory</td><td align="right">15166603264 / 15166603264</td><td align="right">6352273408 / <strong>6352273408</strong></td><td align="right"><strong>5941231616</strong> / 7195328512</td></tr><tr><td align="center">NodeResourcesBalancedAllocation Score</td><td align="right">0 / 0</td><td align="right">45 / <strong>45</strong></td><td align="right"><strong>46</strong> / 0</td></tr><tr><td align="center">NodeResourcesLeastAllocated Score</td><td align="right">4 / 4</td><td align="right">34 / <strong>34</strong></td><td align="right"><strong>37</strong> / 28</td></tr><tr><td align="center">Other Scores</td><td align="right">1000354 / 1000354</td><td align="right">1000354 / <strong>1000354</strong></td><td align="right"><strong>1000354</strong> / 1000354</td></tr><tr><td align="center">Total Score</td><td align="right">1000358 / 1000358</td><td align="right">1000358 / <strong>1000433</strong></td><td align="right"><strong>1000437</strong> / 1000382</td></tr></tbody></table><p><strong>Table 4</strong></p><table><thead><tr><th align="center">Score</th><th align="right">harvester-node-0</th><th align="right">harvester-node-1</th><th align="right">harvester-node-2</th></tr></thead><tbody><tr><td align="center">VM 1</td><td align="right">1000359</td><td align="right">1000455</td><td align="right">1000459</td></tr><tr><td align="center">VM 2</td><td align="right">1000359</td><td align="right">1000455</td><td align="right">1000461</td></tr><tr><td align="center">VM 3</td><td align="right">1000359</td><td align="right">1000455</td><td align="right">1000462</td></tr><tr><td align="center">VM 4</td><td align="right">1000359</td><td align="right">1000455</td><td align="right">1000462</td></tr><tr><td align="center">VM 5</td><td align="right">1000359</td><td align="right">1000455</td><td align="right">1000463</td></tr><tr><td align="center">VM 6</td><td align="right">1000359</td><td align="right">1000455</td><td align="right">1000465</td></tr><tr><td align="center">VM 7</td><td align="right">1000359</td><td align="right">1000455</td><td align="right">1000466</td></tr><tr><td align="center">VM 8</td><td align="right">1000359</td><td align="right">1000455</td><td align="right">1000467</td></tr><tr><td align="center">VM 9</td><td align="right">1000359</td><td align="right">1000455</td><td align="right">1000469</td></tr><tr><td align="center">VM 10</td><td align="right">1000359</td><td align="right">1000455</td><td align="right">1000469</td></tr><tr><td align="center">VM 11</td><td align="right">1000359</td><td align="right">1000455</td><td align="right"><strong>1000465</strong></td></tr><tr><td align="center">VM 12</td><td align="right">1000359</td><td align="right">1000455</td><td align="right"><strong>1000457</strong></td></tr></tbody></table><h2 class="anchor anchorWithStickyNavbar_mojV" id="how-to-avoid-uneven-distribution-of-vms">How to avoid uneven distribution of VMs?<a class="hash-link" href="#how-to-avoid-uneven-distribution-of-vms" title="Direct link to heading">​</a></h2><p>There are many plugins in <code>kube-scheduler</code> which we can use to influence the scores. For example, we can add the <code>podAntiAffinity</code> plugin to avoid VMs with the same labels being deployed on the same node.</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">  affinity:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    podAntiAffinity:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      preferredDuringSchedulingIgnoredDuringExecution:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      - podAffinityTerm:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          labelSelector:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            matchExpressions:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            - key: harvesterhci.io/creator</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">              operator: Exists</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          topologyKey: kubernetes.io/hostname</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        weight: 100</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div><h2 class="anchor anchorWithStickyNavbar_mojV" id="how-to-see-scores-in-kube-scheduler">How to see scores in kube-scheduler?<a class="hash-link" href="#how-to-see-scores-in-kube-scheduler" title="Direct link to heading">​</a></h2><p><code>kube-scheduler</code> is deployed as a static pod in Harvester. The file is under <code>/var/lib/rancher/rke2/agent/pod-manifests/kube-scheduler.yaml</code> in each Management Node. We can add <code>- --v=10</code> to the <code>kube-scheduler</code> container to show score logs.</p><div class="codeBlockContainer_I0IT theme-code-block"><div class="codeBlockContent_wNvx"><pre tabindex="0" class="prism-code language-text codeBlock_jd64 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_mRuA"><span class="token-line" style="color:#393A34"><span class="token plain">kind: Pod</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">metadata:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  labels:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    component: kube-scheduler</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    tier: control-plane</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  name: kube-scheduler</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  namespace: kube-system</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">spec:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  containers:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  - command:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    - kube-scheduler</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    # ...</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    - --v=10</span><br></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_wuS7 clean-btn">Copy</button></div></div>]]></content>
        <author>
            <name>PoAn Yang</name>
            <uri>https://github.com/FrankYang0529</uri>
        </author>
        <category label="vm" term="vm"/>
        <category label="scheduling" term="scheduling"/>
    </entry>
</feed>