<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://kubevela.io/blog/</id>
    <title>KubeVela Blog</title>
    <updated>2025-12-20T00:00:00.000Z</updated>
    <generator>https://github.com/jpmonette/feed</generator>
    <link rel="alternate" href="https://kubevela.io/blog/"/>
    <subtitle>KubeVela Blog</subtitle>
    <icon>https://kubevela.io/img/favicons/favicon.ico</icon>
    <entry>
        <title type="html"><![CDATA[State of KubeVela 2025: A Year of Maturity, Community, and Looking Ahead]]></title>
        <id>https://kubevela.io/blog/2025/12/20/state-of-kubevela-2025/</id>
        <link href="https://kubevela.io/blog/2025/12/20/state-of-kubevela-2025/"/>
        <updated>2025-12-20T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Reflecting on KubeVela's achievements in 2025 and our vision for the future of application delivery]]></summary>
        <content type="html"><![CDATA[<p>As we close out 2025, we want to take a moment to reflect on what has been a transformative year for KubeVela. From major releases to community growth, from enterprise adoption to exciting new features on the horizon—this year has reinforced our belief that making application delivery enjoyable is not just a tagline, but a mission worth pursuing.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="2025-by-the-numbers">2025 By The Numbers<a href="https://kubevela.io/blog/2025/12/20/state-of-kubevela-2025/#2025-by-the-numbers" class="hash-link" aria-label="Direct link to 2025 By The Numbers" title="Direct link to 2025 By The Numbers" translate="no">​</a></h2>
<p>Before we dive into the details, here's what the KubeVela community accomplished this year:</p>
<table><thead><tr><th>Metric</th><th>2025</th></tr></thead><tbody><tr><td><strong>Releases</strong></td><td><a href="https://github.com/kubevela/kubevela/releases" target="_blank" rel="noopener noreferrer" class="">7 (v1.10.0 through v1.10.6)</a></td></tr><tr><td><strong>Commits</strong></td><td><a href="https://github.com/kubevela/kubevela/compare/v1.9.13...v1.10.6" target="_blank" rel="noopener noreferrer" class="">124</a></td></tr><tr><td><strong>Contributors</strong></td><td><a href="https://github.com/kubevela/kubevela/graphs/contributors" target="_blank" rel="noopener noreferrer" class="">33 unique contributors</a></td></tr><tr><td><strong>Bug Fixes</strong></td><td><a href="https://github.com/kubevela/kubevela/commits/master/?since=2025-01-01&amp;until=2025-12-31" target="_blank" rel="noopener noreferrer" class="">51</a></td></tr><tr><td><strong>GitHub Stars</strong></td><td><a href="https://github.com/kubevela/kubevela/stargazers" target="_blank" rel="noopener noreferrer" class="">7,600+</a></td></tr><tr><td><strong>Forks</strong></td><td><a href="https://github.com/kubevela/kubevela/network/members" target="_blank" rel="noopener noreferrer" class="">960+</a></td></tr></tbody></table>
<p>These numbers tell a story of a healthy, active open-source project—but the real story is in the features we shipped and the problems we solved.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-110-release-series-maturity-in-focus">The 1.10 Release Series: Maturity in Focus<a href="https://kubevela.io/blog/2025/12/20/state-of-kubevela-2025/#the-110-release-series-maturity-in-focus" class="hash-link" aria-label="Direct link to The 1.10 Release Series: Maturity in Focus" title="Direct link to The 1.10 Release Series: Maturity in Focus" translate="no">​</a></h2>
<p>2025 was the year of the 1.10 release series, and our theme was clear: <strong>maturity and reliability</strong>. We listened to our users—platform engineers running KubeVela in production—and focused on the features that make their lives easier.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="kubernetes-compatibility">Kubernetes Compatibility<a href="https://kubevela.io/blog/2025/12/20/state-of-kubevela-2025/#kubernetes-compatibility" class="hash-link" aria-label="Direct link to Kubernetes Compatibility" title="Direct link to Kubernetes Compatibility" translate="no">​</a></h3>
<p>We continue to invest in ensuring KubeVela works seamlessly with recent Kubernetes releases. Staying current with the Kubernetes ecosystem is critical for enterprise adoption, and we regularly update our dependencies, API versions, and test matrices to keep KubeVela on the leading edge.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="statefulset-support">StatefulSet Support<a href="https://kubevela.io/blog/2025/12/20/state-of-kubevela-2025/#statefulset-support" class="hash-link" aria-label="Direct link to StatefulSet Support" title="Direct link to StatefulSet Support" translate="no">​</a></h3>
<p>One of our most requested features finally landed in v1.10.3: native <strong>StatefulSet support</strong> (<a href="https://github.com/kubevela/kubevela/pull/6638" target="_blank" rel="noopener noreferrer" class="">#6638</a>). Platform engineers can now define stateful workloads—databases, message queues, distributed caches—with the same elegance as stateless services. This opens up KubeVela to a whole new class of applications.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="cuex-compiler-for-templating">CueX Compiler for Templating<a href="https://kubevela.io/blog/2025/12/20/state-of-kubevela-2025/#cuex-compiler-for-templating" class="hash-link" aria-label="Direct link to CueX Compiler for Templating" title="Direct link to CueX Compiler for Templating" translate="no">​</a></h3>
<p>Building on the CueX compiler framework originally developed for workflows, we expanded CueX support to <strong>component and trait templating</strong> (<a href="https://github.com/kubevela/kubevela/pull/6720" target="_blank" rel="noopener noreferrer" class="">#6720</a>). This extension unlocks new advanced capabilities and lays the groundwork for future templating improvements across KubeVela.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="dependency-aware-workflows">Dependency-Aware Workflows<a href="https://kubevela.io/blog/2025/12/20/state-of-kubevela-2025/#dependency-aware-workflows" class="hash-link" aria-label="Direct link to Dependency-Aware Workflows" title="Direct link to Dependency-Aware Workflows" translate="no">​</a></h3>
<p><a href="https://github.com/kubevela/kubevela/issues/6852" target="_blank" rel="noopener noreferrer" class="">Issue #6852</a> was one of our most upvoted issues—users were confused about why component <code>dependsOn</code> wasn't respected in workflows. In v1.10.4, we fixed this. KubeVela now dynamically adds workflow dependencies between steps according to component dependencies.</p>
<p>This was a small change in code but a big change in user experience. It's the kind of improvement that makes you wonder, "Why didn't it always work this way?" And that's exactly the point—<strong>good software should be intuitive</strong>.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="enhanced-status-reporting">Enhanced Status Reporting<a href="https://kubevela.io/blog/2025/12/20/state-of-kubevela-2025/#enhanced-status-reporting" class="hash-link" aria-label="Direct link to Enhanced Status Reporting" title="Direct link to Enhanced Status Reporting" translate="no">​</a></h3>
<p>Platform engineers told us they needed more visibility into what's happening with their applications. The existing health checks were helpful, but they wanted more. So we added <strong>Status Details</strong>—a new field that captures structured diagnostic information about your components and traits.</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token key atrule">status</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">services</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> my</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">service</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">status</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">readyReplicas</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"3"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">totalReplicas</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"3"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">readyPercentage</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"100"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">deploymentMode</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"RollingUpdate"</span><br></span></code></pre></div></div>
<p>This is the kind of information that makes debugging at 2 AM a little less painful.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="application-status-metrics">Application Status Metrics<a href="https://kubevela.io/blog/2025/12/20/state-of-kubevela-2025/#application-status-metrics" class="hash-link" aria-label="Direct link to Application Status Metrics" title="Direct link to Application Status Metrics" translate="no">​</a></h3>
<p>Speaking of observability, we added new Prometheus metrics for application health:</p>
<ul>
<li class=""><code>kubevela_application_health_status</code></li>
<li class=""><code>kubevela_application_phase</code></li>
<li class=""><code>kubevela_application_workflow_phase</code></li>
</ul>
<p>Now you can set up alerts, build dashboards, and integrate KubeVela into your existing monitoring stack. We've kept these metrics low-cardinality to ensure they're cost-effective to collect and store.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="security-enhancements">Security Enhancements<a href="https://kubevela.io/blog/2025/12/20/state-of-kubevela-2025/#security-enhancements" class="hash-link" aria-label="Direct link to Security Enhancements" title="Direct link to Security Enhancements" translate="no">​</a></h3>
<p>Security was a major theme in 2025. We shipped several improvements that make KubeVela safer for production use:</p>
<ul>
<li class=""><strong>securityContext and podSecurityContext traits</strong> (<a href="https://github.com/kubevela/kubevela/pull/6666" target="_blank" rel="noopener noreferrer" class="">#6666</a>): Configure pod and container security settings directly in your component definitions</li>
<li class=""><strong>Definition permission validation</strong> (<a href="https://github.com/kubevela/kubevela/pull/6876" target="_blank" rel="noopener noreferrer" class="">#6876</a>): KubeVela now validates that your Definitions have the necessary permissions at application creation time, catching misconfigurations early</li>
<li class=""><strong>Fail-fast CUE validation</strong> (<a href="https://github.com/kubevela/kubevela/pull/6774" target="_blank" rel="noopener noreferrer" class="">#6774</a>): Required parameters are now validated upfront, preventing deployments that would fail later</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="supply-chain-security">Supply Chain Security<a href="https://kubevela.io/blog/2025/12/20/state-of-kubevela-2025/#supply-chain-security" class="hash-link" aria-label="Direct link to Supply Chain Security" title="Direct link to Supply Chain Security" translate="no">​</a></h3>
<p>In an era where software supply chain attacks are increasingly common, we're proud to have shipped <strong>signed releases, SBOMs, and SLSA provenance</strong> for all KubeVela artifacts. When you pull a KubeVela container image, you can verify it came from us and see exactly what's inside.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="semantic-versioning-for-definitions">Semantic Versioning for Definitions<a href="https://kubevela.io/blog/2025/12/20/state-of-kubevela-2025/#semantic-versioning-for-definitions" class="hash-link" aria-label="Direct link to Semantic Versioning for Definitions" title="Direct link to Semantic Versioning for Definitions" translate="no">​</a></h3>
<p>Platform engineers managing large definition libraries will appreciate the new <strong>semantic versioning support for Definitions</strong> (<a href="https://github.com/kubevela/kubevela/pull/6648" target="_blank" rel="noopener noreferrer" class="">#6648</a>). You can now version your ComponentDefinitions and TraitDefinitions, making it easier to evolve your platform APIs without breaking existing applications.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="looking-ahead-the-future-of-application-delivery">Looking Ahead: The Future of Application Delivery<a href="https://kubevela.io/blog/2025/12/20/state-of-kubevela-2025/#looking-ahead-the-future-of-application-delivery" class="hash-link" aria-label="Direct link to Looking Ahead: The Future of Application Delivery" title="Direct link to Looking Ahead: The Future of Application Delivery" translate="no">​</a></h2>
<p>As we look beyond 2025, we find ourselves at an exciting inflection point. The landscape of software delivery is evolving rapidly, and we're paying close attention to the trends that will shape how developers and platform engineers work in the years to come.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-rise-of-intelligent-platforms">The Rise of Intelligent Platforms<a href="https://kubevela.io/blog/2025/12/20/state-of-kubevela-2025/#the-rise-of-intelligent-platforms" class="hash-link" aria-label="Direct link to The Rise of Intelligent Platforms" title="Direct link to The Rise of Intelligent Platforms" translate="no">​</a></h3>
<p>The emergence of AI and large language models is transforming how we interact with complex systems. We're exploring how these capabilities could fundamentally change the KubeVela experience. Imagine describing what you need in natural language and having an intelligent system generate the right configuration, diagnose issues before they become problems, or suggest optimizations based on real-world patterns.</p>
<p>We're not building AI for the sake of AI—we're asking ourselves: <em>What if deploying and operating applications could be as simple as having a conversation?</em></p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="lowering-barriers-not-just-abstracting-complexity">Lowering Barriers, Not Just Abstracting Complexity<a href="https://kubevela.io/blog/2025/12/20/state-of-kubevela-2025/#lowering-barriers-not-just-abstracting-complexity" class="hash-link" aria-label="Direct link to Lowering Barriers, Not Just Abstracting Complexity" title="Direct link to Lowering Barriers, Not Just Abstracting Complexity" translate="no">​</a></h3>
<p>One consistent theme in our community feedback is the desire for simpler paths to productivity. Whether you're a developer who just wants to ship code or a platform engineer building golden paths for your organization, KubeVela should meet you where you are.</p>
<p>We're investing in new ways to author and share platform building blocks—approaches that leverage familiar tools and languages while maintaining the power and flexibility that KubeVela offers today.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="beyond-deployment-intelligent-operations">Beyond Deployment: Intelligent Operations<a href="https://kubevela.io/blog/2025/12/20/state-of-kubevela-2025/#beyond-deployment-intelligent-operations" class="hash-link" aria-label="Direct link to Beyond Deployment: Intelligent Operations" title="Direct link to Beyond Deployment: Intelligent Operations" translate="no">​</a></h3>
<p>The future of application delivery isn't just about getting code to production—it's about running it well. We're thinking deeply about how KubeVela can provide proactive insights: cost awareness before you deploy, security posture at a glance, performance optimization suggestions based on actual usage patterns.</p>
<p>These are explorations, not promises. We're in the early stages of understanding how these capabilities could benefit our community. But we're genuinely excited about the possibilities, and we believe the intersection of platform engineering and intelligent tooling will define the next era of cloud-native development.</p>
<p><strong>Stay tuned.</strong> We'll share more as these ideas take shape.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="community-highlights">Community Highlights<a href="https://kubevela.io/blog/2025/12/20/state-of-kubevela-2025/#community-highlights" class="hash-link" aria-label="Direct link to Community Highlights" title="Direct link to Community Highlights" translate="no">​</a></h2>
<p>Open source is about people, and we've been fortunate to have an incredible community this year.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="new-contributors">New Contributors<a href="https://kubevela.io/blog/2025/12/20/state-of-kubevela-2025/#new-contributors" class="hash-link" aria-label="Direct link to New Contributors" title="Direct link to New Contributors" translate="no">​</a></h3>
<p>We welcomed <strong>33 unique contributors</strong> in 2025, from first-time contributors fixing typos to seasoned developers implementing major features. Every contribution matters, and we're grateful for each one.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="community-meetings">Community Meetings<a href="https://kubevela.io/blog/2025/12/20/state-of-kubevela-2025/#community-meetings" class="hash-link" aria-label="Direct link to Community Meetings" title="Direct link to Community Meetings" translate="no">​</a></h3>
<p>Our monthly community meetings continue to be a highlight. Each month, we showcase new features, review upcoming milestones, and engage in Q&amp;A. If you haven't joined one, we'd love to see you there. Check our <a href="https://github.com/kubevela/community#community-meetings" target="_blank" rel="noopener noreferrer" class="">community calendar</a> for details.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="kubecon-north-america-2025">KubeCon North America 2025<a href="https://kubevela.io/blog/2025/12/20/state-of-kubevela-2025/#kubecon-north-america-2025" class="hash-link" aria-label="Direct link to KubeCon North America 2025" title="Direct link to KubeCon North America 2025" translate="no">​</a></h3>
<p>KubeCon North America 2025 in Atlanta was a milestone moment for our community. We presented <a href="https://www.youtube.com/watch?v=0yW79y48U3k" target="_blank" rel="noopener noreferrer" class="">Democratizing Platform Engineering and Introducing the Component Contributor Architecture</a>, sharing our vision for how KubeVela enables organizations to build platforms that empower every team to contribute—not just consume.</p>
<p>We also hosted a <strong>Project Pavilion booth</strong> throughout the conference, which gave us invaluable face time with the community. Platform engineers, developers, and operators from organizations of all sizes stopped by to share their experiences, challenges, and ideas for the future. These conversations are the lifeblood of open source—hearing directly from users about what's working and what needs improvement helps us build for the real world. If you visited us at the booth, thank you. Your feedback is already shaping our roadmap.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="cncf-incubation">CNCF Incubation<a href="https://kubevela.io/blog/2025/12/20/state-of-kubevela-2025/#cncf-incubation" class="hash-link" aria-label="Direct link to CNCF Incubation" title="Direct link to CNCF Incubation" translate="no">​</a></h3>
<p>As a CNCF Incubating project, we continue to work closely with the foundation and the broader cloud-native ecosystem. We're committed to the open governance and vendor-neutral approach that makes CNCF projects trustworthy for enterprise adoption.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="lessons-learned">Lessons Learned<a href="https://kubevela.io/blog/2025/12/20/state-of-kubevela-2025/#lessons-learned" class="hash-link" aria-label="Direct link to Lessons Learned" title="Direct link to Lessons Learned" translate="no">​</a></h2>
<p>Looking back at 2025, a few lessons stand out:</p>
<p><strong>1. Listen to your users.</strong> The best features we shipped this year—StatefulSet support, dependency-aware workflows, enhanced status reporting, security traits—all came from user feedback. Keep those GitHub issues coming.</p>
<p><strong>2. Boring is good.</strong> We didn't ship flashy new features every month. Instead, we focused on stability, compatibility, and reliability. For a project used in production, that's exactly what matters.</p>
<p><strong>3. Documentation is a feature.</strong> We're the first to admit our documentation needs work. Simplifying the getting-started experience and making it easier for new users to succeed with KubeVela remains a priority for us.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="thank-you">Thank You<a href="https://kubevela.io/blog/2025/12/20/state-of-kubevela-2025/#thank-you" class="hash-link" aria-label="Direct link to Thank You" title="Direct link to Thank You" translate="no">​</a></h2>
<p>To everyone who used KubeVela in 2025, filed an issue, submitted a PR, joined a community meeting, or just gave us a star on GitHub—<strong>thank you</strong>.</p>
<p>Building an open-source project is a marathon, not a sprint. We're in this for the long haul, and we're grateful to have you on this journey with us.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="get-involved">Get Involved<a href="https://kubevela.io/blog/2025/12/20/state-of-kubevela-2025/#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Want to be part of the story? Here's how:</p>
<ul>
<li class=""><strong>Star us on GitHub</strong>: <a href="https://github.com/kubevela/kubevela" target="_blank" rel="noopener noreferrer" class="">github.com/kubevela/kubevela</a></li>
<li class=""><strong>Join our Slack</strong>: <a href="https://cloud-native.slack.com/archives/C01BLQ3HTJA" target="_blank" rel="noopener noreferrer" class="">#kubevela on CNCF Slack</a></li>
<li class=""><strong>Attend a community meeting</strong>: Every month, all are welcome</li>
<li class=""><strong>Contribute</strong>: Check out our <a href="https://github.com/kubevela/kubevela/labels/good%20first%20issue" target="_blank" rel="noopener noreferrer" class="">good first issues</a></li>
</ul>
<p>Here's to making shipping applications more enjoyable. 🚀</p>
<hr>
<p><em>The KubeVela Team</em></p>
<p><em>December 2025</em></p>]]></content>
        <author>
            <name>Anoop Gopalakrishnan</name>
            <uri>https://github.com/anoop2811</uri>
        </author>
        <category label="KubeVela" term="KubeVela"/>
        <category label="2025" term="2025"/>
        <category label="community" term="community"/>
        <category label="roadmap" term="roadmap"/>
        <category label="CNCF" term="CNCF"/>
        <category label="year-in-review" term="year-in-review"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[KubeVela 1.10.4 Now Available]]></title>
        <id>https://kubevela.io/blog/2025/10/20/release-1.10.4/</id>
        <link href="https://kubevela.io/blog/2025/10/20/release-1.10.4/"/>
        <updated>2025-10-20T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This article discusses the changes released in the latest v1.10.4 release]]></summary>
        <content type="html"><![CDATA[<p><strong>Hello community!</strong> 👋</p>
<p>This is the first blog post in a while but we are excited to reinvigorate the community and keep developers and users up to date with all things KubeVela. The team is committed to providing regular updates, news and information about upcoming events and features.</p>
<p>We recently released the latest v1.10.4 which includes a host of useful features to improve the maintainability of Applications deployed with Kubevela. This blog will provide a quick overview of the features and how you can get started with utilising them in your KubeVela setup.</p>
<p>While v1.10.4 follows semantic versioning as a patch release, we're excited to deliver several new opt-in features alongside the usual bug fixes and improvements.</p>
<p>These features are disabled by default (where applicable) to maintain backward compatibility, allowing users to adopt them at their own pace.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="kubernetes-131-support">Kubernetes 1.31 Support<a href="https://kubevela.io/blog/2025/10/20/release-1.10.4/#kubernetes-131-support" class="hash-link" aria-label="Direct link to Kubernetes 1.31 Support" title="Direct link to Kubernetes 1.31 Support" translate="no">​</a></h2>
<p>The team have put huge efforts into completing the support for Kubernetes v1.31 across all KubeVela repositories.</p>
<p>Users can now confidently run KubeVela on Kubernetes 1.31 with all core functionality validated.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="resource-existence-validation">Resource Existence Validation<a href="https://kubevela.io/blog/2025/10/20/release-1.10.4/#resource-existence-validation" class="hash-link" aria-label="Direct link to Resource Existence Validation" title="Direct link to Resource Existence Validation" translate="no">​</a></h2>
<p>KubeVela users can now validate that the resources being created by their definitions are present on the cluster ahead of deployment of the Application. This new feature will work across Component, Trait, Policy and WorkflowStep definitions to reduce runtime errors and improve the overall reliability of KubeVela deployments.</p>
<p>To get started, developers can set <code>ValidateResourcesExist</code> feature flag in their installations.</p>
<p>See <a href="https://github.com/kubevela/kubevela/pull/6932" target="_blank" rel="noopener noreferrer" class="">PR 6932</a> for more information.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="native-cue-in-health-fields">Native Cue in Health Fields<a href="https://kubevela.io/blog/2025/10/20/release-1.10.4/#native-cue-in-health-fields" class="hash-link" aria-label="Direct link to Native Cue in Health Fields" title="Direct link to Native Cue in Health Fields" translate="no">​</a></h2>
<p>Developers writing workload definitions can now add status attributes in native cue, rather than nested strings. Behind the scenes, the string and cue conversions happen automatically and include some new validations of the attribute types and the presence of required fields.</p>
<p>This feature is enabled by default; but you'll need to ensure to use the latest version of the KubeVela CLI to take advantage of cue formatting. String formatting is completely backwards compatible.</p>
<p>See <a href="https://github.com/kubevela/kubevela/pull/6859" target="_blank" rel="noopener noreferrer" class="">PR 6859</a> for more information.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="enhanced-status-reporting">Enhanced Status Reporting<a href="https://kubevela.io/blog/2025/10/20/release-1.10.4/#enhanced-status-reporting" class="hash-link" aria-label="Direct link to Enhanced Status Reporting" title="Direct link to Enhanced Status Reporting" translate="no">​</a></h2>
<p>Applications had two primary means to communicate status - the <a href="https://kubevela.io/docs/next/platform-engineers/status/definition_health_status/#2-health-check---overall-health-indicator" target="_blank" rel="noopener noreferrer" class="">Health Check</a> and <a href="https://kubevela.io/docs/next/platform-engineers/status/definition_health_status/#2-health-check---overall-health-indicator" target="_blank" rel="noopener noreferrer" class="">Custom Message</a>. Whilst these provide an insight into the overall health of the application and give a succinct human readable summary of current state - we had feedback from developers that they required a longer lived, more detailed way to capture information about managed resources.</p>
<p>Hence, we added the new <a href="https://kubevela.io/docs/next/platform-engineers/status/definition_health_status/#1-status-details---structured-diagnostic-information" target="_blank" rel="noopener noreferrer" class="">Status Details</a> field that can capture a map of any information developers feel is useful for reporting on, debugging or observing their components &amp; traits.</p>
<p>It uses familiar cue syntax to extract information and has access to the full KubeVela context already accessible in Health Checks and Custom Messages.</p>
<p>For example, from the docs:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">attributes: status: details: {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    readyReplicas: context.output.status.readyReplicas</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    totalReplicas: context.output.spec.replicas</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    readyPercentage: (context.output.status.readyReplicas / context.output.spec.replicas) * 100</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    deploymentMode: context.output.spec.strategy.type</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span></code></pre></div></div>
<p>will provide users with the following in their Application status, allowing for better abstraction from the underlying resource.</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">status:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  services:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    - name: my-service</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      status:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        readyReplicas: "3"</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        totalReplicas: "3"</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        readyPercentage: "100"</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        deploymentMode: "RollingUpdate"</span><br></span></code></pre></div></div>
<p>Better still - we've put work into unifying the various status evaluators. The fields captured in Status Details are made available in the Health Check and Custom Message (via <code>context.status.details</code>) so that logic can be better reused. See <a href="https://kubevela.io/docs/next/platform-engineers/status/definition_health_status/#how-status-evaluation-works" target="_blank" rel="noopener noreferrer" class="">How Status Evaluation Works</a> for full details of the changes.</p>
<p>See <a href="https://github.com/kubevela/kubevela/pull/6828" target="_blank" rel="noopener noreferrer" class="">PR 6828</a> or the <a href="https://kubevela.io/docs/next/platform-engineers/status/definition_health_status" target="_blank" rel="noopener noreferrer" class="">revised documentation</a> for more information.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="application-status-metrics">Application Status Metrics<a href="https://kubevela.io/blog/2025/10/20/release-1.10.4/#application-status-metrics" class="hash-link" aria-label="Direct link to Application Status Metrics" title="Direct link to Application Status Metrics" translate="no">​</a></h2>
<p>As part of the fix in <a href="https://github.com/kubevela/kubevela/pull/6824" target="_blank" rel="noopener noreferrer" class="">PR 6824</a> we now ensures that Application health is continuously evaluated, even after the workflow succeeds.</p>
<p>To compliment this, we've added additional application level metrics so that operators can have simplified visibility into the status of their Applications.</p>
<p>These are the:</p>
<ul>
<li class=""><code>kubevela_application_health_status{app_name, namespace}</code></li>
<li class=""><code>kubevela_application_phase{app_name, namespace}</code></li>
<li class=""><code>kubevela_application_workflow_phase{app_name, namespace}</code></li>
</ul>
<p>We've made efforts to ensure these are low cardinality through numeric phase mapping - so operators should be able to collect and monitor these cost effectively in their monitoring solutions.</p>
<p>To add more depth to monitoring capabilities, we've also added structured logging when Application changes occur. These logs capture the Application state in a high detail of detail to supplement the new metrics.</p>
<p>The full structure of these logs can be found <a href="https://kubevela.io/docs/next/platform-engineers/status/application_health_status_metrics/#structured-logging" target="_blank" rel="noopener noreferrer" class="">here</a></p>
<p>To get started, users can enable the EnableApplicationStatusMetrics feature gate to activate both metrics and the new structured logging.</p>
<p>See <a href="https://github.com/kubevela/kubevela/pull/6857" target="_blank" rel="noopener noreferrer" class="">PR 6857</a> or the <a href="https://kubevela.io/docs/next/platform-engineers/status/application_health_status_metrics/" target="_blank" rel="noopener noreferrer" class="">documentation</a> for more information.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="dependency-aware-workflows">Dependency-Aware Workflows<a href="https://kubevela.io/blog/2025/10/20/release-1.10.4/#dependency-aware-workflows" class="hash-link" aria-label="Direct link to Dependency-Aware Workflows" title="Direct link to Dependency-Aware Workflows" translate="no">​</a></h2>
<p><a href="https://github.com/kubevela/kubevela/issues/6852" target="_blank" rel="noopener noreferrer" class="">Issue 6852</a> raised the issue with the confusion of DependsOn <a href="https://kubevela.io/docs/end-user/workflow/component-dependency-parameter/#dependency" target="_blank" rel="noopener noreferrer" class="">within components</a>, and DependsOn <a href="https://kubevela.io/docs/end-user/workflow/dependency/#how-to-use" target="_blank" rel="noopener noreferrer" class="">within workflows</a> - and how workflows did not natively respect component dependencies.</p>
<p>KubeVela will now dynamically add workflow dependencies between steps according to the components dependencies; which is vastly simplified and much more in line with user expectations.</p>
<p>See <a href="https://github.com/kubevela/kubevela/pull/6854" target="_blank" rel="noopener noreferrer" class="">PR 6854</a> for more information.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="colorised-logging-support">Colorised Logging Support<a href="https://kubevela.io/blog/2025/10/20/release-1.10.4/#colorised-logging-support" class="hash-link" aria-label="Direct link to Colorised Logging Support" title="Direct link to Colorised Logging Support" translate="no">​</a></h2>
<p>We've introduced opt-in support for colorised logging to improve the developer debugging experience.</p>
<p>For local development, developers can use the new <code>--dev-logs</code> to enable this for their console output.</p>
<p>This feature is <strong>not</strong> recommended for production &amp; CI usage and is disabled by default. When disabled, existing log functionality is preserved.</p>
<p>The log formatting enhancements include:</p>
<ul>
<li class="">Color-coded structured fields (cyan for keys, grey for values)</li>
<li class="">Emphasized primary message text in bright white</li>
<li class="">Enriched location information (file:method<!-- -->:line<!-- -->)</li>
<li class="">Spring Boot-inspired formatting style</li>
</ul>
<p>See <a href="https://github.com/kubevela/kubevela/pull/6931" target="_blank" rel="noopener noreferrer" class="">PR 6931</a> for more information.</p>
<br>
<h1>Full Release Details</h1>
<p>Of course this blog doesn't capture all of the great work that went into this release. Our contributors have made amazing progress on fixing bugs, handling chore work, bolstering our test suites, providing feedback &amp; issue reports, and much more.</p>
<p>So a huge thank you due to everyone who contributed during this (and all!) release cycles. The full details of the release can be found at <a href="https://github.com/kubevela/kubevela/releases/tag/v1.10.4" target="_blank" rel="noopener noreferrer" class="">v1.10.4</a></p>
<br>
<h1>Give Us Your Feedback</h1>
<p>We are excited for the community to get their hands on these new features and encourage any feedback or contributions to keep improving KubeVela!</p>
<p>Slack: <a href="https://cloud-native.slack.com/archives/C01BLQ3HTJA" target="_blank" rel="noopener noreferrer" class="">#kubevela</a> (English)</p>
<p>Every week we host a <a href="https://github.com/kubevela/community?tab=readme-ov-file#community-meetings" target="_blank" rel="noopener noreferrer" class="">community meeting</a> to showcase new features, review upcoming milestones, and engage in a Q&amp;A. All are welcome!</p>]]></content>
        <author>
            <name>Brian Kane</name>
            <uri>https://github.com/briankane</uri>
        </author>
        <category label="KubeVela" term="KubeVela"/>
        <category label="release-note" term="release-note"/>
        <category label="Kubernetes" term="Kubernetes"/>
        <category label="DevOps" term="DevOps"/>
        <category label="CNCF" term="CNCF"/>
        <category label="CI/CD" term="CI/CD"/>
        <category label="Application delivery" term="Application delivery"/>
        <category label="Role-Based Access Control" term="Role-Based Access Control"/>
        <category label="Telemetry" term="Telemetry"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[LFX Mentorship: Meeting with the KubeVela Community in Open Source]]></title>
        <id>https://kubevela.io/blog/2023/05/30/lfx-cue-generator/</id>
        <link href="https://kubevela.io/blog/2023/05/30/lfx-cue-generator/"/>
        <updated>2023-05-30T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This article describes the experience of participating in the LFX Mentorship program and contributing to the KubeVela community.]]></summary>
        <content type="html"><![CDATA[<p>Hello, I am Junyu Liu (GitHub: iyear), currently a sophomore majoring in software engineering. In this blog post, I will share my experiences as a Linux Foundation Mentorship mentee: from applying for the project to becoming part of the community.</p>
<p>In the spring of 2023, I was accepted as a CNCF student under the KubeVela project through LFX Mentorship. In this project, I am responsible for developing a CUE code and documentation generator based on Golang from scratch, laying the foundation for the infrastructure part of KubeVela's future extensibility.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-is-lfx-mentorship">What is LFX Mentorship?<a href="https://kubevela.io/blog/2023/05/30/lfx-cue-generator/#what-is-lfx-mentorship" class="hash-link" aria-label="Direct link to What is LFX Mentorship?" title="Direct link to What is LFX Mentorship?" translate="no">​</a></h2>
<p><img decoding="async" loading="lazy" alt="LFX Mentorship" src="data:image/svg+xml;base64,PHN2ZyBfbmdjb250ZW50LWdsdi1jND0iIiBpZD0iTGF5ZXJfMSIgZGF0YS1uYW1lPSJMYXllciAxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0OTAgODAiIGNsYXNzPSJpcy1jdXJyZW50Ij48ZGVmcyBfbmdjb250ZW50LWdsdi1jND0iIj48c3R5bGUgX25nY29udGVudC1nbHYtYzQ9IiI+LmNscy0xe2ZpbGw6IzAwOWFkZTt9LmNscy0ye2ZpbGw6IzAwMzc2NDt9LmNscy0ze2ZpbGw6bm9uZTtzdHJva2U6IzAwMzc2NDtzdHJva2UtbWl0ZXJsaW1pdDoxMDtzdHJva2Utd2lkdGg6MC45MXB4O308L3N0eWxlPjwvZGVmcz48cG9seWdvbiBfbmdjb250ZW50LWdsdi1jND0iIiBwb2ludHM9IjExLjA5IDU0LjE3IDExLjA5IDM2LjkxIDIuNDMgMzYuOTEgMi40MyA2Mi44MSAyOC4zNSA2Mi44MSAyOC4zNSA1NC4xNyAxMS4wOSA1NC4xNyIgY2xhc3M9ImNscy0xIj48L3BvbHlnb24+PHBvbHlnb24gX25nY29udGVudC1nbHYtYzQ9IiIgcG9pbnRzPSI0NS42MSAxOS42MyAyLjQ0IDE5LjYzIDIuNDQgMzIuNTggMTEuMDcgMzIuNTggMTEuMDcgMjguMyAzNi45OCAyOC4zIDM2Ljk4IDU0LjE3IDMyLjY2IDU0LjE3IDMyLjY2IDYyLjgxIDQ1LjYxIDYyLjgxIDQ1LjYxIDE5LjYzIiBjbGFzcz0iY2xzLTIiPjwvcG9seWdvbj48cGF0aCBfbmdjb250ZW50LWdsdi1jND0iIiBkPSJNNTQuMzEsMTkuNDlINjcuNjRWNTEuNjVIODYuNzhWNjIuNzRINTQuMzFaIiBjbGFzcz0iY2xzLTIiPjwvcGF0aD48cGF0aCBfbmdjb250ZW50LWdsdi1jND0iIiBkPSJNOTUuMjksMTkuNDRoMzMuNDh2MTEuMUgxMDguNjN2NS40aDE3LjI4VjQ2LjI1SDEwOC42M1Y2Mi43NEg5NS4yOVoiIGNsYXNzPSJjbHMtMiI+PC9wYXRoPjxwYXRoIF9uZ2NvbnRlbnQtZ2x2LWM0PSIiIGQ9Ik0xNDguNDksMzkuNzksMTM0LjMsMTkuNjJoMTUuNThsNi41MiwxMS43Miw2LjQtMTEuNzJoMTQuNzNMMTYzLjcxLDM5LjkxLDE3OS4xLDYyLjc0aC0xNmwtNy4zNy0xMi44Ni03LjYsMTIuODZIMTMyLjkxWiIgY2xhc3M9ImNscy0xIj48L3BhdGg+PHBhdGggX25nY29udGVudC1nbHYtYzQ9IiIgZD0iTTIwNCwxOS42Nmg2bDE0LjgyLDM3LjU3LDE0Ljc3LTM3LjU3aDZWNjIuNTFIMjQxLjV2LTM3aC0uMTJsLTE0LjY1LDM3aC0zLjg0bC0xNC43LTM3aC0uMTJ2MzdIMjA0WiIgY2xhc3M9ImNscy0xIj48L3BhdGg+PHBhdGggX25nY29udGVudC1nbHYtYzQ9IiIgZD0iTTI1NS42LDQ4LjA1YzAsNS41MiwzLDEyLjE4LDEwLjIxLDEyLjE4LDUuNTIsMCw4LjUyLTMuMTgsOS43Mi03LjkyaDMuNzhjLTEuNjIsNy01LjY0LDExLjEtMTMuNSwxMS4xLTkuODUsMC0xNC03LjU3LTE0LTE2LjM5LDAtOC4xNiw0LjE0LTE2LjM4LDE0LTE2LjM4czEzLjkyLDguNywxMy42MiwxNy40MVptMjAtMy4xOWMtLjE4LTUuNy0zLjc4LTExLTkuODQtMTEtNi4yNSwwLTkuNTUsNS40LTEwLjIxLDExWiIgY2xhc3M9ImNscy0xIj48L3BhdGg+PHBhdGggX25nY29udGVudC1nbHYtYzQ9IiIgZD0iTTI4NC40NywzMS41NGgzLjc4djUuMzRoLjEyYzEuNDQtMy43Miw1LjUyLTYuMjQsOS45LTYuMjQsOC43MSwwLDExLjM1LDQuNTYsMTEuMzUsMTEuOTRWNjIuNTFoLTMuNzhWNDMuMThjMC01LjI4LTEuNzQtOS4zNi03Ljg3LTkuMzZzLTkuNTQsNC41Ni05LjcyLDEwLjYyVjYyLjUxaC0zLjc4WiIgY2xhc3M9ImNscy0xIj48L3BhdGg+PHBhdGggX25nY29udGVudC1nbHYtYzQ9IiIgZD0iTTMyMi43NiwzMS41NGg2LjN2My4xOGgtNi4zVjU1LjYxYzAsMi40Ni4zNiwzLjksMy4wNiw0LjA4YTI5LjMyLDI5LjMyLDAsMCwwLDMuMjQtLjE4djMuMjRjLTEuMTQsMC0yLjIyLjEyLTMuMzYuMTItNSwwLTYuNzgtMS42OC02LjcyLTdWMzQuNzJoLTUuNFYzMS41NEgzMTl2LTkuM2gzLjc4WiIgY2xhc3M9ImNscy0xIj48L3BhdGg+PHBhdGggX25nY29udGVudC1nbHYtYzQ9IiIgZD0iTTM2Mi4yNSw0N2MwLDguODktNS4yMiwxNi4zOS0xNC42NCwxNi4zOVMzMzMsNTUuOTEsMzMzLDQ3czUuMjItMTYuMzgsMTQuNjQtMTYuMzhTMzYyLjI1LDM4LjE0LDM2Mi4yNSw0N1ptLTI1LjUsMGMwLDYuNTUsMy42NiwxMy4yMSwxMC44NiwxMy4yMVMzNTguNDcsNTMuNTcsMzU4LjQ3LDQ3cy0zLjY2LTEzLjItMTAuODYtMTMuMlMzMzYuNzUsNDAuNDgsMzM2Ljc1LDQ3WiIgY2xhc3M9ImNscy0xIj48L3BhdGg+PHBhdGggX25nY29udGVudC1nbHYtYzQ9IiIgZD0iTTM2Ny45LDMxLjU0aDMuNDhWMzguOGguMTJhMTEuMzcsMTEuMzcsMCwwLDEsMTEuNy03LjY4VjM0LjljLTYuODQtLjMtMTEuNTIsNC42Mi0xMS41MiwxMS4xVjYyLjUxSDM2Ny45WiIgY2xhc3M9ImNscy0xIj48L3BhdGg+PHBhdGggX25nY29udGVudC1nbHYtYzQ9IiIgZD0iTTQwNS4zNCw0MC42Yy0uMTgtNC42OC0zLjc4LTYuNzgtOC4xLTYuNzgtMy4zNiwwLTcuMzIsMS4zMi03LjMyLDUuMzQsMCwzLjMsMy43OCw0LjU2LDYuNDIsNS4yMmw1LDEuMTRjNC4zMi42Niw4LjgyLDMuMTksOC44Miw4LjU5LDAsNi43Mi02LjY2LDkuMy0xMi40Miw5LjMtNy4yNiwwLTEyLjA2LTMuMy0xMi43Mi0xMC45MmgzLjc4Yy4zLDUuMSw0LjA4LDcuNzQsOS4xMiw3Ljc0LDMuNiwwLDguNDYtMS41Niw4LjQ2LTUuODgsMC0zLjYxLTMuMzYtNC44MS02Ljc4LTUuNjRsLTQuODYtMS4wOWMtNC45Mi0xLjI2LTguNjQtMy4wNi04LjY0LTguMjgsMC02LjMsNi4xOC04LjcsMTEuNjQtOC43LDYuMjQsMCwxMSwzLjI0LDExLjM0LDEwWiIgY2xhc3M9ImNscy0xIj48L3BhdGg+PHBhdGggX25nY29udGVudC1nbHYtYzQ9IiIgZD0iTTQxNS42MSwxOS42NmgzLjc4VjM2Ljg4aC4xMmMxLjQ0LTMuNzIsNS41Mi02LjI0LDkuOS02LjI0LDguNywwLDExLjM0LDQuNTYsMTEuMzQsMTEuOTRWNjIuNTFINDM3VjQzLjE4YzAtNS4yOC0xLjc0LTkuMzYtNy44Ni05LjM2cy05LjU0LDQuNTYtOS43MiwxMC42MlY2Mi41MWgtMy43OFoiIGNsYXNzPSJjbHMtMSI+PC9wYXRoPjxwYXRoIF9uZ2NvbnRlbnQtZ2x2LWM0PSIiIGQ9Ik00NDgsMTkuNjZoMy43OHY2LjA2SDQ0OFptMCwxMS44OGgzLjc4djMxSDQ0OFoiIGNsYXNzPSJjbHMtMSI+PC9wYXRoPjxwYXRoIF9uZ2NvbnRlbnQtZ2x2LWM0PSIiIGQ9Ik00NTksMzEuNTRoMy40OHY1Ljg4aC4xMmMxLjc0LTQuMjYsNi02Ljc4LDExLTYuNzgsOS40MiwwLDEzLjkzLDcuNTYsMTMuOTMsMTYuMzhzLTQuNTEsMTYuMzktMTMuOTMsMTYuMzljLTQuNTYsMC05LjEyLTIuMjgtMTAuNzQtNi43OGgtLjEyVjc0SDQ1OVptMTQuNjQsMi4yOGMtOC40LDAtMTAuODYsNi4xOC0xMC44NiwxMy4yLDAsNi40MiwyLjg4LDEzLjIxLDEwLjg2LDEzLjIxLDcuMiwwLDEwLjE1LTYuNzksMTAuMTUtMTMuMjFTNDgwLjg0LDMzLjgyLDQ3My42NCwzMy44MloiIGNsYXNzPSJjbHMtMSI+PC9wYXRoPjxsaW5lIF9uZ2NvbnRlbnQtZ2x2LWM0PSIiIHgxPSIxOTAuNzEiIHkxPSI3NS40OCIgeDI9IjE5MC43MSIgeTI9IjMuNDkiIGNsYXNzPSJjbHMtMyI+PC9saW5lPjxwb2x5Z29uIF9uZ2NvbnRlbnQtZ2x2LWM0PSIiIHBvaW50cz0iMTEuMDkgNTQuMTcgMTEuMDkgMzYuOTEgMi40MyAzNi45MSAyLjQzIDYyLjgxIDI4LjM1IDYyLjgxIDI4LjM1IDU0LjE3IDExLjA5IDU0LjE3IiBjbGFzcz0iY2xzLTEiPjwvcG9seWdvbj48cG9seWdvbiBfbmdjb250ZW50LWdsdi1jND0iIiBwb2ludHM9IjQ1LjYxIDE5LjYzIDIuNDQgMTkuNjMgMi40NCAzMi41OCAxMS4wNyAzMi41OCAxMS4wNyAyOC4zIDM2Ljk4IDI4LjMgMzYuOTggNTQuMTcgMzIuNjYgNTQuMTcgMzIuNjYgNjIuODEgNDUuNjEgNjIuODEgNDUuNjEgMTkuNjMiIGNsYXNzPSJjbHMtMiI+PC9wb2x5Z29uPjxwYXRoIF9uZ2NvbnRlbnQtZ2x2LWM0PSIiIGQ9Ik01NC4zMSwxOS40OUg2Ny42NFY1MS42NUg4Ni43OFY2Mi43NEg1NC4zMVoiIGNsYXNzPSJjbHMtMiI+PC9wYXRoPjxwYXRoIF9uZ2NvbnRlbnQtZ2x2LWM0PSIiIGQ9Ik05NS4yOSwxOS40NGgzMy40OHYxMS4xSDEwOC42M3Y1LjRoMTcuMjhWNDYuMjVIMTA4LjYzVjYyLjc0SDk1LjI5WiIgY2xhc3M9ImNscy0yIj48L3BhdGg+PHBhdGggX25nY29udGVudC1nbHYtYzQ9IiIgZD0iTTE0OC40OSwzOS43OSwxMzQuMywxOS42MmgxNS41OGw2LjUyLDExLjcyLDYuNC0xMS43MmgxNC43M0wxNjMuNzEsMzkuOTEsMTc5LjEsNjIuNzRoLTE2bC03LjM3LTEyLjg2LTcuNiwxMi44NkgxMzIuOTFaIiBjbGFzcz0iY2xzLTEiPjwvcGF0aD48cGF0aCBfbmdjb250ZW50LWdsdi1jND0iIiBkPSJNMjA0LDE5LjY2aDZsMTQuODIsMzcuNTcsMTQuNzctMzcuNTdoNlY2Mi41MUgyNDEuNXYtMzdoLS4xMmwtMTQuNjUsMzdoLTMuODRsLTE0LjctMzdoLS4xMnYzN0gyMDRaIiBjbGFzcz0iY2xzLTEiPjwvcGF0aD48cGF0aCBfbmdjb250ZW50LWdsdi1jND0iIiBkPSJNMjU1LjYsNDguMDVjMCw1LjUyLDMsMTIuMTgsMTAuMjEsMTIuMTgsNS41MiwwLDguNTItMy4xOCw5LjcyLTcuOTJoMy43OGMtMS42Miw3LTUuNjQsMTEuMS0xMy41LDExLjEtOS44NSwwLTE0LTcuNTctMTQtMTYuMzksMC04LjE2LDQuMTQtMTYuMzgsMTQtMTYuMzhzMTMuOTIsOC43LDEzLjYyLDE3LjQxWm0yMC0zLjE5Yy0uMTgtNS43LTMuNzgtMTEtOS44NC0xMS02LjI1LDAtOS41NSw1LjQtMTAuMjEsMTFaIiBjbGFzcz0iY2xzLTEiPjwvcGF0aD48cGF0aCBfbmdjb250ZW50LWdsdi1jND0iIiBkPSJNMjg0LjQ3LDMxLjU0aDMuNzh2NS4zNGguMTJjMS40NC0zLjcyLDUuNTItNi4yNCw5LjktNi4yNCw4LjcxLDAsMTEuMzUsNC41NiwxMS4zNSwxMS45NFY2Mi41MWgtMy43OFY0My4xOGMwLTUuMjgtMS43NC05LjM2LTcuODctOS4zNnMtOS41NCw0LjU2LTkuNzIsMTAuNjJWNjIuNTFoLTMuNzhaIiBjbGFzcz0iY2xzLTEiPjwvcGF0aD48cGF0aCBfbmdjb250ZW50LWdsdi1jND0iIiBkPSJNMzIyLjc2LDMxLjU0aDYuM3YzLjE4aC02LjNWNTUuNjFjMCwyLjQ2LjM2LDMuOSwzLjA2LDQuMDhhMjkuMzIsMjkuMzIsMCwwLDAsMy4yNC0uMTh2My4yNGMtMS4xNCwwLTIuMjIuMTItMy4zNi4xMi01LDAtNi43OC0xLjY4LTYuNzItN1YzNC43MmgtNS40VjMxLjU0SDMxOXYtOS4zaDMuNzhaIiBjbGFzcz0iY2xzLTEiPjwvcGF0aD48cGF0aCBfbmdjb250ZW50LWdsdi1jND0iIiBkPSJNMzYyLjI1LDQ3YzAsOC44OS01LjIyLDE2LjM5LTE0LjY0LDE2LjM5UzMzMyw1NS45MSwzMzMsNDdzNS4yMi0xNi4zOCwxNC42NC0xNi4zOFMzNjIuMjUsMzguMTQsMzYyLjI1LDQ3Wm0tMjUuNSwwYzAsNi41NSwzLjY2LDEzLjIxLDEwLjg2LDEzLjIxUzM1OC40Nyw1My41NywzNTguNDcsNDdzLTMuNjYtMTMuMi0xMC44Ni0xMy4yUzMzNi43NSw0MC40OCwzMzYuNzUsNDdaIiBjbGFzcz0iY2xzLTEiPjwvcGF0aD48cGF0aCBfbmdjb250ZW50LWdsdi1jND0iIiBkPSJNMzY3LjksMzEuNTRoMy40OFYzOC44aC4xMmExMS4zNywxMS4zNywwLDAsMSwxMS43LTcuNjhWMzQuOWMtNi44NC0uMy0xMS41Miw0LjYyLTExLjUyLDExLjFWNjIuNTFIMzY3LjlaIiBjbGFzcz0iY2xzLTEiPjwvcGF0aD48cGF0aCBfbmdjb250ZW50LWdsdi1jND0iIiBkPSJNNDA1LjM0LDQwLjZjLS4xOC00LjY4LTMuNzgtNi43OC04LjEtNi43OC0zLjM2LDAtNy4zMiwxLjMyLTcuMzIsNS4zNCwwLDMuMywzLjc4LDQuNTYsNi40Miw1LjIybDUsMS4xNGM0LjMyLjY2LDguODIsMy4xOSw4LjgyLDguNTksMCw2LjcyLTYuNjYsOS4zLTEyLjQyLDkuMy03LjI2LDAtMTIuMDYtMy4zLTEyLjcyLTEwLjkyaDMuNzhjLjMsNS4xLDQuMDgsNy43NCw5LjEyLDcuNzQsMy42LDAsOC40Ni0xLjU2LDguNDYtNS44OCwwLTMuNjEtMy4zNi00LjgxLTYuNzgtNS42NGwtNC44Ni0xLjA5Yy00LjkyLTEuMjYtOC42NC0zLjA2LTguNjQtOC4yOCwwLTYuMyw2LjE4LTguNywxMS42NC04LjcsNi4yNCwwLDExLDMuMjQsMTEuMzQsMTBaIiBjbGFzcz0iY2xzLTEiPjwvcGF0aD48cGF0aCBfbmdjb250ZW50LWdsdi1jND0iIiBkPSJNNDE1LjYxLDE5LjY2aDMuNzhWMzYuODhoLjEyYzEuNDQtMy43Miw1LjUyLTYuMjQsOS45LTYuMjQsOC43LDAsMTEuMzQsNC41NiwxMS4zNCwxMS45NFY2Mi41MUg0MzdWNDMuMThjMC01LjI4LTEuNzQtOS4zNi03Ljg2LTkuMzZzLTkuNTQsNC41Ni05LjcyLDEwLjYyVjYyLjUxaC0zLjc4WiIgY2xhc3M9ImNscy0xIj48L3BhdGg+PHBhdGggX25nY29udGVudC1nbHYtYzQ9IiIgZD0iTTQ0OCwxOS42NmgzLjc4djYuMDZINDQ4Wm0wLDExLjg4aDMuNzh2MzFINDQ4WiIgY2xhc3M9ImNscy0xIj48L3BhdGg+PHBhdGggX25nY29udGVudC1nbHYtYzQ9IiIgZD0iTTQ1OSwzMS41NGgzLjQ4djUuODhoLjEyYzEuNzQtNC4yNiw2LTYuNzgsMTEtNi43OCw5LjQyLDAsMTMuOTMsNy41NiwxMy45MywxNi4zOHMtNC41MSwxNi4zOS0xMy45MywxNi4zOWMtNC41NiwwLTkuMTItMi4yOC0xMC43NC02Ljc4aC0uMTJWNzRINDU5Wm0xNC42NCwyLjI4Yy04LjQsMC0xMC44Niw2LjE4LTEwLjg2LDEzLjIsMCw2LjQyLDIuODgsMTMuMjEsMTAuODYsMTMuMjEsNy4yLDAsMTAuMTUtNi43OSwxMC4xNS0xMy4yMVM0ODAuODQsMzMuODIsNDczLjY0LDMzLjgyWiIgY2xhc3M9ImNscy0xIj48L3BhdGg+PGxpbmUgX25nY29udGVudC1nbHYtYzQ9IiIgeDE9IjE5MC43MSIgeTE9Ijc1LjQ4IiB4Mj0iMTkwLjcxIiB5Mj0iMy40OSIgY2xhc3M9ImNscy0zIj48L2xpbmU+PC9zdmc+Cg==" width="490" height="80" class="img_ev3q"></p>
<p><a href="https://lfx.linuxfoundation.org/tools/mentorship" target="_blank" rel="noopener noreferrer" class="">LFX Mentorship</a> is a remote learning program that provides 12 weeks of learning opportunities for open source contributors. It is led by specific mentors (usually the maintainers of the projects) who help mentees contribute to the community and projects.</p>
<p>Many open-source organizations or foundations use LFX Mentorship to announce projects and recruit students for development and contributions. I focused on the cloud-native and noticed that CNCF started its spring projects on LFX in February 2023. I began to explore and apply for projects that interested me.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-is-kubevela">What is KubeVela?<a href="https://kubevela.io/blog/2023/05/30/lfx-cue-generator/#what-is-kubevela" class="hash-link" aria-label="Direct link to What is KubeVela?" title="Direct link to What is KubeVela?" translate="no">​</a></h2>
<p><img decoding="async" loading="lazy" alt="KubeVela" src="https://kubevela.io/assets/images/kubevela-logo-6eb605b70e884c4c4c3f439086b8438e.png" width="1080" height="273" class="img_ev3q"></p>
<p><a href="https://kubevela.io/" target="_blank" rel="noopener noreferrer" class="">KubeVela</a> is a modern software delivery and management control plane. The goal is to make deploying and operating applications across today's hybrid, multi-cloud environments easier, faster and more reliable.</p>
<p>KubeVela originated from the Open Application Model (OAM) model based on Kubernetes, jointly launched by Alibaba Cloud and Microsoft at the end of 2019. Through continuous evolution and iteration, it has incorporated a large amount of feedback and contributions from the open-source community (especially participants from Microsoft, ByteDance, 4Paradigm, Tencent, and Full Truck Alliance). In 2020, it officially met the open-source community under the name "KubeVela" at KubeCon North America.</p>
<p>The KubeVela project has been developing rapidly, and its community growth trend is as follows:
<img decoding="async" loading="lazy" alt="KubeVela Community" src="https://kubevela.io/assets/images/kubevela-community-254b4f2cf0543c344c7fe3186d1d5259.png" width="1920" height="1080" class="img_ev3q"></p>
<p>It is worth mentioning that in March, KubeVela was promoted to a CNCF incubation project, further proving the stability and flexibility of KubeVela in production environments.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="project-details">Project Details<a href="https://kubevela.io/blog/2023/05/30/lfx-cue-generator/#project-details" class="hash-link" aria-label="Direct link to Project Details" title="Direct link to Project Details" translate="no">​</a></h2>
<p><strong>Project Name:</strong> Support auto generation of CUE schema and docs from Go struct</p>
<p><strong>Project Description:</strong> In KubeVela's provider system, we can use our defined Go functions in CUE schema. The Go providers usually have a parameter and return. Fields in Go providers are the same as fields in CUE schema, so it is possible and important to support automatic generation of CUE schemas and documents from Go structs.</p>
<p><strong>Project Outcome:</strong> Auto-generators of CUE schemas and docs from Go structs, the capabilities should be wrapped in vela cli command.</p>
<p><strong>Project Mentors:</strong> <a href="https://github.com/FogDong" target="_blank" rel="noopener noreferrer" class="">Fog Dong</a>, <a href="https://github.com/Somefive" target="_blank" rel="noopener noreferrer" class="">Da Yin</a></p>
<p><strong>Project Link:</strong> <a href="https://mentorship.lfx.linuxfoundation.org/project/85f61cae-02d7-4931-8d87-d3da3128060e" target="_blank" rel="noopener noreferrer" class="">https://mentorship.lfx.linuxfoundation.org/project/85f61cae-02d7-4931-8d87-d3da3128060e</a></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="application-and-development">Application and Development<a href="https://kubevela.io/blog/2023/05/30/lfx-cue-generator/#application-and-development" class="hash-link" aria-label="Direct link to Application and Development" title="Direct link to Application and Development" translate="no">​</a></h2>
<p>When browsing through the project list, KubeVela quickly became one of my candidates. Before diving into the cloud-native, I had come across the KubeVela project and attempted to understand its concepts and working principles, but due to my limited expertise, I only scratched the surface. This time, if I could familiarize myself with KubeVela through a small entry point, it would be the best contribution path. Additionally, metaprogramming and code generation are important techniques in Golang, and I also wanted to participate in this project as an opportunity for practical experience.</p>
<p>The project involves the core part of KubeVela: <a href="https://cuelang.org/" target="_blank" rel="noopener noreferrer" class="">CUE</a>. This is the first concept I needed to understand. Through the <a href="https://kubevela.io/zh/docs/platform-engineers/cue/basic" target="_blank" rel="noopener noreferrer" class="">KubeVela official documentation</a> and <a href="https://github.com/cue-lang/cue/issues?q=is%3Aopen+is%3Aissue+label%3Ax%2Fuser%2FKubeVela" target="_blank" rel="noopener noreferrer" class="">CUE Issues</a>, I realized that CUE is a language designed for configuration, with advantages compared to other languages in terms of programmability, automation, and integration with Golang. On the other hand, as KubeVela evolves, it continuously provides practical use cases and feedback for CUE.</p>
<p>After contacting the mentor, my initial goal was to create a demo as a showcase. The core part of the entire project lies in the conversion between Golang AST and CUE AST. I first found a snippet of <a href="https://github.com/cue-lang/cue/blob/master/cmd/cue/cmd/get_go.go" target="_blank" rel="noopener noreferrer" class="">code</a> that I could learn from. After thoroughly understanding it, I extracted the core parts, made modifications and adaptations, and implemented the struct conversion for the demo.
<img decoding="async" loading="lazy" alt="DEMO" src="https://kubevela.io/assets/images/kubevela-demo-e5991a9429a9c7162ed4908e1a7027ee.png" width="1396" height="655" class="img_ev3q"></p>
<p>By writing the demo, I gained a clearer understanding of the overall project targets. As the top-level language for users and platform developers, CUE needs to interact with Golang extensively, serving as an intermediary to connect and control cloud platforms. In many scenarios, CUE needs to maintain consistency with Golang code, or else there may be errors in the intermediate conversion. This process is time-consuming, labor-intensive and issues are only exposed at runtime, which can potentially impact the stability of production environments. The aim of this project is to solve this problem, making Golang code the single source of truth and ensuring overall configuration consistency through static code generation.</p>
<p>In the <a href="https://github.com/kubevela/kubevela/issues/5364" target="_blank" rel="noopener noreferrer" class="">project description issue</a>, the mentor provided an example of generating providers. Everything became clear: I divided the CUE Generator into three layers. The bottom layer is responsible for basic and core AST conversions. The middle layer reads specific Golang code, such as providers, policies, etc. , extracts information from the Golang code, and writes it into CUE files. The top layer exposes the generation capability as a CLI to users and developers, allowing them to quickly generate CUE and documentation. When supporting more different formats of CUE in the future, the underlying transformation capabilities can be easily reused.</p>
<p>After further communication with the mentor, I added support for struct tags and comments and summarized some ideas into the proposal. After a series of iterations and discussions, the project has taken shape, and I am honored to have been accepted as a mentee in the LFX Mentorship program.</p>
<p><img decoding="async" loading="lazy" alt="Acceptance" src="https://kubevela.io/assets/images/kubevela-accept-7f2414b12fadf825aa4a29144452596a.png" width="1056" height="811" class="img_ev3q"></p>
<p>Following the initial design and demo, the formal development process went relatively smoothly, with most of the communication focused on user experience and detailed design.</p>
<p>The first pull request (PR) received valuable reviews as it was not split into smaller parts, and it took 50 comments before it was finally merged. Since the initial code was written in a casual manner, I also focused on refactoring parts of the code to make it more clear and robust.</p>
<p>From the first PR in February to the fifteenth PR at the end of May, the project is essentially complete, and all the code has been merged into the main branch. It has also passed two mentor evaluations, and I am about to graduate from the first project of LFX Mentorship program.👏</p>
<p><img decoding="async" loading="lazy" alt="End-Term Evaluation" src="https://kubevela.io/assets/images/kubevela-end-term-54cc2fe65d8dcf43cb8ee963a580ba49.png" width="1974" height="711" class="img_ev3q"></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="project-outcomes">Project Outcomes<a href="https://kubevela.io/blog/2023/05/30/lfx-cue-generator/#project-outcomes" class="hash-link" aria-label="Direct link to Project Outcomes" title="Direct link to Project Outcomes" translate="no">​</a></h2>
<p>Over the past three months of development, the project has primarily produced three capabilities and two CLIs, with test coverage exceeding 90%.</p>
<p>The core capabilities of the project are located in the <a href="https://github.com/kubevela/kubevela/tree/master/references/cuegen" target="_blank" rel="noopener noreferrer" class="">references/cuegen</a> directory. It implements the basic functionality of converting Go AST to CUE AST and is accompanied by a README to provide developers with specific conversion rules. The code for the middle layer is placed in the <a href="https://github.com/kubevela/kubevela/tree/master/references/cuegen/generators" target="_blank" rel="noopener noreferrer" class="">references/cuegen/generators</a> directory, and generators for the provider format have been implemented so far. The documentation generation component is located in <a href="https://github.com/kubevela/kubevela/blob/master/references/docgen/provider.go" target="_blank" rel="noopener noreferrer" class="">references/docgen/provider.go</a>.</p>
<p>The project has added two CLI subcommands, namely <a href="https://github.com/kubevela/kubevela/blob/master/references/cli/def.go#L1153" target="_blank" rel="noopener noreferrer" class="">vela def gen-cue</a> and <a href="https://github.com/kubevela/kubevela/blob/master/references/cli/def.go#L1205" target="_blank" rel="noopener noreferrer" class="">vela def gen-doc</a>. The former generates CUE files in the corresponding format from Go code, exposing the capabilities of the middle layer as a CLI, while the latter generates documentation for CUE.</p>
<p>Since <code>vela def gen-cue</code> only supports one file at a time, a shell script was written to enable batch generation by traversing directories: <a href="https://github.com/kubevela/kubevela/pull/6009" target="_blank" rel="noopener noreferrer" class="">#6009</a></p>
<p>Taking the code snippet from <a href="https://github.com/kubevela/pkg/blob/main/cue/cuex/providers/kube/kube.go" target="_blank" rel="noopener noreferrer" class="">kubevela/pkg/providers/kube</a> as an example, let's perform the transformation and verification.</p>
<p>First, convert <code>kube.go</code> to <code>kube.cue</code>:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">$ vela def gen-cue \</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	-t provider \</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	--types *k8s.io/apimachinery/pkg/apis/meta/v1/unstructured.Unstructured=ellipsis \</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	--types *k8s.io/apimachinery/pkg/apis/meta/v1/unstructured.UnstructuredList=ellipsis \</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	kube.go &gt; kube.cue</span><br></span></code></pre></div></div>
<p>Then, convert <code>kube.cue</code> to <code>kube.md</code>:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">$ vela def gen-doc -t provider kube.cue &gt; kube.md</span><br></span></code></pre></div></div>
<p>The final result is as follows:</p>
<p><img decoding="async" loading="lazy" alt="Final Generated Result" src="https://kubevela.io/assets/images/kubevela-kube-e716d1f72373226bdea2fc4e25bad8da.png" width="4500" height="4000" class="img_ev3q"></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="future-outlook">Future Outlook<a href="https://kubevela.io/blog/2023/05/30/lfx-cue-generator/#future-outlook" class="hash-link" aria-label="Direct link to Future Outlook" title="Direct link to Future Outlook" translate="no">​</a></h2>
<p>Although the expected outcomes of LFX Mentorship have been fully achieved, it is only the first step for cuegen, and its derivative work will also play an important role in the future development of KubeVela. For example, based on cuegen, we can automate the generation of policy rules that are currently manually maintained. We can migrate and validate the existing providers in <a href="https://github.com/kubevela/pkg/tree/main/cue/cuex/providers" target="_blank" rel="noopener noreferrer" class="">kubevela/pkg</a>. We can also develop scaffolding tools for user-defined providers, all of which rely on the capabilities of cuegen. These will be the key areas of my future work in the community.</p>
<p>In addition to the related work in the cuegen ecosystem, I will also delve into other aspects of KubeVela, such as gaining in-depth familiarity with OAM production practices and the user community, and exploring the possibilities of new features by reading the source code of Workflow component. I have also initiated an application to become a KubeVela Reviewer, aiming to contribute to the project's code quality control.</p>
<p>This is my first participation in the LFX Mentorship program, and throughout the three months of communication and collaboration, both mentors have provided me with a lot of help and guidance in terms of details and decision-making. We also conducted a complete demonstration of the functionality and discussed the future direction of the community through online meetings.</p>
<p>Open source is a process driven by interests and self-motivation. Developers can continuously improve themselves through their experiences in different communities and grow together with the community. Open source is about taking the first step with courage and trying to read the source code of projects that interest you. For students, participation in open source is primarily a learning process, and each step brings different rewards and insights. I am very grateful to have encountered the KubeVela community through LFX Mentorship, and I look forward to further deepening my involvement and contributions to the community in the future!</p>]]></content>
        <author>
            <name>Junyu Liu</name>
            <uri>https://github.com/iyear</uri>
        </author>
        <category label="KubeVela" term="KubeVela"/>
        <category label="LFX" term="LFX"/>
        <category label="Mentorship" term="Mentorship"/>
        <category label="CNCF" term="CNCF"/>
        <category label="CUE" term="CUE"/>
        <category label="Generator" term="Generator"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[PromptOps in Application Delivery: Empowering Your Workflow with ChatGPT]]></title>
        <id>https://kubevela.io/blog/2023/04/06/workflow-chat-gpt/</id>
        <link href="https://kubevela.io/blog/2023/04/06/workflow-chat-gpt/"/>
        <updated>2023-04-06T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This article introduces how to use ChatGPT in your KubeVela Workflow]]></summary>
        <content type="html"><![CDATA[<p>ChatGPT is taking the tech industry by storm, thanks to its unparalleled natural language processing capabilities. As a powerful AI language model, it has the ability to understand and generate human-like responses, revolutionizing communication in various industries. From streamlining customer service chatbots to enabling seamless language translation tools, ChatGPT has already proved its mettle in creating innovative solutions that improve efficiency and user experience.</p>
<p>Now the question is, can we leverage ChatGPT to transform the way we deliver applications? With the integration of ChatGPT into DevOps workflows, we are witnessing the possible emergence of a new era of automation called PromptOps. This advancement in AIOps technology is revolutionizing the way businesses operate, allowing for faster and more efficient application delivery.</p>
<p>In this article, we will explore how to integrate ChatGPT into your DevOps workflow to deliver applications.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="integrate-chatgpt-into-your-devops-workflow">Integrate ChatGPT into Your DevOps Workflow<a href="https://kubevela.io/blog/2023/04/06/workflow-chat-gpt/#integrate-chatgpt-into-your-devops-workflow" class="hash-link" aria-label="Direct link to Integrate ChatGPT into Your DevOps Workflow" title="Direct link to Integrate ChatGPT into Your DevOps Workflow" translate="no">​</a></h2>
<p>When it comes to integrating ChatGPT into DevOps workflows, many developers are faced with the challenge of managing extra resources and writing complicated shells. However, there is a better way - <a href="https://github.com/kubevela/workflow" target="_blank" rel="noopener noreferrer" class="">KubeVela Workflow</a>. This open-source cloud-native workflow project offers a streamlined solution that eliminates the need for pods or complex scripting.</p>
<p>In KubeVela Workflow, every step has a type that can be easily abstracted and reused. The step-type is programmed in <a href="https://cuelang.org/" target="_blank" rel="noopener noreferrer" class="">CUE</a> language, making it incredibly easy to customize and use atomic capabilities like a function call in every step. An important point to note is that with all these atomic capabilities, such as HTTP requests, it is possible to integrate ChatGPT in just 5 minutes by writing a new step.</p>
<blockquote>
<p>Check out the <a href="https://github.com/kubevela/workflow#installation" target="_blank" rel="noopener noreferrer" class="">Installation Guide</a> to get started with KubeVela Workflow.
The complete code of this <code>chat-gpt</code> step type is available at <a href="https://github.com/kubevela/workflow/blob/main/charts/vela-workflow/templates/definitions/chat-gpt.yaml" target="_blank" rel="noopener noreferrer" class="">GitHub</a>.</p>
</blockquote>
<p>Now that we choose the right tool, let's see the capabilities of ChatGPT in delivery.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="case-1-diagnose-the-resources">Case 1: Diagnose the resources<a href="https://kubevela.io/blog/2023/04/06/workflow-chat-gpt/#case-1-diagnose-the-resources" class="hash-link" aria-label="Direct link to Case 1: Diagnose the resources" title="Direct link to Case 1: Diagnose the resources" translate="no">​</a></h3>
<p>It's quite common in the DevOps world to encounter problems like "I don't know why the pod is not running" or "I don't know why the service is not available". In this case, we can use ChatGPT to diagnose the resource.</p>
<p>For example, In our workflow, we can apply a Deployment with an invalid image in the first step. Since the deployment will never be ready, we can add a timeout in the step to ensure the workflow is not stuck in this step. Then, passing the unhealthy resources deployed in the first step to the second step, we can use the <code>chat-gpt</code> step type to diagnose the resource to determine the issue. Note that the second step is only executed if the first one fails.</p>
<p><img decoding="async" loading="lazy" alt="The process of diagnosing the resource in the workflow" src="https://kubevela.io/assets/images/img1-b2fae94297852e92dbd0b456741da298.png" title="The process of diagnosing the resource in the workflow" width="1798" height="842" class="img_ev3q"></p>
<p>The complete workflow is shown below:</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token key atrule">apiVersion</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> core.oam.dev/v1alpha1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> WorkflowRun</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">metadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> chat</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">gpt</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">diagnose</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">namespace</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> default</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">spec</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">workflowSpec</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">steps</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token comment" style="color:rgb(98, 114, 164)"># Apply an invalid deployment with a timeout</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> apply</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> apply</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">deployment</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">timeout</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> 3s</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">image</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> invalid</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token comment" style="color:rgb(98, 114, 164)"># output the resource to the next step</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">outputs</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> resource</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">valueFrom</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> output.value</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token comment" style="color:rgb(98, 114, 164)"># Use chat-gpt to diagnose the resource</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> chat</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">diagnose</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token comment" style="color:rgb(98, 114, 164)"># only execute this step if the `apply` step fails</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">if</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> status.apply.failed</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> chat</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">gpt</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token comment" style="color:rgb(98, 114, 164)"># use the resource as inputs and pass it to prompt.content</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">inputs</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">from</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> resource</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">parameterKey</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> prompt.content</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">token</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">value</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> &lt;your token</span><span class="token punctuation" style="color:rgb(248, 248, 242)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">prompt</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> diagnose</span><br></span></code></pre></div></div>
<p>Apply this Workflow and check the result, the first step will fail because of timeout. Then the second step will be executed and the result of chat-gpt will be shown in the log:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela workflow logs chat-gpt-diagnose</span><br></span></code></pre></div></div>
<p><img decoding="async" loading="lazy" alt="The logs of diagnose step" src="https://kubevela.io/assets/images/img2-30f74564ea9bc7e56fbc8cfb6369ac78.png" title="The logs of diagnose step" width="1264" height="374" class="img_ev3q"></p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="visualize-in-the-dashboard">Visualize in the dashboard<a href="https://kubevela.io/blog/2023/04/06/workflow-chat-gpt/#visualize-in-the-dashboard" class="hash-link" aria-label="Direct link to Visualize in the dashboard" title="Direct link to Visualize in the dashboard" translate="no">​</a></h4>
<p>If you want to visualize the process and the result in the dashboard, it's time to enable the <code>[velaux](https://kubevela.io/docs/reference/addons/velaux#install)</code> addon.</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela addon enable velaux</span><br></span></code></pre></div></div>
<p>Copy all the steps in the above yaml to create a pipeline.</p>
<p><img decoding="async" loading="lazy" alt="Create the pipeline in VelaUX" src="https://kubevela.io/assets/images/img3-0407e16923770130d714e86dd1caaa45.png" title="Create the pipeline in VelaUX" width="3832" height="1840" class="img_ev3q"></p>
<p>Run this pipeline, and you can check out the failed reason analyzed by ChatGPT in the logs of the second step.</p>
<p><img decoding="async" loading="lazy" alt="Run the pipeline in VelaUX" src="https://kubevela.io/assets/images/img4-1f54d287233469fde6f01fdf3725a033.png" title="Run the pipeline in VelaUX" width="3312" height="1664" class="img_ev3q"></p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="write-the-chat-gpt-step-from-scratch">Write the <code>chat-gpt</code> step from scratch<a href="https://kubevela.io/blog/2023/04/06/workflow-chat-gpt/#write-the-chat-gpt-step-from-scratch" class="hash-link" aria-label="Direct link to write-the-chat-gpt-step-from-scratch" title="Direct link to write-the-chat-gpt-step-from-scratch" translate="no">​</a></h4>
<p>How to write this <code>chat-gpt</code> step type? Is it simple for you to write a step type like this? Let's see how to complete this step type.</p>
<p>We can first define what this step type need from the user. That is: the users' token for ChatGPT, and the resource to diagnose. For some other parameters like the model or the request timeout, we can set the default value with <code>*</code> like below:</p>
<div class="language-cue codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cue codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">parameter</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  token</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> value</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">string</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	</span><span class="token comment" style="color:rgb(98, 114, 164)">// +usage=the model name</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	model</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token operator">*</span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"gpt-3.5-turbo"</span><span class="token plain"> </span><span class="token operator">|</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">string</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	</span><span class="token comment" style="color:rgb(98, 114, 164)">// +usage=the prompt to use</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	prompt</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">		type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">    </span><span class="token operator">*</span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"diagnose"</span><span class="token plain"> </span><span class="token operator">|</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">string</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">		lang</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">    </span><span class="token operator">*</span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"English"</span><span class="token plain"> </span><span class="token operator">|</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">string</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">		content</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token operator">...</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	timeout</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token operator">*</span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"30s"</span><span class="token plain"> </span><span class="token operator">|</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">string</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></div></div>
<p>Let's complete this step type by writing the logic of the step. We can first import <code>vela/op</code> package in which we can use the <code>op.#HTTPDo</code> capability to send a request to the ChatGPT API. If the request fails, the step should be failed with <code>op.#Fail</code>. We can also set this step's log data with ChatGPT's answer. The complete step type is shown below:</p>
<div class="language-cue codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cue codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">// import packages</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	</span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"vela/op"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	</span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"encoding/json"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)">// this is the name of the step type</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"chat-gpt"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	description</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"Send request to chat-gpt"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"workflow-step"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)">// this is the logic of the step type</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">template</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token comment" style="color:rgb(98, 114, 164)">// send http request to chat gpt</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	http</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> op</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">#HTTPDo </span><span class="token operator">&amp;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">		method</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"POST"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">		url</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">    </span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"https://api.openai.com/v1/chat/completions"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">		request</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">			timeout</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> parameter</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">timeout</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">			body</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">    json</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">Marshal</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">				model</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> parameter</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">model</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">				messages</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">					</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> parameter</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">prompt</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">type </span><span class="token operator">==</span><span class="token plain"> </span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"diagnose"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">						content</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> """</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">You are a professional kubernetes administrator</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Carefully read the provided information</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> being certain to spell out the diagnosis </span><span class="token operator">&amp;</span><span class="token plain"> reasoning</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> and don't skip any steps</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Answer </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">in</span><span class="token plain">  \</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">parameter</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">prompt</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">lang</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token operator">-</span><span class="token operator">-</span><span class="token operator">-</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">\</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">json</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">Marshal</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">parameter</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">prompt</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">content</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token operator">-</span><span class="token operator">-</span><span class="token operator">-</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">What is wrong with this object and how to fix it</span><span class="token operator">?</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">"""</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">					</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">					role</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"user"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">				</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">			</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">			header</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">				</span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"Content-Type"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">  </span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"application/json"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">				</span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"Authorization"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"Bearer </span><span class="token string-literal interpolation punctuation" style="color:rgb(248, 248, 242)">\(</span><span class="token string-literal interpolation expression">parameter</span><span class="token string-literal interpolation expression punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token string-literal interpolation expression">token</span><span class="token string-literal interpolation expression punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token string-literal interpolation expression">value</span><span class="token string-literal interpolation punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">			</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">		</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	response</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> json</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">Unmarshal</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">http</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">response</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">body</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	fail</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">     op</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">#Steps </span><span class="token operator">&amp;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">		</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> http</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">response</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">statusCode </span><span class="token operator">&gt;=</span><span class="token plain"> </span><span class="token number">400</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">			requestFail</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> op</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">#Fail </span><span class="token operator">&amp;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">				message</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"</span><span class="token string-literal interpolation punctuation" style="color:rgb(248, 248, 242)">\(</span><span class="token string-literal interpolation expression">http</span><span class="token string-literal interpolation expression punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token string-literal interpolation expression">response</span><span class="token string-literal interpolation expression punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token string-literal interpolation expression">statusCode</span><span class="token string-literal interpolation punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token string-literal string" style="color:rgb(255, 121, 198)">: failed to request: </span><span class="token string-literal interpolation punctuation" style="color:rgb(248, 248, 242)">\(</span><span class="token string-literal interpolation expression">response</span><span class="token string-literal interpolation expression punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token string-literal interpolation expression">error</span><span class="token string-literal interpolation expression punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token string-literal interpolation expression">message</span><span class="token string-literal interpolation punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">			</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">		</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	result</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> response</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">choices</span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token number">0</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">content</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	log</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">    op</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">#Log </span><span class="token operator">&amp;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">		data</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> result</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  parameter</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    token</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> value</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">string</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token comment" style="color:rgb(98, 114, 164)">// +usage=the model name</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    model</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token operator">*</span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"gpt-3.5-turbo"</span><span class="token plain"> </span><span class="token operator">|</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">string</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token comment" style="color:rgb(98, 114, 164)">// +usage=the prompt to use</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    prompt</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">    </span><span class="token operator">*</span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"diagnose"</span><span class="token plain"> </span><span class="token operator">|</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">string</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      lang</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">    </span><span class="token operator">*</span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"English"</span><span class="token plain"> </span><span class="token operator">|</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">string</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      content</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token operator">...</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    timeout</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token operator">*</span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"30s"</span><span class="token plain"> </span><span class="token operator">|</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">string</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></div></div>
<p>That's it! Apply this step type and we can use it in our Workflow like the above.</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela def apply chat-gpt.cue</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="case-2-audit-the-resource">Case 2: Audit the resource<a href="https://kubevela.io/blog/2023/04/06/workflow-chat-gpt/#case-2-audit-the-resource" class="hash-link" aria-label="Direct link to Case 2: Audit the resource" title="Direct link to Case 2: Audit the resource" translate="no">​</a></h3>
<p>Now the ChatGPT is our Kubernetes expert and can diagnose the resource. Can it also give us some security advice for the resource? Definitely! It's just prompt. Let's modify the step type that we wrote in the previous case to add the audit feature. We can add a new prompt type <code>audit</code> and pass the resource to the prompt. You can check out the whole step type in <a href="https://github.com/kubevela/workflow/blob/main/charts/vela-workflow/templates/definitions/chat-gpt.yaml" target="_blank" rel="noopener noreferrer" class="">GitHub</a>.</p>
<p>In the Workflow, we can apply a Deployment with nginx image and pass it to the second step. The second step will use the <code>audit</code> prompt to audit the resource.
<img decoding="async" loading="lazy" alt="The process of auditing the resource in workflow" src="https://kubevela.io/assets/images/img5-55963fcfdeaba6b38726c1d45f16b628.png" title="The process of auditing the resource in workflow" width="1794" height="898" class="img_ev3q">
The complete Workflow is shown below:</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token key atrule">apiVersion</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> core.oam.dev/v1alpha1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> WorkflowRun</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">metadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> chat</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">gpt</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">audit</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">namespace</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> default</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">spec</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">workflowSpec</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">steps</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> apply</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> apply</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">deployment</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token comment" style="color:rgb(98, 114, 164)"># output the resource to the next step</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">outputs</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> resource</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">valueFrom</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> output.value</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">image</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> nginx</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> chat</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">audit</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> chat</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">gpt</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token comment" style="color:rgb(98, 114, 164)"># use the resource as inputs and pass it to prompt.content</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">inputs</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">from</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> resource</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">parameterKey</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> prompt.content</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">token</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">value</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> &lt;your token</span><span class="token punctuation" style="color:rgb(248, 248, 242)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">prompt</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> audit</span><br></span></code></pre></div></div>
<p><img decoding="async" loading="lazy" alt="image.png" src="https://kubevela.io/assets/images/img6-f79cbb45cd73ad7254a13cf3f67b0e57.png" width="1264" height="390" class="img_ev3q"></p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="use-diagnose--audit-in-one-workflow">Use Diagnose &amp; Audit in one Workflow<a href="https://kubevela.io/blog/2023/04/06/workflow-chat-gpt/#use-diagnose--audit-in-one-workflow" class="hash-link" aria-label="Direct link to Use Diagnose &amp; Audit in one Workflow" title="Direct link to Use Diagnose &amp; Audit in one Workflow" translate="no">​</a></h4>
<p>Now that we have the capability to diagnose and audit the resource, we can use them in one Workflow, and use the <code>if</code> condition to control the execution of the steps. For example, if the apply step fails, then diagnose the resource, if it succeeds, audit the resource.</p>
<p><img decoding="async" loading="lazy" alt="Use diagnose &amp;amp; audit in one workflow" src="https://kubevela.io/assets/images/img7-28b2fea116c410c39eb72e521398f74c.png" title="Use diagnose &amp;amp; audit in one workflow" width="2248" height="888" class="img_ev3q"></p>
<p>The complete Workflow is shown below:</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token key atrule">apiVersion</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> core.oam.dev/v1alpha1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> WorkflowRun</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">metadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> chat</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">gpt</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">namespace</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> default</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">spec</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">workflowSpec</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">steps</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> apply</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> apply</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">deployment</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">outputs</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> resource</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">valueFrom</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> output.value</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">image</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> nginx</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token comment" style="color:rgb(98, 114, 164)"># if the apply step fails, then diagnose the resource</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> chat</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">diagnose</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">if</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> status.apply.failed</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> chat</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">gpt</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">inputs</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">from</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> resource</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">parameterKey</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> prompt.content</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">token</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">value</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> &lt;your token</span><span class="token punctuation" style="color:rgb(248, 248, 242)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">prompt</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> diagnose</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token comment" style="color:rgb(98, 114, 164)"># if the apply step succeeds, then audit the resource</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> chat</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">audit</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">if</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> status.apply.succeeded</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> chat</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">gpt</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">inputs</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">from</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> resource</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">parameterKey</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> prompt.content</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">token</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">value</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> &lt;your token</span><span class="token punctuation" style="color:rgb(248, 248, 242)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">prompt</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> audit</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="case-3-use-chatgpt-as-a-quality-gate">Case 3: Use ChatGPT as a quality gate<a href="https://kubevela.io/blog/2023/04/06/workflow-chat-gpt/#case-3-use-chatgpt-as-a-quality-gate" class="hash-link" aria-label="Direct link to Case 3: Use ChatGPT as a quality gate" title="Direct link to Case 3: Use ChatGPT as a quality gate" translate="no">​</a></h3>
<p>If we want to apply the resources to a production environment, can we let ChatGPT rate the quality of the resource first, only if the quality is high enough, then apply the resource to the production environment? Absolutely!</p>
<blockquote>
<p>Note that to make the score evaluated by chat-gpt more convincing, it's better to pass metrics than the resource in this case.</p>
</blockquote>
<p>Let's write our Workflow. KubeVela Workflow has the capability to apply resources to multi clusters. The first step is to apply the Deployment to the test environment. The second step is to use the ChatGPT to rate the quality of the resource. If the quality is high enough, then apply the resource to the production environment.</p>
<p><img decoding="async" loading="lazy" alt="The process of using quality gate in workflow" src="https://kubevela.io/assets/images/img8-db8a862b2d8760a56b3e67ceba834f90.png" title="The process of using quality gate in workflow" width="2196" height="966" class="img_ev3q"></p>
<p>The complete Workflow is shown below:</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token key atrule">apiVersion</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> core.oam.dev/v1alpha1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> WorkflowRun</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">metadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> chat</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">gpt</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">quality</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">gate</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">namespace</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> default</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">spec</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">workflowSpec</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">steps</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token comment" style="color:rgb(98, 114, 164)"># apply the resource to the test environment</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> apply</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> apply</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">deployment</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token comment" style="color:rgb(98, 114, 164)"># output the resource to the next step</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">outputs</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> resource</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">valueFrom</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> output.value</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">image</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> nginx</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">cluster</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> test</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> chat</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">quality</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">check</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token comment" style="color:rgb(98, 114, 164)"># this step will always be executed</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">if</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> always</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> chat</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">gpt</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token comment" style="color:rgb(98, 114, 164)"># get the inputs from resource and pass it to the prompt.content</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">inputs</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">from</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> resource</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">parameterKey</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> prompt.content</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token comment" style="color:rgb(98, 114, 164)"># output the score of ChatGPT and use strconv.Atoi to convert the score string to int</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">outputs</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> chat</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">result</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">valueFrom</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">|</span><span class="token scalar string" style="color:rgb(255, 121, 198)"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token scalar string" style="color:rgb(255, 121, 198)">            import "strconv"</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token scalar string" style="color:rgb(255, 121, 198)">            strconv.Atoi(result)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">token</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">value</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> &lt;your token</span><span class="token punctuation" style="color:rgb(248, 248, 242)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">prompt</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> quality</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">gate</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token comment" style="color:rgb(98, 114, 164)"># if the score is higher than 60, then apply the resource to the production environment</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> apply</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">production</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> apply</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">deployment</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token comment" style="color:rgb(98, 114, 164)"># get the score from chat-result</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">inputs</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">from</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> chat</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">result</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token comment" style="color:rgb(98, 114, 164)"># check if the score is higher than 60</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">if</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> inputs</span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">"chat-result"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">&gt;</span><span class="token plain"> 60</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">image</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> nginx</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">cluster</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> prod</span><br></span></code></pre></div></div>
<p>Apply this Workflow and we can see that if the score is higher than 60, then the resource will be applied to the production environment.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="in-the-end">In the End<a href="https://kubevela.io/blog/2023/04/06/workflow-chat-gpt/#in-the-end" class="hash-link" aria-label="Direct link to In the End" title="Direct link to In the End" translate="no">​</a></h2>
<p>ChatGPT brings imagination to the world of Kubernetes. Diagnose, audit, rate is just the beginning. In the new AI era, the most precious thing is idea. What do you want to do with ChatGPT? Share your insights with us in the <a href="https://github.com/kubevela/kubevela" target="_blank" rel="noopener noreferrer" class="">KubeVela Community</a>.</p>]]></content>
        <author>
            <name>Fog Dong</name>
            <uri>https://github.com/FogDong</uri>
        </author>
        <category label="KubeVela" term="KubeVela"/>
        <category label="CNCF" term="CNCF"/>
        <category label="ChatGPT" term="ChatGPT"/>
        <category label="Workflow" term="Workflow"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Interpreting KubeVela 1.7: Taking Over Your Existing Workloads]]></title>
        <id>https://kubevela.io/blog/2023/03/30/kubevela-1.7/</id>
        <link href="https://kubevela.io/blog/2023/03/30/kubevela-1.7/"/>
        <updated>2023-03-30T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This article interprets the release of KubeVela 1.7.]]></summary>
        <content type="html"><![CDATA[<p>The KubeVela 1.7 version has been officially released for some time, during which KubeVela has been officially promoted to a CNCF incubation project, marking a new milestone. KubeVela 1.7 itself is also a turning point because KubeVela has been focusing on the design of an extensible system from the beginning, and the demand for the core functionality of controllers has gradually converged, freeing up more resources to focus on user experience, ease of use, and performance. In this article, we will focus on highlighting the prominent features of version 1.7, such as workload takeover and performance optimization.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="taking-over-your-existing-workloads">Taking Over Your Existing Workloads<a href="https://kubevela.io/blog/2023/03/30/kubevela-1.7/#taking-over-your-existing-workloads" class="hash-link" aria-label="Direct link to Taking Over Your Existing Workloads" title="Direct link to Taking Over Your Existing Workloads" translate="no">​</a></h2>
<p>Taking over existing workloads has always been a highly demanded requirement within the community, with a clear scenario: existing workloads can be naturally migrated to the OAM standard system and be managed uniformly by KubeVela's application delivery control plane. The workload takeover feature also allows reuse of VelaUX's UI console functions, including a series of operations and maintenance characteristics, workflow steps, and a rich plugin ecosystem. In version 1.7, we officially released this feature. Before diving into the specific operation details, let's first have a basic understanding of its operation mode.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="read-only-and-take-over-policy">"read-only" and "take-over" policy<a href="https://kubevela.io/blog/2023/03/30/kubevela-1.7/#read-only-and-take-over-policy" class="hash-link" aria-label="Direct link to &quot;read-only&quot; and &quot;take-over&quot; policy" title="Direct link to &quot;read-only&quot; and &quot;take-over&quot; policy" translate="no">​</a></h3>
<p>To meet the needs of different usage scenarios, KubeVela provides two modes for unified management. <strong>One is the "read-only" mode, which is suitable for systems that already have a self-built platform internally and still have the main control capability for existing businesses. The new KubeVela-based platform system can only observe these applications in a read-only manner. The other mode is the "take-over" mode, which is suitable for users who want to directly migrate their workloads to the KubeVela system and achieve complete unified management.</strong></p>
<ul>
<li class="">
<p>The "read-only" mode, as the name suggests, does not perform any "write" operations on resources. Workloads managed in read-only mode can be visualized through KubeVela's toolset (such as CLI and VelaUX), which satisfies the need for unified viewing and observability. At the same time, when the managed application generated under read-only mode is deleted, the underlying workload resources will not be reclaimed. If the underlying workload is artificially modified by other controllers, KubeVela can also observe these changes.</p>
</li>
<li class="">
<p>The "take-over" mode means that the underlying workloads will be fully managed by KubeVela, just like other workloads created directly through the KubeVela system. The update, deletion, and other lifecycle of the workloads will be fully controlled by KubeVela's application system. By default, modifications to workloads by other systems will no longer take effect and will be changed back by KubeVela's end-state control loop, unless you add other management policies (such as apply-once).</p>
</li>
</ul>
<p>The method of declaring the take-over mode uses KubeVela's policy system, as shown below:</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token key atrule">apiVersion</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> core.oam.dev/v1beta1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> Application</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">metadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> read</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">only</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">spec</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">components</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> nginx</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> webservice</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">image</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> nginx</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">policies</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> read</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">only</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> read</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">only</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">rules</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">selector</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">              </span><span class="token key atrule">resourceTypes</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">"Deployment"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><br></span></code></pre></div></div>
<p>In the "read-only" policy, we have defined multiple read-only rules. For example, if the read-only selector hits a "Deployment" resource, it means that only the resources related to Deployment are read-only. We can still create and modify resources such as "Ingress" and "Service" using operational features. However, modifying the number of instances of Deployment using the "scaler" operational feature will not take effect.</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token key atrule">apiVersion</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> core.oam.dev/v1beta1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> Application</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">metadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> take</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">over</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">spec</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">components</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> nginx</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">take</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">over</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> k8s</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">objects</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">objects</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">apiVersion</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> apps/v1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> Deployment</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token key atrule">metadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">              </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> nginx</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">traits</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> scaler</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token key atrule">replicas</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token number">3</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">policies</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> take</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">over</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> take</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">over</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">rules</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">selector</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">              </span><span class="token key atrule">resourceTypes</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">"Deployment"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><br></span></code></pre></div></div>
<p>In the "take-over" policy, we also include a series of selectors to ensure that the resources being taken over are controllable. In the example above, without the "take-over" policy, the operation would fail if there is already a Deployment resource named "nginx" in the system, because the resource already exists. On one hand, the take-over policy ensures that already existing resources can be included in management when creating applications; on the other hand, it also allows the reuse of previously existing workload configurations, and only modifications to the number of instances in operational features such as "scaler" will be "patched" to the original configuration as part of the new configuration.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="use-command-line-to-take-over-workloads">Use command line to take over workloads<a href="https://kubevela.io/blog/2023/03/30/kubevela-1.7/#use-command-line-to-take-over-workloads" class="hash-link" aria-label="Direct link to Use command line to take over workloads" title="Direct link to Use command line to take over workloads" translate="no">​</a></h3>
<p>After learning about the <code>take-over</code> mode, you might wonder if there is an easy way to take over workloads with a single command. Yes, KubeVela's command line provides such a convenient way to take over workloads such as common K8s resources and "Helm". It is very easy to use. Specifically, the vela CLI automatically recognizes the resources in the system and assembles them into an application for take-over. Our core principle in designing this feature is that <strong>"taking over resources cannot trigger a restart of the underlying workloads"</strong>.</p>
<p>As shown below, by default, using <code>vela adopt</code> will manage the resources in "read-only" mode. Simply specify the type, namespace, and name of the native resources you want to take over, and an Application object for takeover will be automatically generated. The generated application spec is strictly consistent with the actual fields in the cluster.</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">$ vela adopt deployment/default/example configmap/default/example</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">apiVersion: core.oam.dev/v1beta1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">kind: Application</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">metadata:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  labels:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    app.oam.dev/adopt: native</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  name: example</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  namespace: default</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">spec:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  components:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  - name: example.Deployment.example</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    properties:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      objects:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      - apiVersion: apps/v1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        kind: Deployment</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        metadata:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          name: example</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          namespace: default</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        spec:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          replicas: 1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          selector:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            matchLabels:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">              app: example</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          template:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            metadata:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">              labels:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                app: example</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            spec:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">              containers:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">              - image: nginx</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                imagePullPolicy: Always</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                name: nginx</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">              restartPolicy: Always</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          ...</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    type: k8s-objects</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  - name: example.config</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    properties:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      objects:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      - apiVersion: v1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        kind: ConfigMap</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        metadata:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          name: example</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          namespace: default</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    type: k8s-objects</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  policies:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  - name: read-only</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    properties:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      rules:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      - selector:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          componentNames:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          - example.Deployment.example</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          - example.config</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    type: read-only</span><br></span></code></pre></div></div>
<p>The currently supported default takeover types and their corresponding resource API names are as follows:</p>
<ul>
<li class="">crd: ["CustomResourceDefinition"]</li>
<li class="">ns: ["Namespace"]</li>
<li class="">workload: ["Deployment", "StatefulSet", "DaemonSet", "CloneSet"]</li>
<li class="">service: ["Service", "Ingress", "HTTPRoute"]</li>
<li class="">config: ["ConfigMap", "Secret"]</li>
<li class="">sa: ["ServiceAccount", "Role", "RoleBinding", "ClusterRole", "ClusterRoleBinding"]</li>
<li class="">operator: ["MutatingWebhookConfiguration", "ValidatingWebhookConfiguration", "APIService"]</li>
<li class="">storage: ["PersistentVolume", "PersistentVolumeClaim"]</li>
</ul>
<p>If you want to change the application to takeover mode and deploy it directly to the cluster, just add a few parameters:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela adopt deployment/default/example --mode take-over --apply</span><br></span></code></pre></div></div>
<p>In addition to native resources, the vela command line also supports taking over workloads created by Helm applications by default.</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela adopt mysql --type helm --mode take-over --apply --recycle -n default</span><br></span></code></pre></div></div>
<p>The above command will manage the "mysql" Helm release in the "default" namespace through "take-over" mode. Specifying <code>--recycle</code> will clean up the original Helm release metadata after a successful deployment.</p>
<p>Once the workloads have been taken over, the corresponding KubeVela Applications have been generated, and the related operations have been integrated with the KubeVela system. You can see the taken-over applications on the VelaUX interface, and also view and operate the applications through other vela command line functions.</p>
<p>You can also use a command to take over all the workloads in your namespace in batches. Based on KubeVela's resource topology capabilities, the system will automatically recognize the associated resources and form a complete application. For custom resources such as CRDs, KubeVela also supports custom rules for association relationships.</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela adopt --all --apply</span><br></span></code></pre></div></div>
<p>This command will automatically recognize the resources and their association relationships in the current namespace based on the built-in resource topology rules, and take over the applications accordingly. Taking a Deployment as an example, the automatically taken over application looks like the following, which not only takes over the main workload Deployment but also its corresponding resources, including ConfigMap, Service, and Ingress.</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token key atrule">apiVersion</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> core.oam.dev/v1beta1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> Application</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">metadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> test2</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">namespace</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> default</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">spec</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">components</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> test2.Deployment.test2</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">objects</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">apiVersion</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> apps/v1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> Deployment</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">metadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> test2</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">namespace</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> default</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">spec</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(248, 248, 242)">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> k8s</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">objects</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> test2.Service.test2</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">objects</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">apiVersion</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> v1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> Service</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">metadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> test2</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">namespace</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> default</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">spec</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(248, 248, 242)">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> k8s</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">objects</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> test2.Ingress.test2</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">objects</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">apiVersion</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> networking.k8s.io/v1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> Ingress</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">metadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> test2</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">namespace</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> default</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">spec</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(248, 248, 242)">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> k8s</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">objects</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> test2.config</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">objects</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">apiVersion</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> v1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> ConfigMap</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">metadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> record</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">event</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">namespace</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> default</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> k8s</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">objects</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">policies</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> read</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">only</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">rules</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">selector</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">componentNames</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> test2.Deployment.test2</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> test2.Service.test2</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> test2.Ingress.test2</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> test2.config</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> read</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">only</span><br></span></code></pre></div></div>
<p>The demonstration result is shown below:
<img decoding="async" loading="lazy" src="https://kubevela.io/images/1.8/adopt-all.gif" alt="adoption.gif" class="img_ev3q"></p>
<p>If you want to use custom resource topology relationships to take over custom resources, you can use the following command:</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela adopt &lt;your</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">crd</span><span class="token punctuation" style="color:rgb(248, 248, 242)">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">all </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">resource</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">topology</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">rule=&lt;your</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">rule</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">file.cue</span><span class="token punctuation" style="color:rgb(248, 248, 242)">&gt;</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="flexible-definition-of-takeover-rules">Flexible Definition of Takeover Rules<a href="https://kubevela.io/blog/2023/03/30/kubevela-1.7/#flexible-definition-of-takeover-rules" class="hash-link" aria-label="Direct link to Flexible Definition of Takeover Rules" title="Direct link to Flexible Definition of Takeover Rules" translate="no">​</a></h3>
<p>Given KubeVela's highly extensible design principles, the workloads and takeover methods faced by resource takeover are also different. Therefore, we have also designed a fully extensible and programmable way to take over workloads. In fact, the one-click takeover capability of the command line is also based on KubeVela's extensible takeover rules as a <a href="https://github.com/kubevela/kubevela/blob/master/references/cli/adopt-templates/default.cue" target="_blank" rel="noopener noreferrer" class="">special case</a>. The core idea is to define a configuration transformation rule through CUE, and then specify the transformation rule when executing the <code>vela adopt</code> command, as shown below.</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela adopt deployment/my-workload --adopt-template=my-adopt-rule.cue</span><br></span></code></pre></div></div>
<p>This mode is only suitable for advanced users, and we will not go into too much detail here. If you want to learn more details, you can refer to the <a href="https://kubevela.net/zh/docs/end-user/policies/resource-adoption" target="_blank" rel="noopener noreferrer" class="">official documentation</a> on workload takeover.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="significant-performance-optimization">Significant Performance Optimization<a href="https://kubevela.io/blog/2023/03/30/kubevela-1.7/#significant-performance-optimization" class="hash-link" aria-label="Direct link to Significant Performance Optimization" title="Direct link to Significant Performance Optimization" translate="no">​</a></h2>
<p>Performance optimization is also a major highlight of this version. Based on the practical experience of different users in the community, <strong>we have improved the overall performance of the controller, the capacity of a single application, and the overall application processing throughput by 5 to 10 times</strong> without changing the default resource quotas. This also includes some changes to default configurations, with parameter trimming for some niche scenarios that affect performance.</p>
<p>In terms of single application capacity, because KubeVela applications may contain a large number of actual Kubernetes APIs, this often leads to the ResourceTracker behind the application that records the actual resource status and the ApplicationRevision object that records version information exceeding the 2MB limit of a single Kubernetes object. In version 1.7, we have added zstd compression functionality and enabled it by default, which directly compresses the size of resources by <a href="https://github.com/kubevela/kubevela/pull/5090" target="_blank" rel="noopener noreferrer" class="">nearly 10 times</a>. This also means that <strong>the resource capacity that a single KubeVela Application can support has increased by 10 times</strong>.</p>
<p>In addition, for some scenarios such as recording application and component versions, these version records themselves will increase proportionally with the number of applications, such as default recording of 10 application versions, which will increase by a factor of ten with the number of applications. Due to the list-watch mechanism of the controller itself, these additional objects will occupy controller memory, leading to a significant increase in memory usage. Many users (such as GitOps users) may have their own version management system. In order to avoid waste of memory, we have changed the default upper limit of application version records from 10 to 2. For component versions, which are relatively niche, we have disabled them by default. <strong>This reduces the controller's overall memory consumption to one-third of the original</strong>.</p>
<p>In addition, some parameter adjustments have been made, including reducing the number of historical versions recorded in the Definition from 20 to 2, and increasing the default Kubernetes API interaction limit QPS from 100 to 200, among others. In future versions, we will continue to optimize the performance of the controller.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="usability-improvement">Usability Improvement<a href="https://kubevela.io/blog/2023/03/30/kubevela-1.7/#usability-improvement" class="hash-link" aria-label="Direct link to Usability Improvement" title="Direct link to Usability Improvement" translate="no">​</a></h2>
<p>In addition to the core feature updates and performance improvements, this release also includes enhancements to the usability of many features.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="client-side-multi-environment-resource-rendering">Client-side multi-environment resource rendering<a href="https://kubevela.io/blog/2023/03/30/kubevela-1.7/#client-side-multi-environment-resource-rendering" class="hash-link" aria-label="Direct link to Client-side multi-environment resource rendering" title="Direct link to Client-side multi-environment resource rendering" translate="no">​</a></h3>
<p>"Dry run" is a popular concept in Kubernetes, which refers to the practice of running resources in a dry, non-destructive mode before they are actually applied to the cluster, to check if the configurations are valid. KubeVela also provides this feature, which not only checks if resources can be run, but also translates the abstract applications of OAM into the Kubernetes native API, allowing the client to convert from application abstraction to actual resources. The new feature added in version 1.7 is to specify different files for dry run, generating different actual resources.</p>
<p>For example, we can write different policy and workflow files for different environments, such as "test-policy.yaml" and "prod-policy.yaml". In this way, the same application can be specified with different policies and workflows in the client, generating different underlying resources, such as:</p>
<ul>
<li class="">Running in test environment</li>
</ul>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela dry-run  -f app.yaml -f test-policy.yaml -f test-workflow.yaml</span><br></span></code></pre></div></div>
<ul>
<li class="">Running in production environment</li>
</ul>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela dry-run  -f app.yaml -f prod-policy.yaml -f prod-workflow.yaml</span><br></span></code></pre></div></div>
<p>Here is the content of <code>app.yaml</code>, which specifies an external workflow to be referenced:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain"># app.yaml</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">apiVersion: core.oam.dev/v1beta1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">kind: Application</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">metadata:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  name: first-vela-app</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">spec:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  components:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    - name: express-server</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      type: webservice</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      properties:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        image: oamdev/hello-world</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        ports:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">         - port: 8000</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">           expose: true</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      traits:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        - type: scaler</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          properties:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            replicas: 1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  workflow:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    ref: deploy-demo</span><br></span></code></pre></div></div>
<p>And the content of <code>prod-policy.yaml</code> and <code>prod-workflow.yaml</code> are as follows:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">apiVersion: core.oam.dev/v1alpha1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">kind: Policy</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">metadata:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  name: env-prod</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">type: topology</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">properties:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  clusters: ["local"]</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  namespace: "prod"</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">---</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">apiVersion: core.oam.dev/v1alpha1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">kind: Policy</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">metadata:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  name: ha</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">type: override</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">properties:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  components:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  - type: webservice</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    traits:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    - type: scaler</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      properties:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        replicas: 2</span><br></span></code></pre></div></div>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">apiVersion: core.oam.dev/v1alpha1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">kind: Workflow</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">metadata:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  name: deploy-demo</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  namespace: default</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">steps:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  - type: deploy</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    name: deploy-prod</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    properties:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      policies: ["ha", "env-prod"]</span><br></span></code></pre></div></div>
<p>The corresponding YAML files for the test environment can be modified in the same way by changing the parameters. This feature is particularly useful for users who use KubeVela as a client abstraction tool and combine it with tools such as Argo to synchronize resources.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="enhanced-application-deletion-feature">Enhanced Application Deletion Feature<a href="https://kubevela.io/blog/2023/03/30/kubevela-1.7/#enhanced-application-deletion-feature" class="hash-link" aria-label="Direct link to Enhanced Application Deletion Feature" title="Direct link to Enhanced Application Deletion Feature" translate="no">​</a></h3>
<p>In many special scenarios, deleting applications has always been a painful experience. In version 1.7, we have added some convenient ways to support smooth application deletion for various special cases.</p>
<ul>
<li class=""><strong>Deleting certain workloads in case of cluster disconnection</strong>: We provide an interactive method to delete resources, which allows users to select the underlying workloads by viewing the cluster name, namespace, and resource type, to remove resources involved in special scenarios such as cluster disconnection.</li>
</ul>
<p><img decoding="async" loading="lazy" alt="vela-delete.gif" src="https://kubevela.io/assets/images/vela-delete-960f1d5af5aea945792271d50810dfad.gif" width="600" height="327" class="img_ev3q"></p>
<ul>
<li class="">
<p><strong>Retain underlying resources when deleting an application</strong>: If you only want to delete the metadata of the application while keeping the underlying workload and configuration, you can use the <code>--orphan</code> flag to retain the underlying resources when deleting the application.</p>
</li>
<li class="">
<p><strong>Deleting application when controller is uninstalled</strong>: When you have uninstalled the KubeVela controller but found some remaining applications that were not cleaned up, you can use <code>--force</code> flag to delete these applications.</p>
</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="custom-output-after-addon-installation">Custom output after addon installation<a href="https://kubevela.io/blog/2023/03/30/kubevela-1.7/#custom-output-after-addon-installation" class="hash-link" aria-label="Direct link to Custom output after addon installation" title="Direct link to Custom output after addon installation" translate="no">​</a></h3>
<p>For the KubeVela plugin system, we have added a <code>NOTES.cue</code> file that allows plugin makers to dynamically output installation completion prompts. For example, for the Backstage plugin, the <code>NOTES.cue</code> file is as follows:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">info: string</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">if !parameter.pluginOnly {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	info: """</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">		By default, the backstage app is strictly serving in the domain `127.0.0.1:7007`, check it by:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">		            </span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">		    vela port-forward addon-backstage -n vela-system</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">		</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">		You can build your own backstage app if you want to use it in other domains. </span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">		"""</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">if parameter.pluginOnly {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	info: "You can use the endpoint of 'backstage-plugin-vela' in your own backstage app by configuring the 'vela.host', refer to example https://github.com/wonderflow/vela-backstage-demo."</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">notes: (info)</span><br></span></code></pre></div></div>
<p>This plugin's output will be displayed with different content based on the parameters used by the user during plugin installation.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="enhanced-workflow-capabilities">Enhanced Workflow Capabilities<a href="https://kubevela.io/blog/2023/03/30/kubevela-1.7/#enhanced-workflow-capabilities" class="hash-link" aria-label="Direct link to Enhanced Workflow Capabilities" title="Direct link to Enhanced Workflow Capabilities" translate="no">​</a></h3>
<p>In version 1.7, we have enhanced the workflow capabilities with more granular options:</p>
<ul>
<li class="">Support specifying a failed step for retry</li>
</ul>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela workflow restart &lt;app-name&gt; --step=&lt;step-name&gt;</span><br></span></code></pre></div></div>
<ul>
<li class="">The step name of a workflow can be left blank, and it will be generated automatically by the webhook.</li>
<li class="">The parameter passing in workflows now supports overriding existing parameters.</li>
</ul>
<p>In addition, we have added <a href="https://kubevela.net/docs/end-user/workflow/built-in-workflow-defs" target="_blank" rel="noopener noreferrer" class="">a series of new workflow steps</a> in this version, including the typical <code>built-push-image</code> step that allows users to build an image and push it to a registry within the workflow. During the execution of the workflow steps, users can check the logs of a specific step using the <code>vela workflow logs &lt;name&gt; --step &lt;step-name&gt;</code> command. The full list of built-in workflow steps can be found in the official documentation.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="enhanced-velaux-capabilities">Enhanced VelaUX Capabilities<a href="https://kubevela.io/blog/2023/03/30/kubevela-1.7/#enhanced-velaux-capabilities" class="hash-link" aria-label="Direct link to Enhanced VelaUX Capabilities" title="Direct link to Enhanced VelaUX Capabilities" translate="no">​</a></h3>
<p>The VelaUX console has also been enhanced in version 1.7, including:</p>
<ul>
<li class="">Enhanced application workflow orchestration capabilities, supporting full workflow capabilities including sub-steps, input/output, timeouts, conditional statements, step dependencies, etc. Application workflow status viewing is also more comprehensive, with historical workflow records, step details, step logs, and input/output information available for query.</li>
<li class="">Support for application version regression, allowing users to view the differences between multiple versions of an application and select a specific version to roll back to.</li>
<li class="">Support for multi-tenancy, with stricter limits on multi-tenant permissions aligned with the Kubernetes RBAC model.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="whats-next">What's Next<a href="https://kubevela.io/blog/2023/03/30/kubevela-1.7/#whats-next" class="hash-link" aria-label="Direct link to What's Next" title="Direct link to What's Next" translate="no">​</a></h2>
<p>Recently, the official version of KubeVela 1.8 is also in full swing and is expected to meet you at the end of March. We will further enhance the following aspects:</p>
<p>Enhance the scalability and stability of the KubeVela core controller, provide a sharding solution for controller horizontal scaling, optimize the controller performance and mapping for 10,000-level application scale in multi-cluster scenarios, and provide a new performance evaluation for the community.
VelaUX supports out-of-the-box gray release capabilities, and interfaces with observability plugins for interactive release processes. At the same time, VelaUX forms an extensible framework system, providing configuration capabilities for customizing UI and supporting business custom extensions and interfaces.
Enhance the GitOps workflow capabilities to support the complete VelaUX experience for applications synchronized with Git repositories.
If you want to learn more about our plans, become a contributor, or partner with us, you can contact us through community communication (<a href="https://github.com/kubevela/community" target="_blank" rel="noopener noreferrer" class="">https://github.com/kubevela/community</a>), and we look forward to your participation!</p>]]></content>
        <author>
            <name>Jianbo Sun</name>
            <uri>https://github.com/kubevela/KubeVela</uri>
        </author>
        <category label="KubeVela" term="KubeVela"/>
        <category label="release-note" term="release-note"/>
        <category label="Kubernetes" term="Kubernetes"/>
        <category label="DevOps" term="DevOps"/>
        <category label="CNCF" term="CNCF"/>
        <category label="CI/CD" term="CI/CD"/>
        <category label="Application delivery" term="Application delivery"/>
        <category label="Adopt workloads" term="Adopt workloads"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[KubeVela brings software delivery control plane capabilities to CNCF Incubator]]></title>
        <id>https://kubevela.io/blog/2023/03/06/incubation/</id>
        <link href="https://kubevela.io/blog/2023/03/06/incubation/"/>
        <updated>2023-03-06T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This article introduces how KubeVela brings software delivery control plane capabilities to CNCF Incubator]]></summary>
        <content type="html"><![CDATA[<blockquote>
<p>Originally post in <a href="https://www.cncf.io/blog/2023/02/27/kubevela-brings-software-delivery-control-plane-capabilities-to-cncf-incubator/" target="_blank" rel="noopener noreferrer" class="">CNCF</a>.</p>
</blockquote>
<p>The CNCF Technical Oversight Committee (TOC) has voted to accept KubeVela as a CNCF incubating project.</p>
<p><a href="https://kubevela.io/" target="_blank" rel="noopener noreferrer" class="">KubeVela</a> is an application delivery engine built with the Kubernetes control plane that makes deploying and operating applications across hybrid and multi-cloud environments easier, faster, and more reliable. KubeVela can orchestrate, deploy, and operate application components and cloud resources with a workflow-based application delivery model. The application delivery abstraction of KubeVela is powered by the <a href="https://oam.dev/" target="_blank" rel="noopener noreferrer" class="">Open Application Model (OAM)</a>.</p>
<p><img decoding="async" loading="lazy" alt="image.png" src="https://kubevela.io/assets/images/what-is-kubevela-0c2584fd19c8a603b9dea994cfdadcb2.png" width="1716" height="896" class="img_ev3q"></p>
<p>The KubeVela project evolved from <a href="https://github.com/crossplane/oam-kubernetes-runtime" target="_blank" rel="noopener noreferrer" class="">oam-kubernetes-runtime</a> and developed with <a href="https://github.com/kubevela/community/blob/main/OWNERS.md#bootstrap-contributors" target="_blank" rel="noopener noreferrer" class="">bootstrap contributions</a> from more than eight different organizations, including Alibaba Cloud, Microsoft, Upbound and more. It was publicly announced as an open source project in November 2020, released as v1.0 in April 2021, and accepted as a CNCF sandbox project in June 2021. The project has more than <a href="https://kubevela.devstats.cncf.io/d/22/prs-authors-table?orgId=1" target="_blank" rel="noopener noreferrer" class="">260 contributors</a> and committers across multiple continents from organizations like Didi, JD.com, JiHu GitLab, SHEIN, and more.</p>
<p>“KubeVela pioneered a path for delivering applications across multi-cloud/multi-cluster environments with unified yet extensible abstractions,” said Lei Zhang, CNCF TOC sponsor. “This innovation unlocked the next-generation software delivery experience and filled the ‘last mile’ gap in existing practices which focus on the ‘deploy’ stage rather than ‘orchestrating’. We are excited to welcome more app-centric tools/platforms in the CNCF community and look forward to watching the adoption of KubeVela grow to a new level in the fast-growing application delivery ecosystem.”</p>
<p>KubeVela is used in production today by multiple companies across all major public clouds and on-premises deployments. Most users are adopting KubeVela as their internal “PaaS”, as part of their CI/CD pipeline, or as an extensible DevOps kernel for building their own IDP. Public <a href="https://github.com/kubevela/community/blob/main/ADOPTERS.md" target="_blank" rel="noopener noreferrer" class="">adopters</a> include Alibaba, which uses KubeVela as the core to deliver and manage applications across hybrid environments; Bytedance, which uses KubeVela and Crossplane to provide advanced Gaming PaaS abilities; China Merchants Bank, which uses KubeVela to build a hybrid cloud application platform to unify the whole process from build, ship and run; and many more.</p>
<p>“We’ve found capabilities such as gateway, security, and observability are being standardized with the emergence of corresponding open source tools and cloud services,” said Fang SITU, leader of aPaaS and Serverless team at Alibaba Cloud. “These capabilities can be integrated so that developers can self-serve, easily configure, automatically trigger, and get faster feedback, thereby greatly improving the application development efficiency. KubeVela is very suitable for the integration and customization of this kind of application delivery process, and it is the best practice of Platform Engineering.”</p>
<p>“KubeVela enables China Merchants Bank to quickly establish a large-scale unified OAM cloud native application management platform, reducing the complexity of cloud for FinTech and accelerating the standardized development and delivery of modern applications,” said Jiahang Xu, Senior Architect at China Merchants Bank and KubeVela maintainer. “KubeVela provides an application model and programmable CRD, workflow orchestration application delivery, observability, and configuration capabilities. KubeVela empowers cloud native applications along with the CNCF ecosystem.”</p>
<p><img decoding="async" loading="lazy" alt="image.png" src="https://kubevela.io/assets/images/kubevela-comps-df59a84c33deee96d5a245f7c369a83e.png" width="1600" height="798" class="img_ev3q"></p>
<p><strong>Main Components:</strong></p>
<ul>
<li class=""><a href="https://github.com/kubevela/kubevela" target="_blank" rel="noopener noreferrer" class="">Vela Core</a> is the main component of KubeVela, also known as the KubeVela Control Plane. It provides operators and webhooks for rendering, orchestrating and delivering OAM applications.</li>
<li class="">The <a href="https://github.com/kubevela/workflow" target="_blank" rel="noopener noreferrer" class="">Vela Workflow</a> engine translates CUE-based steps and executes them. It’s a common library that can work as a standalone engine or run inside a KubeVela application.</li>
<li class=""><strong>KubeVela CLI</strong> provides various commands that help you to operate applications, such as managing definitions, viewing resources, restarting workflow, and rolling versions.</li>
<li class=""><a href="https://github.com/kubevela/velaux" target="_blank" rel="noopener noreferrer" class="">VelaUX</a> is the Web UI for KubeVela. It incorporates business logic into fundamental APIs and provides out-of-box user experiences for non-k8s-expert users.</li>
<li class="">The <a href="https://github.com/kubevela/terraform-controller" target="_blank" rel="noopener noreferrer" class="">Terraform Controller</a> in KubeVela allows users to use Terraform to manage cloud resources through Kubernetes Custom Resources.</li>
<li class="">The <a href="https://github.com/oam-dev/cluster-gateway" target="_blank" rel="noopener noreferrer" class="">Cluster Gateway</a> provides a unified multi-cluster access interface.</li>
<li class="">KubeVela also has a growing <a href="https://github.com/kubevela/catalog" target="_blank" rel="noopener noreferrer" class="">catalog</a> with more than 50 community add-ons for integrations, including ArgoCD, FluxCD, Backstage, OpenKruise, Dapr, Crossplane, Terraform, OpenYurt and more.</li>
</ul>
<p><strong>Notable Milestones:</strong></p>
<ul>
<li class="">&gt;4.7k GitHub Stars</li>
<li class="">&gt;3.5k pull requests</li>
<li class="">&gt;1.6k issues</li>
<li class="">&gt;290 contributors</li>
<li class="">&gt;150 Releases</li>
</ul>
<p>Since joining the CNCF Sandbox, KubeVela has released seven minor versions to v1.7 and added five new components, including standalone workflow, VelaUX, ClusterGateway, VelaD, and Vela Prism. The number of contributors has tripled from 90+ to 290+, GitHub stars have doubled from 1900+ to 4700+, and contributing organizations have tripled from 20+ to 70+.</p>
<p>“KubeVela improved the developer experience when it comes to complex multi-cloud environments with their modern open source software delivery control plane,” said Chris Aniszczyk, CNCF CTO. “We look forward to supporting the community in its growth and maturity towards a graduated project.”</p>
<p>Looking forward, the community plans to improve the user experience for cloud resource provisioning and consumption with delivery workflow, enhance the security for the whole CI/CD delivery process in hybrid/multi-cluster scenarios, support the KubeVela Dynamic API that allows users to make integration with third-party APIs easily, and more. Visit the <a href="https://kubevela.io/docs/roadmap/" target="_blank" rel="noopener noreferrer" class="">roadmap</a> to learn more.</p>
<iframe width="720" height="480" src="https://www.youtube.com/embed/p6rB3qQ2zn4" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"></iframe>
<p>“We’re humbled and grateful for the trust and support from users and contributors,” said Jianbo Sun, Staff Engineer at Alibaba Cloud and KubeVela maintainer. “KubeVela’s highly extensible design is very suitable for the diverse user scenarios of the community, bringing us a powerful engine to the ecosystem for application delivery. Thanks to the support and endorsement from CNCF, I believe that reaching incubation status is an important milestone for the project. The KubeVela maintainers look forward to collaborating with CNCF in our goals to make deploying and operating applications across today’s hybrid environments easier, faster and more reliable.”</p>
<p>“Thanks to Kubevela, the way we deploy and manage applications in Kubernetes has now become more accessible,” Daniel Higuero, CTO at Napptive and KubeVela maintainer. “The use of Application and Workflow as top-level entities greatly simplifies common processes on top of Kubernetes. The strength of the approach lies in its ability to simplify basic use cases while enabling complex ones with multi-tenant and multi-cluster support. This is combined with an inherently extensible system which supports community add-ons, allowing it to integrate with other tools and add custom definitions to tailor the experience to your use case.”</p>
<p>“The CNCF community has incubated a large number of cloud native operation and atomic management capabilities,” said  QingGuo Zeng, Technical Expert at Alibaba Cloud and KubeVela maintainer. “We hope to integrate various capabilities through a unified, application-centric concept and help more and more platform developers easily implement standardized applications in enterprises. KubeVela is growing into a powerful helper for enterprises to practice Platform Engineering.”</p>
<p>“KubeVela aims to provide convenience and advancements of the rich cloud native infrastructures to various industries,” said Da Yin, Senior Engineer at Alibaba Cloud and KubeVela maintainer. “To meet the modern application delivery demands, KubeVela is always exploring extensible and flexible architecture and adding pioneering ideas, including multi-cluster delivery, programmable workflow, and automated observability. KubeVela also continuously cares for the security and stability of the control plane, which builds up production confidence for community adopters. We expect the openness of KubeVela could make it a frontier explorer in the cloud native era.”</p>
<p>As a CNCF-hosted project, KubeVela is part of a neutral foundation aligned with its technical interests and the larger Linux Foundation, which provides governance, marketing support, and community outreach. The project joins 35 other <a href="https://www.cncf.io/projects/" target="_blank" rel="noopener noreferrer" class="">incubating technologies</a>, including Backstage, Cilium, Istio, Knative, OpenTelemetry, and more. For more information on maturity requirements for each level, please visit the <a href="https://github.com/cncf/toc/blob/main/process/graduation_criteria.md" target="_blank" rel="noopener noreferrer" class="">CNCF Graduation Criteria</a>.</p>]]></content>
        <author>
            <name>CNCF</name>
            <uri>https://www.cncf.io/blog/2023/02/27/kubevela-brings-software-delivery-control-plane-capabilities-to-cncf-incubator/</uri>
        </author>
        <category label="KubeVela" term="KubeVela"/>
        <category label="CNCF" term="CNCF"/>
        <category label="Incubation" term="Incubation"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[How Does an Open-Source Workflow Engine Support an Enterprise-Level Serverless Architecture?]]></title>
        <id>https://kubevela.io/blog/2023/01/18/workflow-sae/</id>
        <link href="https://kubevela.io/blog/2023/01/18/workflow-sae/"/>
        <updated>2023-01-18T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This article will focus on KubeVela Workflow and show its enterprise use cases in serverless scenario]]></summary>
        <content type="html"><![CDATA[<p><a href="https://www.alibabacloud.com/product/severless-application-engine" target="_blank" rel="noopener noreferrer" class="">Serverless Application Engine (SAE)</a> is a Kubernetes-based cloud product that combines the Serverless architecture and the microservice model. As an iterative cloud product, it has encountered many challenges in the process of rapid development. <strong>How can we solve these challenges in the booming cloud-native era and perform reliable and fast upgrades for architecture?</strong> The SAE team and the KubeVela community worked closely to address these challenges and came up with a replicable open-source solution, KubeVela Workflow.</p>
<p>This article describes how to use KubeVela Workflow to upgrade the architecture of SAE and interprets multiple practice scenarios.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="challenges-in-the-serverless-era">Challenges in the Serverless Era<a href="https://kubevela.io/blog/2023/01/18/workflow-sae/#challenges-in-the-serverless-era" class="hash-link" aria-label="Direct link to Challenges in the Serverless Era" title="Direct link to Challenges in the Serverless Era" translate="no">​</a></h2>
<p>SAE is an application hosting platform for business application architecture and microservices. It is a Kubernetes-based cloud product that combines the Serverless architecture and the microservice model.</p>
<p><img decoding="async" loading="lazy" alt="image.png" src="https://kubevela.io/assets/images/wf-sae-1-6b1f1c1ca32f18cea997eb0a2e776deb.png" width="1080" height="290" class="img_ev3q"></p>
<p>As shown in the preceding architecture diagram, SAE users can host multiple types of applications on SAE. At the underlying layer of SAE, the Java business layer processes the relevant business logic and interacts with Kubernetes resources. At the bottom, it relies on highly available, O&amp;M-free, and pay-as-you-go elastic resource pools.</p>
<p>In this architecture, SAE mainly relies on its Java business layer to provide users with capabilities. This architecture helps users easily deploy applications. Still, at the same time, it brings some challenges as well.</p>
<p>With the continuous development of Serverless, SAE has encountered three major challenges:</p>
<ol>
<li class="">Engineers in SAE have some complex and non-standardized operations. <strong>How can we automate these complex operations to reduce development consumption?</strong></li>
<li class="">With the development of business, the application-delivering capability of SAE is favored by a large number of users. The growth of users also brings efficiency challenges.** How can we optimize the existing delivery capability and improve efficiency in high concurrency?**</li>
<li class="">As Serverless architecture continues to be implemented in enterprises, numerous of cloud vendors are making their product systems serverless. <strong>In such a wave, how can SAE quickly connect with internal Serverless capabilities and reduce development costs while launching new features?</strong></li>
</ol>
<p>The preceding three challenges show that SAE needs some kind of orchestration engine to upgrade the delivery process, integrate with internal capabilities, and automate operations.</p>
<p>So, what does this orchestration engine need to meet to solve these challenges?</p>
<ol>
<li class=""><strong>High Scalability:</strong> The steps in the process need to be highly scalable for this orchestration engine. Only in this way can the originally non-standardized and complex operations be standardized with the steps. In the meanwhile, the steps can combine with the process control capability of the orchestration engine, thus reducing the consumption of development resources.</li>
<li class=""><strong>Lightweight and Efficient:</strong> This orchestration engine must be efficient and production-ready, so as to meet the high concurrency requirements of SAE in large-scale user scenarios.</li>
<li class=""><strong>Strong Integration and Process Control Capabilities:</strong> This orchestration engine needs to be able to quickly integrate with the atomic functions in the company. If the glue code that connects upstream and downstream capabilities can be transformed into the process in the orchestration engine, development costs can be reduced.</li>
</ol>
<p>Based on these challenges and considerations, the SAE team and the KubeVela community have conducted in-depth cooperation and launched the <a href="https://github.com/kubevela/workflow" target="_blank" rel="noopener noreferrer" class="">KubeVela Workflow</a> project as an orchestration engine.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="why-use-kubevela-workflow">Why Use Kubevela Workflow?<a href="https://kubevela.io/blog/2023/01/18/workflow-sae/#why-use-kubevela-workflow" class="hash-link" aria-label="Direct link to Why Use Kubevela Workflow?" title="Direct link to Why Use Kubevela Workflow?" translate="no">​</a></h2>
<p>Thanks to the booming ecological of cloud-native, there are already many mature workflow projects in the community (such as Tekton, Argo, etc.). There are also some orchestration engines within Alibaba Cloud. So, <em>why <strong>reinvent the wheel</strong> instead of using existing technology?</em></p>
<p>This is because KubeVela Workflow has a fundamental difference in design. <strong>The steps in the workflow are designed for the cloud-native IaC system and support abstract encapsulation and reuse, which means that you can use atomic capabilities like a function call in every step, instead of just creating pods or containers.</strong></p>
<p><img decoding="async" loading="lazy" alt="image.png" src="https://kubevela.io/assets/images/wf-sae-2-c805a7d738de937e3dbeeaaa4f053c3e.png" width="1500" height="756" class="img_ev3q"></p>
<p>In KubeVela Workflow, each step has a step type, and each step type corresponds to the resource callend <code>WorkflowStepDefinition</code>. You can use the <a href="https://github.com/cue-lang/cue" target="_blank" rel="noopener noreferrer" class="">CUE language</a> (an IaC language, which is a superset of JSON) to write this step definition or directly use the step type defined in the community.</p>
<p>You can simply regard a <code>WorkflowStepDefinition</code> as a function declaration. Each time a new step type is defined, a new function is defined. The function requires some input parameters, and the step definition is the same. In the step definition, you can define the input parameters required for this step type in the <code>parameter</code> field. When the workflow is running, the workflow controller executes the CUE code in the corresponding step definition using the actual parameter values input by the user, just as it executes your custom function.</p>
<p>With such a layer of abstraction of the steps, it adds huge possibilities to the steps:</p>
<ul>
<li class="">If you want to customize the step type (just like writing a new function), you can import the official code packages in the step definition, thus introducing other atomic capabilities into the step, including HTTP requests, CRUD resources in multiple clusters, conditional waiting, etc. With such a programmable step type, you can easily integrate with any system. For example, in the SAE scenario, the step definition is integrate with other internal atomic capabilities (such as MSE, ACR, ALB, SLS, etc.). Then, the workflow orchestration capability is used to control the process.</li>
</ul>
<p><img decoding="async" loading="lazy" alt="image.png" src="https://kubevela.io/assets/images/wf-sae-3-75762ab79b86c361d236c1c7d4197dd9.png" width="1288" height="410" class="img_ev3q"></p>
<ul>
<li class="">If you only want to use defined steps, just like calling a packaged third-party function, the only thing you need to care about is your input parameters and the step type you want. For example, in a typical image-building scenario, first, specify the step type as <code>build-push-image</code> and then specify your input parameters: the code source and branch of the built image, the name of the built image, and the secret key of the image repository to push.</li>
</ul>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token key atrule">apiVersion</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> core.oam.dev/v1alpha1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> WorkflowRun</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">metadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> build</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">push</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">image</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">namespace</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> default</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">spec</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">workflowSpec</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">   </span><span class="token key atrule">steps</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> build</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">push</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> build</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">push</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">image</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">git</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> github.com/FogDong/simple</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">web</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">demo</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">branch</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> main</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">image</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> fogdong/simple</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">web</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">demo</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">v1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">credentials</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">image</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> image</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">secret</span><br></span></code></pre></div></div>
<p>In such an architecture, the abstraction of the step brings infinite possibilities to the workflow. When you need to add a step to the workflow, you no longer need to compile-build-package the business code and then use the pod to execute the code. You only need to modify the configuration code in the step definition (together with the workflow engine's orchestration and control capability) to integrate with new features.</p>
<p>This is also the main reason why SAE chooses Kubevela Workflow. Based on scalability, we can fully leverage the power of ecology and accelerate product upgrades.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="cases">Cases<a href="https://kubevela.io/blog/2023/01/18/workflow-sae/#cases" class="hash-link" aria-label="Direct link to Cases" title="Direct link to Cases" translate="no">​</a></h2>
<p>Next, let's go deeper into the user cases in SAE.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="case-1-automated-operations">Case 1: Automated Operations<a href="https://kubevela.io/blog/2023/01/18/workflow-sae/#case-1-automated-operations" class="hash-link" aria-label="Direct link to Case 1: Automated Operations" title="Direct link to Case 1: Automated Operations" translate="no">​</a></h3>
<p>The first scenario is an automated operations scenario for SREs in SAE.</p>
<p>In SAE, we write and update some base images for users. We need to preload these images to multiple clusters in different regions to provide a better experience for users who use these base images.</p>
<p>The original operation process is very complicated. It involves building images and pushing them across multiple regions using ACR, as well as creating image cache templates and managing those image caches. Regions here include Shanghai, US West, Shenzhen, and Singapore. These operations are non-standardized and time-consuming. This is because when an SRE needs to push these images from the local to foreign clusters, it is likely to fail due to network problems. Therefore, he needs to disperse his energy on these operations that could otherwise be automated.</p>
<p>This is also the scenario that KubeVela Workflow is suitable for: each step in these operations can be converted into a step in the workflow programmatically, so that these steps can be orchestrated and reused. In addition, KubeVela Workflow provides a visual dashboard. SREs only need to configure a pipeline template once, and can automate the process by triggering execution or by entering specific runtime parameters each time the execution is triggered.</p>
<p>The simplified steps is like below:</p>
<ol>
<li class="">Use the <code>HTTP request</code> step type to build an image by requesting the service of ACR and pass the image ID to the next step through inputs/outputs. In this step definition, you need to wait until the ACR service is done before ending the execution of the current step.</li>
<li class="">If the first step fails, execute the <code>error handle</code> step.</li>
<li class="">If the first step is successfully built, use the <code>HTTP request</code> step to build image cache, at the same time, the service logs are used as the source of the current step.  Here you can view the logs of the steps directly in the Dashboard to troubleshoot problems.</li>
<li class="">Use a <code>step group</code> with <code>deploy</code> step type to preload images for clusters in the China (Shanghai) region and the US (West) region. The multi-cluster management and control capabilities of KubeVela Workflow are used to distribute the <code>ImagePullJob</code> workload to multiple clusters to preload images.</li>
</ol>
<p><img decoding="async" loading="lazy" alt="image.png" src="https://kubevela.io/assets/images/wf-sae-4-e1be5147c409f0ced65c0f9c0f7dec74.png" width="1500" height="548" class="img_ev3q"></p>
<p>In the preceding process, if you do not use KubeVela Workflow, you may need to write a bunch of business code to connect multiple services and clusters. Let’s take the last step of distributing the <code>ImagePullJob</code> workload to multiple clusters as an example: Not only do you need to manage the configuration of multiple clusters, but also need to watch the status of the workload (CRD) until the status of the workload becomes <code>Ready</code> before proceeding to the next step. This process actually corresponds to a simple Kubernetes Operator's reconcile logic: first create or update a resource, if the status of the resource is as expected, then end the reconcile, if not, continue to wait.</p>
<p><strong>Do we need to implement an Operator for every new resource management in our operations? Is there any convenient way to free us from the complicated Operator development?</strong></p>
<p>It is precisely because of the programmability of steps in KubeVela Workflow that it can completely cover these operations and resource management in SAE scenarios, which can help engineers reduce manpower consumption. Similar to the above logic, the step definition corresponding to KubeVela Workflow is very simple. No matter what kind of resources (or a HTTP interface request), it can be covered by a similar step template like:</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token key atrule">template</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  // First</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> read resources from the specified cluster</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	</span><span class="token key atrule">read</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> op.</span><span class="token comment" style="color:rgb(98, 114, 164)">#Read &amp; {</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  	</span><span class="token key atrule">value</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    	</span><span class="token key atrule">apiVersion</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> parameter.apiVersion</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    	</span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> parameter.kind</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    	</span><span class="token key atrule">metadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      	</span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> parameter.name</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      	</span><span class="token key atrule">namespace</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> parameter.namespace</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    	</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  	</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  	</span><span class="token key atrule">cluster</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> parameter.cluster</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	// Second</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> wait until the resource is Ready. Otherwise</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> the step keeps waiting</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	</span><span class="token key atrule">wait</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> op.</span><span class="token comment" style="color:rgb(98, 114, 164)">#ConditionalWait &amp; {</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  	</span><span class="token key atrule">continue</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> read.value.status </span><span class="token tag" style="color:rgb(255, 121, 198)">!=</span><span class="token plain"> _</span><span class="token punctuation" style="color:rgb(248, 248, 242)">|</span><span class="token plain">_ </span><span class="token important">&amp;&amp;</span><span class="token plain"> read.value.status.phase == "Ready"</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	// Third(optional)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> if the resource is Ready</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> then</span><span class="token punctuation" style="color:rgb(248, 248, 242)">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	// Custom Logic</span><span class="token punctuation" style="color:rgb(248, 248, 242)">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	// Users must input the defined parameter when using the step type</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	</span><span class="token key atrule">parameter</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  	</span><span class="token key atrule">apiVersion</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> string</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  	</span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> string</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  	</span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> string</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  	</span><span class="token key atrule">namespace</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token important">*context.namespace</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">|</span><span class="token plain"> string</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  	</span><span class="token key atrule">cluster</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token important">*""</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">|</span><span class="token plain"> string</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> 	</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></div></div>
<p>Corresponding to the current case is:</p>
<ul>
<li class=""><strong>First:</strong> Read the status of <code>ImagePullJob</code> in a specified cluster, such as the cluster in the China (Shanghai) region.</li>
<li class=""><strong>Second:</strong> If the <code>ImagePullJob</code> is ready and the image has been preloaded, continue to execute.</li>
<li class="">**Third(Optional): **After the <code>ImagePullJob</code> is ready, clean up the <code>ImagePullJob</code> in the cluster.</li>
</ul>
<p>Like this, no matter how many Region clusters or new type resources are added in the subsequent O&amp;M scenarios, you can let KubeVela Workflow manage the cluster's KubeConfig, and use the defined step types with different cluster names or resource types to achieve a simplified Kubernetes Operator Reconcile process to reduce development costs.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="case-2-optimize-the-existing-delivery-process">Case 2: Optimize the Existing Delivery Process<a href="https://kubevela.io/blog/2023/01/18/workflow-sae/#case-2-optimize-the-existing-delivery-process" class="hash-link" aria-label="Direct link to Case 2: Optimize the Existing Delivery Process" title="Direct link to Case 2: Optimize the Existing Delivery Process" translate="no">​</a></h3>
<p>In addition to automating internal O&amp;M operations, upgrading the original SAE product architecture to improve delivery efficiency for users is also an important reason of choosing KubeVela Workflow.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="original-architecture">Original Architecture<a href="https://kubevela.io/blog/2023/01/18/workflow-sae/#original-architecture" class="hash-link" aria-label="Direct link to Original Architecture" title="Direct link to Original Architecture" translate="no">​</a></h4>
<p>In the delivery scenario of SAE, a delivery process corresponds to a series of tasks, such as: initializing the environment, building images, releasing in batches, etc. This series of tasks corresponds to the <code>SAE Tasks</code> in the figure below.</p>
<p>These tasks are sequentially thrown to <code>Java Executor</code> for business logic in the original architecture of SAE, such as creating resources in Kubernetes, and synchronizing the status of current tasks with the MySQL database, etc.</p>
<p>After the current task is completed, JAVA Executor will get the next task from SAE's original orchestration engine, and at the same time, the orchestration engine will continuously put new tasks into the initial task list.</p>
<p><img decoding="async" loading="lazy" alt="image.png" src="https://kubevela.io/assets/images/wf-sae-5-e056e8df35321357b420886fc46625f3.png" width="1500" height="862" class="img_ev3q"></p>
<p>The biggest problem in this old architecture is the polling call. <code>JAVA Executor</code> will get it from the SAE task list every second to check whether there are new tasks; at the same time, after <code>JAVA Executor</code> creates Kubernetes resources, it will attempts to get the status of resources from the cluster every second.</p>
<p>The original architecture of SAE is not the controller model in the Kubernetes ecosystem, but the polling model. If the orchestration engine layer is upgraded to the controller model for event watching, it can better integrate with the entire Kubernetes ecosystem and improve efficiency.</p>
<p><img decoding="async" loading="lazy" alt="image.png" src="https://kubevela.io/assets/images/wf-sae-6-0bdee101ba67e5f629701ef1a7a2c5ff.png" width="1064" height="344" class="img_ev3q"></p>
<p>However, the logic coupling of business is deep in the original architecture. If the traditional container-based cloud-native workflow is used, SAE needs to package the original business logic into images and maintain and update a large number of images, which is not a sustainable path. We hope the upgraded workflow engine can be easily integrated with the task orchestration, business execution layer, and Kubernetes cluster.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="new-architecture">New Architecture<a href="https://kubevela.io/blog/2023/01/18/workflow-sae/#new-architecture" class="hash-link" aria-label="Direct link to New Architecture" title="Direct link to New Architecture" translate="no">​</a></h4>
<p>With the high scalability of KubeVela Workflow, SAE engineers do not need to repackage the original capabilities into images or make large-scale modifications.</p>
<p><img decoding="async" loading="lazy" alt="image.png" src="https://kubevela.io/assets/images/wf-sae-7-782999032d97704ef2772b2e3e16d9e6.png" width="1500" height="667" class="img_ev3q"></p>
<p>The new process is shown in the preceding figure. After a delivery paln is created on the SAE product side, the business side writes the model to the database, converts the model, and generates a KubeVele workflow, which corresponds to YAML on the right side.</p>
<p>At the same time, SAE's original Java Executor provides the original business capabilities as microservice APIs. When KubeVela Workflow is executed, each step is IaC-based, and the underlying implementation is in the CUE language. Some of these steps will call the business microservice API of SAE, while others will directly interact with the underlying Kubernetes resources. Data can be transferred between steps. If there is an error in the call, you can use the conditional judgment of the step to handle the error.</p>
<p>Such optimization is scalable and fully reuses the Kubernetes ecosystem. It extends workflow processes and atomic capabilities and is oriented to the final state. This combination of scalability and process control can cover the original business functions and reduce the amount of development. At the same time, the state update latency is reduced from the minute level to the millisecond level, which is agile and native. It has the YAML-level description capability but also improves the development efficiency from 1d to 1h.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="case-3-launch-new-features-quickly">Case 3: Launch New Features Quickly<a href="https://kubevela.io/blog/2023/01/18/workflow-sae/#case-3-launch-new-features-quickly" class="hash-link" aria-label="Direct link to Case 3: Launch New Features Quickly" title="Direct link to Case 3: Launch New Features Quickly" translate="no">​</a></h3>
<p>In addition to automated O&amp;M and upgrading the original architecture, <em>what else can KubeVela Workflow provide?</em></p>
<p>The reusability of steps and the ease of integration with other ecosystems bring more surprises to SAE in addition to upgrades: <strong>from</strong> <strong>writing business code to orchestrating different steps, so as to launch new product features quickly!</strong></p>
<p>SAE has accumulated a large amount of JAVA foundation and supports a wealth of functions, such as: supporting single-batch release, multi-batch release, and canary release for JAVA microservices. However, with the increase of customers, some customers have put forward new requirements, and they hope to have the ability to publish multilingual north-south traffic in canary release.</p>
<p>There are also many mature open-source products for canary releases, such as Kruise Rollout. After investigation, SAE engineers found that Kruise Rollout can be used to complete the ability of canary release, and it can cooperate with the internal ingress controller(ALB) of Alibaba Cloud to split different traffic.</p>
<p><img decoding="async" loading="lazy" alt="image.png" src="https://kubevela.io/assets/images/wf-sae-8-69036ef617f7da9b4aa97b3bc4391308.png" width="1374" height="1042" class="img_ev3q"></p>
<p>Such a solution is shown in the architecture diagram above. SAE distributes a KubeVela Workflow, and the steps in the Workflow will integrate with Alibaba Cloud ALB, open-source Kruise Rollout, and SAE's business components at the same time. Batch management is completed in the steps, thus completing the rapid launch of features.</p>
<p>In fact, after using KubeVela Workflow, it is no longer necessary to write new business codes for this feature. It is only necessary to write a step type for updating canary batches.</p>
<p>Due to the programmability of step types, we can easily use different patch policies in the definition to update the release batches of Rollout objects in the different clusters. Moreover, in the workflow, the step type of each step is reusable. This means when you develop a new step type, you are laying the foundation for the next time a new feature is launched. This reuse allows you to launch features quickly and reduce development costs.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="summary">Summary<a href="https://kubevela.io/blog/2023/01/18/workflow-sae/#summary" class="hash-link" aria-label="Direct link to Summary" title="Direct link to Summary" translate="no">​</a></h2>
<p>After SAE upgraded the KubeVela architecture, it improved delivery efficiency and reduced development costs. Based on the advantages of its underlying reliance on Serverless infrastructure, it can give full play to the advantages of the product in application hosting.</p>
<p>In addition, the architecture upgrade solution of KubeVela Workflow in SAE is an open-source solution that can be <strong>replicated</strong>. The community provides more than 50 built-in step types (including image building, image pushing, image scanning, and multi-cluster deployment, using Terraform to manage infrastructure, condition wait, message notification, etc) to help you open up CI/CD easily.</p>
<p><img decoding="async" loading="lazy" alt="image.png" src="https://kubevela.io/assets/images/wf-sae-9-f40e1e27d1d5351e7f4e0e230712e9e6.png" width="1500" height="602" class="img_ev3q"></p>
<p>You can refer to the following documents for more usage scenarios:</p>
<ul>
<li class=""><a href="https://github.com/kubevela/workflow#try-kubevela-workflow" target="_blank" rel="noopener noreferrer" class="">Build images, push images, and deploy resources</a></li>
<li class=""><a href="https://github.com/kubevela/workflow/blob/main/examples/multiple-apps.md" target="_blank" rel="noopener noreferrer" class="">Orchestrate multiple KubeVela Applications</a></li>
<li class=""><a href="https://github.com/kubevela/workflow/blob/main/examples/initialize-env.md" target="_blank" rel="noopener noreferrer" class="">Initialize the Environment with One Click, use Terraform to pull up clusters, manage clusters, and distribute resources to new clusters</a></li>
<li class=""><a href="https://github.com/kubevela/workflow/blob/main/examples/request-and-notify.md" target="_blank" rel="noopener noreferrer" class="">Call the specified service and send a notification of the returned result through data passing</a></li>
<li class=""><a href="https://github.com/kubevela/workflow/blob/main/examples/run-with-template.md" target="_blank" rel="noopener noreferrer" class="">Use different context parameters to control the deployment of resources</a></li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-end">The End<a href="https://kubevela.io/blog/2023/01/18/workflow-sae/#the-end" class="hash-link" aria-label="Direct link to The End" title="Direct link to The End" translate="no">​</a></h2>
<p>You can learn more about KubeVela and the OAM project through the following materials:</p>
<ul>
<li class="">Project Code Library: <a href="https://github.com/kubevela/kubevela" target="_blank" rel="noopener noreferrer" class="">https://github.com/kubevela/kubevela</a> Welcome to Star/Watch/Fork!</li>
<li class="">Workflow Code Library: <a href="https://github.com/kubevela/workflow" target="_blank" rel="noopener noreferrer" class="">https://github.com/kubevela/workflow</a> Welcome to Star/Watch/Fork!</li>
<li class="">Official Project Homepage and Documents: kubevela.io</li>
<li class="">Slack：CNCF #kubevela Channel</li>
</ul>]]></content>
        <author>
            <name>Fog Dong</name>
            <uri>https://github.com/FogDong</uri>
        </author>
        <category label="KubeVela" term="KubeVela"/>
        <category label="Workflow" term="Workflow"/>
        <category label="serverless" term="serverless"/>
        <category label="use-case" term="use-case"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Unified Application Management under Cloud-Edge Collaboration: A Solution Based on OpenYurt and KubeVela]]></title>
        <id>https://kubevela.io/blog/2023/01/09/kubevela-openyurt-integration/</id>
        <link href="https://kubevela.io/blog/2023/01/09/kubevela-openyurt-integration/"/>
        <updated>2023-01-09T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This article will focus on KubeVela and OpenYurt (two open-source projects of CNCF) and introduce the solution of cloud-edge collaboration in a practical Helm application delivery scenario.]]></summary>
        <content type="html"><![CDATA[<p>This article will focus on KubeVela and OpenYurt (two open-source projects of CNCF) and introduce the solution of cloud-edge collaboration in a practical Helm application delivery scenario.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="background">Background<a href="https://kubevela.io/blog/2023/01/09/kubevela-openyurt-integration/#background" class="hash-link" aria-label="Direct link to Background" title="Direct link to Background" translate="no">​</a></h2>
<p>With the popularization of the Internet of Everything scenario, the computing power of edge devices is increasing. It is a new technological challenge to use the advantages of cloud computing to meet complex and diversified edge application scenarios and extend cloud-native technology to the end and edge. <strong>Cloud-Edge Collaboration</strong> is becoming a new technological focus. This article will focus on KubeVela and OpenYurt (two open-source projects of CNCF) and introduce the solution of cloud-edge collaboration in a practical Helm application delivery scenario.</p>
<p>OpenYurt focuses on extending Kubernetes to edge computing in a non-intrusive manner. Based on the container orchestration and scheduling capabilities of native Kubernetes, OpenYurt integrates edge computing power into the Kubernetes infrastructure for unified management. It provides capabilities (such as edge autonomy, efficient O&amp;M channels, unitized edge management, edge traffic topology, secure containers, and edge Serverless/FaaS) and support for heterogeneous resources. In short, OpenYurt builds a unified infrastructure for cloud-edge collaboration in a Kubernetes-native manner.</p>
<p>Incubated in the OAM model, KubeVela focuses on helping enterprises build unified application delivery and management capabilities. It shields the complexity of underlying infrastructure for developers and provides flexible scaling capabilities. It also provides out-of-the-box microservice container management, cloud resource management, versioning and canary release, scaling, observability, resource dependency orchestration and data delivery, multi-cluster, CI docking, and GitOps. Maximize the R&amp;D performance of developer self-service application management, which also meets the extensibility demands of the long-term evolution of the platform.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="openyurt--kubevela---what-problems-can-be-solved">OpenYurt + KubeVela - What Problems Can be Solved?<a href="https://kubevela.io/blog/2023/01/09/kubevela-openyurt-integration/#openyurt--kubevela---what-problems-can-be-solved" class="hash-link" aria-label="Direct link to OpenYurt + KubeVela - What Problems Can be Solved?" title="Direct link to OpenYurt + KubeVela - What Problems Can be Solved?" translate="no">​</a></h2>
<p>As mentioned before, OpenYurt supports the access of edge nodes, allowing users to manage edge nodes by operating native Kubernetes. "Edge nodes" are used to represent computing resources closer to users (such as virtual machines or physical servers in a nearby data center). After you add them through OpenYurt, these edge nodes are converted into nodes that can be used in Kubernetes. OpenYurt uses NodePool to describe a group of edge nodes in the same region. After basic resource management is met, we have the following core requirements for how to orchestrate and deploy applications to different NodePools in a cluster.</p>
<ol>
<li class=""><strong>Unified Configuration:</strong> If you manually modify each resource to be distributed, there are many manual interventions, which are prone to errors. We need a unified way to configure parameters, which can not only facilitate batch management operations, but also connect security and audit to meet enterprise risk control and compliance requirements.</li>
<li class=""><strong>Differential Deployment:</strong> Most workloads deployed to different NodePools have the same attributes, but there are still personalized configuration differences. The key is how to set the parameters related to node selection. For example, <code>NodeSelector</code> can instruct the Kubernetes scheduler to schedule workloads to different NodePools.</li>
<li class=""><strong>Scalability:</strong> The cloud-native ecosystem is booming. Both workload types and different O&amp;M functions are growing. We need the overall application architecture to be scalable so that we can fully benefit from the dividends of the cloud-native ecosystem and meet business needs flexibly.</li>
</ol>
<p>KubeVela and OpenYurt can complement each other at the application layer to meet the preceding three core requirements. Next, I will show these functions with the operation process.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="deploy-an-application-to-the-edge">Deploy an Application to the Edge<a href="https://kubevela.io/blog/2023/01/09/kubevela-openyurt-integration/#deploy-an-application-to-the-edge" class="hash-link" aria-label="Direct link to Deploy an Application to the Edge" title="Direct link to Deploy an Application to the Edge" translate="no">​</a></h2>
<p>We will use the Ingress controller as an example to show how to use KubeVela to deploy applications to the edge. We want to deploy the Nginx Ingress controller to multiple NodePools to access the services provided by the specified NodePool through the edge Ingress. An Ingress can only be handled by the Ingress controller in the NodePool.</p>
<p>The cluster in the schematic diagram contains two NodePools: Beijing and Shanghai. The networks between them are not interconnected. We want to deploy an Nginx Ingress Controller, which can act as the network traffic ingress for each NodePool. A client close to Beijing can access the services provided in the Beijing NodePool by accessing the Ingress Controller of the Beijing NodePool and does not access the services provided in the Shanghai NodePool.</p>
<p><img decoding="async" loading="lazy" alt="NodePool Structure" src="https://kubevela.io/assets/images/nodepool-869edf33a4d3ec63522ed497903ff98d.png" width="1500" height="515" class="img_ev3q"></p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="basic-environment-of-demo">Basic Environment of Demo<a href="https://kubevela.io/blog/2023/01/09/kubevela-openyurt-integration/#basic-environment-of-demo" class="hash-link" aria-label="Direct link to Basic Environment of Demo" title="Direct link to Basic Environment of Demo" translate="no">​</a></h3>
<p>We will use Kubernetes clusters to simulate edge scenarios. The cluster has three nodes, and their roles are:</p>
<ul>
<li class=""><strong>Node 1:</strong> master node, cloud node</li>
<li class=""><strong>Node 2:</strong> worker node, edge node, in NodePool <code>Beijing</code></li>
<li class=""><strong>Node 3:</strong> worker node, edge node, in NodePool <code>Shanghai</code></li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="preparations">Preparations<a href="https://kubevela.io/blog/2023/01/09/kubevela-openyurt-integration/#preparations" class="hash-link" aria-label="Direct link to Preparations" title="Direct link to Preparations" translate="no">​</a></h3>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="1-install-yurtappmanager">1. Install YurtAppManager<a href="https://kubevela.io/blog/2023/01/09/kubevela-openyurt-integration/#1-install-yurtappmanager" class="hash-link" aria-label="Direct link to 1. Install YurtAppManager" title="Direct link to 1. Install YurtAppManager" translate="no">​</a></h4>
<p>YurtAppManager is the core component of OpenYurt. It provides NodePool CRD and controller. There are other components in OpenYurt, but we only need YurtAppManager in this tutorial.</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">git clone https://github.com/openyurtio/yurt-app-managercd yurt-app-manager &amp;&amp; helm install yurt-app-manager -n kube-system ./charts/yurt-app-manager/</span><br></span></code></pre></div></div>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="2-install-kubevela-and-enable-the-fluxcd-addon">2. Install KubeVela and Enable the FluxCD Addon<a href="https://kubevela.io/blog/2023/01/09/kubevela-openyurt-integration/#2-install-kubevela-and-enable-the-fluxcd-addon" class="hash-link" aria-label="Direct link to 2. Install KubeVela and Enable the FluxCD Addon" title="Direct link to 2. Install KubeVela and Enable the FluxCD Addon" translate="no">​</a></h4>
<p>Install the Vela command-line tool and install KubeVela in the cluster:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">curl -fsSl https://kubevela.io/script/install.sh | bash</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela install</span><br></span></code></pre></div></div>
<p>We want to reuse the mature Helm charts provided by the community, so we use Helm-type components to install the Nginx Ingress Controller. In KubeVela with microkernel design, Helm components are provided by the FluxCD addon. The following enables the <a href="https://kubevela.net/zh/docs/reference/addons/fluxcd" target="_blank" rel="noopener noreferrer" class="">FluxCD addon</a>.</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela addon enable fluxcd</span><br></span></code></pre></div></div>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="3-prepare-nodepool">3. Prepare NodePool<a href="https://kubevela.io/blog/2023/01/09/kubevela-openyurt-integration/#3-prepare-nodepool" class="hash-link" aria-label="Direct link to 3. Prepare NodePool" title="Direct link to 3. Prepare NodePool" translate="no">​</a></h4>
<p>Create two NodePools: Beijing and Shanghai. Dividing NodePools by region is a common pattern in actual edge scenarios. Different groups of nodes often have obvious isolation attributes (such as network disconnection, no resource sharing, resource heterogeneity, and application independence). This is the origin of the NodePool concept. In OpenYurt, features (such as NodePools and service topologies) are used to help users deal with the preceding issues. In today's example, we will use NodePools to describe and manage nodes:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">kubectl apply -f - &lt;&lt;EOF</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">apiVersion: apps.openyurt.io/v1beta1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">kind: NodePool</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">metadata:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  name: beijing</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">spec:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  type: Edge</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  annotations:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    apps.openyurt.io/example: test-beijing</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  taints:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    - key: apps.openyurt.io/example</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      value: beijing</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      effect: NoSchedule</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">---</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">apiVersion: apps.openyurt.io/v1beta1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">kind: NodePool</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">metadata:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  name: shanghai</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">spec:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  type: Edge</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  annotations:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    apps.openyurt.io/example: test-shanghai</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  taints:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    - key: apps.openyurt.io/example</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      value: shanghai</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      effect: NoSchedule</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">EOF</span><br></span></code></pre></div></div>
<p>Add edge nodes to their respective NodePools. Please see how OpenYurt nodes are added for more information about how edge nodes are added.</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">kubectl label node &lt;node1&gt; apps.openyurt.io/desired-nodepool=Beijing</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">kubectl label node &lt;node2&gt; apps.openyurt.io/desired-nodepool=shanghai</span><br></span></code></pre></div></div>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">kubectl get nodepool</span><br></span></code></pre></div></div>
<p>Expected Output</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">NAME       TYPE   READYNODES   NOTREADYNODES   AGE</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">beijing    Edge   1            0               6m2s</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">shanghai   Edge   1            0               6m1s</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="deploy-edge-applications-in-batches">Deploy Edge Applications in Batches<a href="https://kubevela.io/blog/2023/01/09/kubevela-openyurt-integration/#deploy-edge-applications-in-batches" class="hash-link" aria-label="Direct link to Deploy Edge Applications in Batches" title="Direct link to Deploy Edge Applications in Batches" translate="no">​</a></h3>
<p>Before we get into the details, let's look at how KubeVela describes and deploys applications to the edge. With the following application, we can deploy multiple Nginx Ingress Controller to their respective edge NodePools. Using the same application to <strong>uniformly configure</strong> the Nginx Ingress can <strong>eliminate duplication and reduce the management burden. It facilitates unified operations (such as the release and other O&amp;M of components in the cluster).</strong></p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token key atrule">apiVersion</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> core.oam.dev/v1beta1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> Application</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">metadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> edge</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">ingress</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">spec</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">components</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> ingress</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">nginx</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> helm</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">chart</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> ingress</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">nginx</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">url</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> https</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">//kubernetes.github.io/ingress</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">nginx</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">repoType</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> helm</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">version</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> 4.3.0</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">values</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">controller</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token key atrule">service</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">              </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> NodePort</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token key atrule">admissionWebhooks</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">              </span><span class="token key atrule">enabled</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token boolean important">false</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">traits</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> edge</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">nginx</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">policies</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> replication</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> replication</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">selector</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"ingress-nginx"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">keys</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"beijing"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token string" style="color:rgb(255, 121, 198)">"shanghai"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">workflow</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">steps</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> deploy</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> deploy</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">policies</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">"replication"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><br></span></code></pre></div></div>
<p>A KubeVela application has three parts.</p>
<ol>
<li class=""><strong><code>Helm</code> Type Component:</strong> It describes the version of the Helm package that we want to install into the cluster. In addition, we have attached an trait to this component: <code>edge-nginx</code>. We'll show the details of this trait later. You can regard it as a patch that contains the properties of different NodePools.</li>
<li class=""><strong>The Strategy of <code>Replication</code>:</strong> It describes how to copy components to different NodePools. The field <code>selector</code> is used to select the components to be copied. Its <code>keys</code> field will convert one component to two components with different keys ("Beijing" and "Shanghai").</li>
<li class=""><strong><code>Deploy</code> Workflow Steps:</strong> It describes how to deploy an application. It specifies the <code>replication</code> strategy to perform replication work.</li>
</ol>
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg 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</div><div class="admonitionContent_BuS1"><ol>
<li class="">If you want this application to work properly, please apply the <code>edge-ingress</code> trait described below in the cluster first.</li>
<li class=""><code>Deploy</code> is a KubeVela built-in workflow step. It can be also used with <code>override</code> and <code>topology</code> strategies in <a href="https://kubevela.net/docs/case-studies/multi-cluster" target="_blank" rel="noopener noreferrer" class="">multi-cluster scenarios</a>.</li>
</ol></div></div>
<p>Now, we can send the application to the cluster.</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela up -f app.yaml</span><br></span></code></pre></div></div>
<p>Check the application status and resources created by KubeVela.</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela status edge-ingress --tree --detail</span><br></span></code></pre></div></div>
<p>Expected Output</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">CLUSTER       NAMESPACE     RESOURCE                           STATUS    APPLY_TIME          DETAIL</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">local  ─── default─┬─ HelmRelease/ingress-nginx-beijing  updated   2022-11-02 12:00:24 Ready: True  Status: Release reconciliation succeeded  Age: 153m</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                   ├─ HelmRelease/ingress-nginx-shanghai updated   2022-11-02 12:00:24 Ready: True  Status: Release reconciliation succeeded  Age: 153m</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                   └─ HelmRepository/ingress-nginx       updated   2022-11-02 12:00:24 URL: https://kubernetes.github.io/ingress-nginx  Age: 153m</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                                                                                         Ready: True</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                                                                                         Status: stored artifact for revision '7bce426c58aee962d479ca84e5c</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                                                                                         fc6931c19c8995e31638668cb958d4a3486c2'</span><br></span></code></pre></div></div>
<p>Vela CLI can stand on a higher level to uniformly show the health status of applications. When it's needed, Vela CLI can help you penetrate applications and direct access to the underlying workloads. Also, it offers a rich selection of observability and Debug capability. For example, you can print the application's log through <code>vela logs</code>. You can forward the port that deploys applications locally through <code>vela port-forward</code>. You can use the <code>vela exec</code> command to go deep into the container at the edge and run Shell commands to troubleshoot the problem.</p>
<p>If you need an intuitive understanding of the application, KubeVela officials provide a Web console addon, VelaUX. You can view detailed resource topologies with the <a href="https://kubevela.net/zh/docs/reference/addons/velaux" target="_blank" rel="noopener noreferrer" class="">VelaUX addon</a> .</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela addon enable velaux</span><br></span></code></pre></div></div>
<p>Visit the Resource Topology page of VelaUX:</p>
<p><img decoding="async" loading="lazy" alt="Resource Topology in VelaUX" src="https://kubevela.io/assets/images/velaux-570fea064d8803b22b91312e24dcb326.png" width="3166" height="2284" class="img_ev3q"></p>
<p>As you can see, KubeVela creates two <code>HelmRelease</code> to deliver the Nginx Ingress Controller Helm chart to two NodePools. <code>HelmRelease</code> resources are processed by the preceding FluxCD addon, and NGINX Ingress is installed in the <strong>two NodePools</strong> of the cluster. Run the following command to check whether pods of the Ingress controller are created in the Beijing NodePool. The same is true for the shanghai NodePool.</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">$ kubectl get node -l  apps.openyurt.io/nodepool=beijing                               </span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">NAME                      STATUS   ROLES    AGE   VERSION</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">iz0xi0r2pe51he3z8pz1ekz   Ready    &lt;none&gt;   23h   v1.24.7+k3s1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">$ kubectl get pod ingress-nginx-beijing-controller-c4c7cbf64-xthlp -oyaml|grep iz0xi0r2pe51he3z8pz1ekz</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  nodeName: iz0xi0r2pe51he3z8pz1ekz</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="differentiated-deployment">Differentiated Deployment<a href="https://kubevela.io/blog/2023/01/09/kubevela-openyurt-integration/#differentiated-deployment" class="hash-link" aria-label="Direct link to Differentiated Deployment" title="Direct link to Differentiated Deployment" translate="no">​</a></h3>
<p><em>How can a differentiated deployment of the same component be implemented during KubeVela application delivery?</em> Let's continue to learn about the Trait and Policy that support the application. As mentioned above, we use KubeVela's built-in component replication policy in the workflow to attach a custom <code>edge-nginx</code> trait to ingress-nginx components.</p>
<ul>
<li class="">The component splitting policy <strong>splits the component into two components</strong> with a different <code>context.replicaKey</code>.</li>
<li class=""><code>edge-nginx</code> Trait uses different <code>context.replicaKey</code> to deliver Helm charts with different configuration values to the cluster. Let the two Nginx Ingress Controller run in different NodePools and monitor Ingress resources with different ingressClasses. Patch the values of the Helm chart and modify the fields related to <strong>Node Selection, Affinity, and ingressClass</strong>.</li>
<li class="">Different <a href="https://kubevela.io/docs/platform-engineers/traits/patch-trait#patch-strategy" target="_blank" rel="noopener noreferrer" class="">patch strategies</a> is used when patching different fields. For example, a <code>retainKeys</code> strategy can overwrite the original value, while a <code>jsonMergePatch</code> strategy is merged with the original value.</li>
</ul>
<div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token property">"edge-nginx"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  type</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"trait"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  annotations</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  attributes</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    podDisruptive</span><span class="token operator">:</span><span class="token plain"> </span><span class="token boolean">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    appliesToWorkloads</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">"helm"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">template</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  patch</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token comment" style="color:rgb(98, 114, 164)">// +patchStrategy=retainKeys</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    metadata</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      name</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"\(context.name)-\(context.replicaKey)"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token comment" style="color:rgb(98, 114, 164)">// +patchStrategy=jsonMergePatch</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    spec</span><span class="token operator">:</span><span class="token plain"> values</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      ingressClassByName</span><span class="token operator">:</span><span class="token plain"> </span><span class="token boolean">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      controller</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        ingressClassResource</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          name</span><span class="token operator">:</span><span class="token plain">            </span><span class="token string" style="color:rgb(255, 121, 198)">"nginx-"</span><span class="token plain"> + context.replicaKey</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          controllerValue</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"openyurt.io/"</span><span class="token plain"> + context.replicaKey</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        _selector</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      defaultBackend</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        _selector</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  _selector</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    tolerations</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        key</span><span class="token operator">:</span><span class="token plain">      </span><span class="token string" style="color:rgb(255, 121, 198)">"apps.openyurt.io/example"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        operator</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Equal"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        value</span><span class="token operator">:</span><span class="token plain">    context.replicaKey</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    nodeSelector</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">"apps.openyurt.io/nodepool"</span><span class="token operator">:</span><span class="token plain"> context.replicaKey</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  parameter</span><span class="token operator">:</span><span class="token plain"> </span><span class="token null keyword" style="color:rgb(189, 147, 249);font-style:italic">null</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="let-more-types-of-applications-go-to-the-edge">Let More Types of Applications Go to the Edge<a href="https://kubevela.io/blog/2023/01/09/kubevela-openyurt-integration/#let-more-types-of-applications-go-to-the-edge" class="hash-link" aria-label="Direct link to Let More Types of Applications Go to the Edge" title="Direct link to Let More Types of Applications Go to the Edge" translate="no">​</a></h3>
<p>As you can see, we only customize a trait with more than 40 rows and make full use of the built-in capabilities of KubeVela to deploy Nginx Ingress to different NodePools. <strong>More applications</strong> are likely to be deployed at the edge with the prosperous cloud-native ecosystem and cloud-edge collaboration trend. When a new application needs to be deployed in the edge NodePool in the new scenario, there is no need to worry. KubeVela makes it easy to expand a new edge application deployment trait following this pattern <strong>without writing code</strong>.</p>
<p>For example, we hope to deploy the implementation of the Kubernetes community's recent evolution hotspot <a href="https://gateway-api.sigs.k8s.io/" target="_blank" rel="noopener noreferrer" class="">Gateway API</a> to the edge as well. We can use the Gateway API to enhance the expressive capability and extensibility of the edge NodePool to expose services and use role-based network APIs on edge nodes. For this scenario, we can easily complete the deployment task based on the preceding extension method. You only need to define a new trait (as shown below):</p>
<div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token property">"gateway-nginx"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  type</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"trait"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  annotations</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  attributes</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    podDisruptive</span><span class="token operator">:</span><span class="token plain"> </span><span class="token boolean">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    appliesToWorkloads</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">"helm"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">template</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  patch</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token comment" style="color:rgb(98, 114, 164)">// +patchStrategy=retainKeys</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    metadata</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      name</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"\(context.name)-\(context.replicaKey)"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token comment" style="color:rgb(98, 114, 164)">// +patchStrategy=jsonMergePatch</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    spec</span><span class="token operator">:</span><span class="token plain"> values</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      _selector</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      fullnameOverride</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"nginx-gateway-nginx-"</span><span class="token plain"> + context.replicaKey</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      gatewayClass</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        name</span><span class="token operator">:</span><span class="token plain">           </span><span class="token string" style="color:rgb(255, 121, 198)">"nginx"</span><span class="token plain"> + context.replicaKey</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        controllerName</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"k8s-gateway-nginx.nginx.org/nginx-gateway-nginx-controller-"</span><span class="token plain"> + context.replicaKey</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  _selector</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    tolerations</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        key</span><span class="token operator">:</span><span class="token plain">      </span><span class="token string" style="color:rgb(255, 121, 198)">"apps.openyurt.io/example"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        operator</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Equal"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        value</span><span class="token operator">:</span><span class="token plain">    context.replicaKey</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    nodeSelector</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">"apps.openyurt.io/nodepool"</span><span class="token operator">:</span><span class="token plain"> context.replicaKey</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  parameter</span><span class="token operator">:</span><span class="token plain"> </span><span class="token null keyword" style="color:rgb(189, 147, 249);font-style:italic">null</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></div></div>
<p>This Trait is similar to the one used to deploy the Nginx Ingress mentioned earlier. We also made some similar patch for Nginx Gateway chart values, including node selection, affinity, and resource name. The difference between the former trait is that this Trait specifies the gatewayClass instead of the IngressClass. Please see the GitHub <a href="https://github.com/chivalryq/yurt-vela-example/tree/main/gateway-nginx" target="_blank" rel="noopener noreferrer" class="">repository</a> for more information about the trait and application files. We extend the ability of the cluster to deploy a new application to the edge by customizing such a Trait.
If we cannot predict application deployment requirements brought about by the development of edge computing in the future, at least we can adapt to new scenarios through this scalability way.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="how-kubevela-solves-edge-deployment-puzzles">How KubeVela Solves Edge Deployment Puzzles<a href="https://kubevela.io/blog/2023/01/09/kubevela-openyurt-integration/#how-kubevela-solves-edge-deployment-puzzles" class="hash-link" aria-label="Direct link to How KubeVela Solves Edge Deployment Puzzles" title="Direct link to How KubeVela Solves Edge Deployment Puzzles" translate="no">​</a></h2>
<p>Let's review how KubeVela addressed the key issues raised at the beginning of the article.</p>
<ol>
<li class=""><strong>Unified Configuration:</strong>:A<!-- --> component is used to describe the common properties of the ingress-nginx Helm chart to be deployed (such as Helm repository, chart name, version, and other unified configurations).</li>
<li class=""><strong>Attribute Differences:</strong> KubeVela uses a user-defined trait that describes the differences in Helm configurations sent to different NodePools. This trait can be repeatedly used to deploy the same Helm Chart.</li>
<li class=""><strong>Scalability:</strong> KubeVela can be programmable for common workloads (such as Deployment/StatefulSet) or other packaging methods (such as Helm or Kustomize). It requires only a few lines of code to push a new application to the edge.</li>
</ol>
<p>It benefits from the powerful functions provided by KubeVela in the application delivery and management field. In addition to solving application definition, delivery, O&amp;M, and observability issues within a single cluster, KubeVela natively supports application release and management in the <strong>multi-cluster mode</strong>. Currently, the Kubernetes deployment mode suitable for edge computing scenarios is not fixed. KubeVela can manage application tasks regardless of the architecture of single cluster + edge NodePool or multi-edge cluster architecture.</p>
<p>With OpenYurt and KubeVela, cloud-edge applications are deployed in a unified manner and share the same abstraction, O&amp;M, and observability, which avoids the experience of being separated in different scenarios. In addition, cloud applications and edge applications can take advantage of KubeVela's excellent practices of a continuously integrated cloud-native ecosystem in the form of addons. In the future, the KubeVela community will continue to enrich out-of-the-box system addons and deliver better and easier-to-use application delivery and management capabilities.</p>
<p>If you want to know more about the capabilities of application deployment and management, you can read KubeVela’s <a href="https://kubevela.io/" target="_blank" rel="noopener noreferrer" class="">official documents</a>. If you want to know the latest development in the KubeVela <a href="https://github.com/kubevela/community" target="_blank" rel="noopener noreferrer" class="">community</a>, you are welcome to participate in the discussion! If you are interested in OpenYurt, you are welcome to join the OpenYurt community!</p>
<p>You can learn more about KubeVela and the OAM project through the following materials:</p>
<ul>
<li class="">Project Code Base: <a href="https://github.com/oam-dev/kubevela" target="_blank" rel="noopener noreferrer" class="">https://github.com/oam-dev/kubevela</a> Welcome Star/Watch/Fork!</li>
<li class="">Project Official Homepage and Documents: kubevela.io</li>
</ul>]]></content>
        <author>
            <name>Qiao Zhongpei</name>
            <uri>https://github.com/chivalryq</uri>
        </author>
        <category label="KubeVela" term="KubeVela"/>
        <category label="OpenYurt" term="OpenYurt"/>
        <category label="edge" term="edge"/>
        <category label="use-case" term="use-case"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[ArgoCD + Kubevela Integration]]></title>
        <id>https://kubevela.io/blog/2023/01/06/kubevela-argocd-integration/</id>
        <link href="https://kubevela.io/blog/2023/01/06/kubevela-argocd-integration/"/>
        <updated>2023-01-06T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This document aims to explain the integration of Kubevela and ArgoCD. We have two approaches to integrate this flow. This doc is trying to explain the pros and cons of two different approaches]]></summary>
        <content type="html"><![CDATA[<p>This document aims to explain the integration of Kubevela and ArgoCD. We have two approaches to integrate this flow. This doc is trying to explain the pros and cons of two different approaches. Before diving deep into details, we can describe Kubevela and ArgoCD.</p>
<p>KubeVela is a modern software delivery platform that makes deploying and operating applications across multi environments easier, faster, and more reliable.</p>
<p>KubeVela is infrastructure agnostic and <strong>application-centric</strong>. It allows you to build robust software and deliver them anywhere! Kubevela provides an Open Application Model (OAM) based abstraction approach to ship applications and any resource across multiple environments.</p>
<p>Open Application Model (OAM) is a set of standard yet higher-level abstractions for modeling cloud-native applications on top of today’s hybrid and multi-cloud environments. You can find more conceptual details here.</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token key atrule">apiVersion</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> core.oam.dev/v1beta1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> Application</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">metadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> first</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">vela</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">app</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">spec</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">components</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> express</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">server</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> webservice</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">image</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> oamdev/hello</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">world</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">ports</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">         </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">port</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token number">8000</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">           </span><span class="token key atrule">expose</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token boolean important">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">traits</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> scaler</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token key atrule">replicas</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token number">1</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="argocd">ArgoCD<a href="https://kubevela.io/blog/2023/01/06/kubevela-argocd-integration/#argocd" class="hash-link" aria-label="Direct link to ArgoCD" title="Direct link to ArgoCD" translate="no">​</a></h3>
<p>Argo CD is a declarative continuous delivery tool for Kubernetes applications.
It uses the GitOps style to create and manage Kubernetes clusters. When any changes are made to the application configuration in Git, Argo CD will compare it with the configurations of the running application and notify users to bring the desired and live state into sync.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="flux">Flux<a href="https://kubevela.io/blog/2023/01/06/kubevela-argocd-integration/#flux" class="hash-link" aria-label="Direct link to Flux" title="Direct link to Flux" translate="no">​</a></h3>
<p>By default, Kubevela works with Flux addon to complete the Gitops journey for applications. You need to enable the flux addon and perform git operations quickly. <a href="https://kubevela.io/docs/end-user/gitops/fluxcd" target="_blank" rel="noopener noreferrer" class="">https://kubevela.io/docs/end-user/gitops/fluxcd</a>.</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela addon enable fluxcd</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="integration-with-argocd">Integration with ArgoCD<a href="https://kubevela.io/blog/2023/01/06/kubevela-argocd-integration/#integration-with-argocd" class="hash-link" aria-label="Direct link to Integration with ArgoCD" title="Direct link to Integration with ArgoCD" translate="no">​</a></h2>
<p>If you want to use Kubevela with ArgoCD, there are two options to enable it.</p>
<ul>
<li class="">Kubevela dry-run option</li>
<li class="">Kubevela + ArgoCD Gitops syncer mode</li>
</ul>
<h1>1. Vela dry-run approach</h1>
<p>First approach is that without using Kubevela GitOps Controller, we can use ArgoCD as the GitOps Controller, which means ArgoCD applies a raw manifest to the target cluster. Kubevela provides us to export oam application components and traits to native Kubernetes resource therefore we can still use OAM based model and ArgoCD can manage resources with custom argo-repo-server plugin. Behind this approach that KubeVela and OAM can also works as a client side tool with the feature dry-run.</p>
<p>This part describe how ArgoCD apply dry-run mode on Kubevela resources. Firstly, ArgoCD and Kubevela same should be installed.</p>
<p>ArgoCD version v2.5.4</p>
<p>Kubevela version v1.6.4</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="prerequisites">Prerequisites<a href="https://kubevela.io/blog/2023/01/06/kubevela-argocd-integration/#prerequisites" class="hash-link" aria-label="Direct link to Prerequisites" title="Direct link to Prerequisites" translate="no">​</a></h3>
<p>Argo CD allows integrating more config management tools using config management plugins.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="1-write-the-plugin-configuration-file">1. Write the plugin configuration file<a href="https://kubevela.io/blog/2023/01/06/kubevela-argocd-integration/#1-write-the-plugin-configuration-file" class="hash-link" aria-label="Direct link to 1. Write the plugin configuration file" title="Direct link to 1. Write the plugin configuration file" translate="no">​</a></h3>
<p>Plugins will be configured via a ConfigManagementPlugin manifest located inside the plugin container.</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token key atrule">apiVersion</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> v1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> ConfigMap</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">metadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> vela</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">cmp</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">namespace</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> argocd</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">data</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">plugin.yaml</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">|</span><span class="token scalar string" style="color:rgb(255, 121, 198)"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token scalar string" style="color:rgb(255, 121, 198)">    apiVersion: argoproj.io/v1alpha1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token scalar string" style="color:rgb(255, 121, 198)">    kind: ConfigManagementPlugin</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token scalar string" style="color:rgb(255, 121, 198)">    metadata:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token scalar string" style="color:rgb(255, 121, 198)">      name: vela</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token scalar string" style="color:rgb(255, 121, 198)">    spec:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token scalar string" style="color:rgb(255, 121, 198)">      version: v1.0</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token scalar string" style="color:rgb(255, 121, 198)">      init:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token scalar string" style="color:rgb(255, 121, 198)">        command: ["vela", "traits"]</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token scalar string" style="color:rgb(255, 121, 198)">      generate:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token scalar string" style="color:rgb(255, 121, 198)">        command: ["sh"]</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token scalar string" style="color:rgb(255, 121, 198)">        args:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token scalar string" style="color:rgb(255, 121, 198)">          - -c</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token scalar string" style="color:rgb(255, 121, 198)">          - |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token scalar string" style="color:rgb(255, 121, 198)">            vela dry-run -f test-argo-oam.yml</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token scalar string" style="color:rgb(255, 121, 198)">      discover:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token scalar string" style="color:rgb(255, 121, 198)">        # fileName: "-oam.yml*"</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token scalar string" style="color:rgb(255, 121, 198)">        find:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token scalar string" style="color:rgb(255, 121, 198)">          # This does the same thing as fileName, but it supports double-start (nested directory) glob patterns.</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token scalar string" style="color:rgb(255, 121, 198)">          glob: "**/*oam*.yml"</span><br></span></code></pre></div></div>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">kubectl apply -f vela-cmp.yml</span><br></span></code></pre></div></div>
<p>This plugin is responsible for converting Kubevela OAM manifest definition to raw kubernetes object and ArgoCD should be responsible to deploy.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="2-register-the-plugin-sidecar">2. Register the plugin sidecar<a href="https://kubevela.io/blog/2023/01/06/kubevela-argocd-integration/#2-register-the-plugin-sidecar" class="hash-link" aria-label="Direct link to 2. Register the plugin sidecar" title="Direct link to 2. Register the plugin sidecar" translate="no">​</a></h3>
<p>To install a plugin, patch argocd-repo-server to run the plugin container as a sidecar, with argocd-cmp-server as its entrypoint.</p>
<p>Vela plugin runs the vela command to export manifest when the plugin is discovered on git manifest. Before initializing the plugin, we need to install Kubevela CLI to run the order successfully. The below configuration adds an init container to download the necessary CLI.</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token key atrule">initContainers</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> kubevela</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">   </span><span class="token key atrule">image</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> nginx</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">1.21.6</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">   </span><span class="token key atrule">command</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> bash</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'-c'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">|</span><span class="token scalar string" style="color:rgb(255, 121, 198)"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token scalar string" style="color:rgb(255, 121, 198)">     #!/usr/bin/env bash</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token scalar string" style="color:rgb(255, 121, 198)">     set -eo pipefail</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token scalar string" style="color:rgb(255, 121, 198)">     curl -fsSl https://kubevela.io/script/install.sh | bash -s 1.6.4</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">   </span><span class="token key atrule">env</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> VELA_INSTALL_DIR</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">value</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> /custom</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">tools</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">   </span><span class="token key atrule">resources</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">limits</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">     </span><span class="token key atrule">cpu</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> 50m</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">     </span><span class="token key atrule">memory</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> 64Mi</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">requests</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">     </span><span class="token key atrule">cpu</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> 10m</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">     </span><span class="token key atrule">memory</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> 32Mi</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">   </span><span class="token key atrule">volumeMounts</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> custom</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">tools</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">mountPath</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> /custom</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">tools</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">   </span><span class="token key atrule">terminationMessagePath</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> /dev/termination</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">log</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">   </span><span class="token key atrule">terminationMessagePolicy</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> File</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">   </span><span class="token key atrule">imagePullPolicy</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> IfNotPresent</span><br></span></code></pre></div></div>
<p>after adding init container, we need to add our custom sidecar binary to run plugins properly. To use configmap plugin configuration in our sidecar, we need to mount configmap plugin to our pods</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token key atrule">containers</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> vela</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">image</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> nginx</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">command</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> /var/run/argocd/argocd</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">cmp</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">server</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">env</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> KUBECONFIG</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">              </span><span class="token key atrule">value</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> /kubeconfig</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">resources</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">volumeMounts</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> var</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">files</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">              </span><span class="token key atrule">mountPath</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> /var/run/argocd</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> vela</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">cli</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">dir</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">              </span><span class="token key atrule">mountPath</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> /.vela</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> kubeconfig</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">              </span><span class="token key atrule">mountPath</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> /kubeconfig</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">              </span><span class="token key atrule">subPath</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> kubeconfig</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> plugins</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">              </span><span class="token key atrule">mountPath</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> /home/argocd/cmp</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">server/plugins</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> vela</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">cmp</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">              </span><span class="token key atrule">mountPath</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> /home/argocd/cmp</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">server/config/plugin.yaml</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">              </span><span class="token key atrule">subPath</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> plugin.yaml</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> cmp</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">tmp</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">              </span><span class="token key atrule">mountPath</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> /tmp</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> custom</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">tools</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">              </span><span class="token key atrule">mountPath</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> /usr/local/bin/vela</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">              </span><span class="token key atrule">subPath</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> vela</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="3-configure-argo-cd-to-watch-this-repo-for-git-pushes">3. Configure Argo CD to watch this repo for Git pushes.<a href="https://kubevela.io/blog/2023/01/06/kubevela-argocd-integration/#3-configure-argo-cd-to-watch-this-repo-for-git-pushes" class="hash-link" aria-label="Direct link to 3. Configure Argo CD to watch this repo for Git pushes." title="Direct link to 3. Configure Argo CD to watch this repo for Git pushes." translate="no">​</a></h3>
<p>Create git repository and put oam manifest to target directory after you can create a simple ArgoCD application that watch git repository and apply manifests to local kubernetes cluster.</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token key atrule">apiVersion</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> core.oam.dev/v1beta1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> Application</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">metadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> test</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token number">2</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">spec</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">components</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> wf</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">poc</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">app</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token number">2</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> webservice</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">image</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> oamdev/helloworld</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">python</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">v1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">env</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"TARGET"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token key atrule">value</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"ArgoCD"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">port</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token number">8080</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="4-final-output">4. Final Output<a href="https://kubevela.io/blog/2023/01/06/kubevela-argocd-integration/#4-final-output" class="hash-link" aria-label="Direct link to 4. Final Output" title="Direct link to 4. Final Output" translate="no">​</a></h3>
<p>ArgoCD synced applications successfully and rendered kubernetes resources.</p>
<p><img decoding="async" loading="lazy" src="https://miro.medium.com/max/1400/0*noBT6sj-0K-DQ3PB" alt="img" class="img_ev3q"></p>
<h1>2. Kubevela Controller + ArgoCD Gitops syncer</h1>
<p>Second approach is that we can use Kubevela gitops controller way as the server side and argocd can be our gitops syncer. This approach is flexible to use native kubevela feature set without using a custom plugin or dry run module. We just need to add below annotations to our manifest repository to ignore outofsync.</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">argocd.argoproj.io/compare-options: IgnoreExtraneous</span><br></span></code></pre></div></div>
<p>In this example, ArgoCD tracks native Kubevela application resources and its revision.</p>
<p><img decoding="async" loading="lazy" src="https://miro.medium.com/max/1400/0*97AatDKE2fC5wQdX" alt="img" class="img_ev3q"></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="conclusion">Conclusion<a href="https://kubevela.io/blog/2023/01/06/kubevela-argocd-integration/#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion" translate="no">​</a></h2>
<p><strong>1. Vela Dry-run approach</strong></p>
<ul>
<li class="">Kubevela can be installed different cluster from ArgoCD.</li>
<li class="">Limited Kubevela features, we just use component and traits definition.</li>
<li class="">Workflow and policy features don’t supported by this way.</li>
<li class="">Depend on Kubevela dry run feature.</li>
<li class="">No needed rbac, ui or any different experience from ARGO.</li>
</ul>
<p><strong>2. Kubevela Controller + ArgoCD Gitops syncer</strong></p>
<ul>
<li class="">Kubevela must be installed to ArgoCD cluster.</li>
<li class="">We can use all the features of Kubevela.</li>
<li class="">No need depends on anything.</li>
</ul>
<p>Reference: <a href="https://gokhan-karadas1992.medium.com/argocd-kubevela-integration-eb88dc0484e0" target="_blank" rel="noopener noreferrer" class="">https://gokhan-karadas1992.medium.com/argocd-kubevela-integration-eb88dc0484e0</a></p>
<p>Big thanks to <a href="https://github.com/erkanzileli" target="_blank" rel="noopener noreferrer" class="">Erkan Zileli</a> 🎉🎉🎉</p>]]></content>
        <author>
            <name>Gokhan Karadas</name>
            <uri>https://github.com/previousdeveloper</uri>
        </author>
        <category label="KubeVela" term="KubeVela"/>
        <category label="Argo" term="Argo"/>
        <category label="IDP" term="IDP"/>
        <category label="OAM" term="OAM"/>
        <category label="CD" term="CD"/>
        <category label="GitOps" term="GitOps"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[A retrospection of KubeVela in 2022]]></title>
        <id>https://kubevela.io/blog/2022/11/29/retro-2022/</id>
        <link href="https://kubevela.io/blog/2022/11/29/retro-2022/"/>
        <updated>2022-11-29T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This article gives a comprehensive introduction to KubeVela in 2022.]]></summary>
        <content type="html"><![CDATA[<blockquote>
<p>Since Open Application Model invented in 2020, KubeVela has experienced tens of version changes and evolves advanced features towards modern application delivery. Recently, KubeVela has proposed to become a CNCF incubation project and delivered several public talks in the community. As a memorandum, this article will look back into the starting points and give a comprehensive introduction to the state of KubeVela in 2022.</p>
</blockquote>
<p>KubeVela is a modern software platform that makes delivering and operating applications across today's hybrid, multi-cloud environments easier, faster and more reliable. It has three main features:</p>
<ul>
<li class="">Infrastructure agnotic: KubeVela is able to deploy your cloud-native application into various destinations, such as Kubernetes multi-clusters, cloud provider runtimes (like Alibaba Cloud, AWS or Azure) and edge devices.</li>
<li class="">Programmable: KubeVela has abstraction layers for modeling applications and delivery process. The abstraction layers allow users to use programmable ways to build higher level reusable modules for application delivery and integrate arbitrary third-party projects (like FluxCD, Crossplane, Istio, Prometheus) in the KubeVela system.</li>
<li class="">Application-centric: There are rich tools and eco-systems designed around the KubeVela applications, which add extra capabilities for deliverying and operating the applications, including CLI, UI, GitOps, Observability, etc.</li>
</ul>
<p>KubeVela cares the whole lifecycle of the applications, including both the Day-1 Delivery and the Day-2 Operating stages. It is able to connect with a wide range of Continuous Integration tools, like Jenkins or GitLab CI, and help users deliver and operate applications across hybrid environments.
<img decoding="async" loading="lazy" alt="Slide2.png" src="https://kubevela.io/assets/images/Slide2-e5baa97fc6bfeb71d26604528e09e195.png" width="1920" height="1080" class="img_ev3q"></p>
<h1>Why KubeVela?</h1>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="challenges-and-difficulties">Challenges and Difficulties<a href="https://kubevela.io/blog/2022/11/29/retro-2022/#challenges-and-difficulties" class="hash-link" aria-label="Direct link to Challenges and Difficulties" title="Direct link to Challenges and Difficulties" translate="no">​</a></h2>
<p>Nowadays, the fast growing of the cloud native infrastructures has given more and more capabilities for users to deploying applications, such as High Availability and Security, but also exposes an increase number of complexities directly to application developers.
For example, the Ingress resource on Kubernetes enables users to expose their applications easily, but developers need to handle the Ingress upgrades when the underlying Kubernetes version shifts, which requires knowledges for the Ingress resource. The hybrid deployment across various cloud provides can make this problem even harder.
These difficulties are caused by the lack of operational input in the application definition and developers must face the infrastructure details directly if they want to enjoy the benefits brought by the rich cloud-native community.
<img decoding="async" loading="lazy" alt="Slide3.png" src="https://kubevela.io/assets/images/Slide3-447f7fa406637b4c370d33d12bdbf144.png" width="1920" height="1080" class="img_ev3q"></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="open-application-model">Open Application Model<a href="https://kubevela.io/blog/2022/11/29/retro-2022/#open-application-model" class="hash-link" aria-label="Direct link to Open Application Model" title="Direct link to Open Application Model" translate="no">​</a></h2>
<p>To tackle the above challenges and bridge the gap between the use of applications and the understanding of infrasturcture details, Open Application Model (OAM) is jointly proposed by Alibaba Cloud and Microsoft Azure in 2020. The aim is to define a consistent application model for application delivery, irrelevant with the platforms and implementations.
The defined application model describes an interface for developers on what an application consists of and how it should work. The former one is known as Component in OAM, which is usually used to model the workloads of the application. The latter one is defined as Trait in OAM, which attaches extra capabilities to Components.
<img decoding="async" loading="lazy" alt="Slide4.png" src="https://kubevela.io/assets/images/Slide4-6de056f46c8056e073351f609b43499b.png" width="1920" height="1080" class="img_ev3q"></p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="kubevela-as-oam">KubeVela as OAM<a href="https://kubevela.io/blog/2022/11/29/retro-2022/#kubevela-as-oam" class="hash-link" aria-label="Direct link to KubeVela as OAM" title="Direct link to KubeVela as OAM" translate="no">​</a></h3>
<p>KubeVela is one of the implementations for the Open Application Model. In KubeVela, the abstraction layer is powered by CUE, a novel configuration programming language which can describe complex rendering logics and work as a superset of JSON.
The abstraction layer simplifies the configuration of resources in Kubernetes, which hides the details of implementations and exposes limited parameters to the front developers. With KubeVela application, it is easy for developers to focus on the centric logic of applications, like what container image should be used and how the service should be made accessible.
<img decoding="async" loading="lazy" alt="Slide5.png" src="https://kubevela.io/assets/images/Slide5-a54b840cdea6f9120160a750422c087c.png" width="1920" height="1080" class="img_ev3q">
To achieve that, best practices of using Kubernetes native resources are summarized into KubeVela X-Definitions, which provide rendering templates of resources using CUE. These templates can be accessed from various sources, including official repositories, community addons or even self customized implementations by system operators. The templates are mostly infrastructure implemetation agnostic, in other words, not necessarily bond to specific infrastructures. The developers do not need to be aware of the underlying infra when using these templates.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="components--traits">Components &amp; Traits<a href="https://kubevela.io/blog/2022/11/29/retro-2022/#components--traits" class="hash-link" aria-label="Direct link to Components &amp; Traits" title="Direct link to Components &amp; Traits" translate="no">​</a></h3>
<p>The application model divides the abstraction of infra into two different aspects. The Component describes the main workload, which particularly in Kubernetes can be Deployments, StatefulSets, Helm Releases, etc. The Trait on the other hands, describes the added capability for the main workload, such as the scaler trait specifying the number of replicas and the gateway trait aggregates the endpoints for access. The separation of concerns in the design of Component and Trait give high extensibility and reusability to the abstraction.
<img decoding="async" loading="lazy" alt="Slide6.png" src="https://kubevela.io/assets/images/Slide6-bb6b7500ac01ddb008102625b905ca08.png" width="1920" height="1080" class="img_ev3q">
For example, the gateway trait could be backended by different infrastructures like Ingress or HTTPRoute. The application developer who uses the trait only needs to care about the exposed parameters, including the path, port and domain. The trait can be attached to various types of workloads, abstracted by different types of components, such as Deployment, StatefulSet, CloneSet, etc.
<img decoding="async" loading="lazy" alt="Slide7.png" src="https://kubevela.io/assets/images/Slide7-0c9a09653aaa08a3b45ae60ea87d49ac.png" width="1920" height="1080" class="img_ev3q">
In the cases where application developers and SRE are in the different teams, KubeVela makes clear division for their responsibilities.</p>
<ul>
<li class="">The platform team providing infrastructures, are responsible to build up X-Definitions where they enforce best practices and deployment confidence.</li>
<li class="">The end users only need to choose the Component and Trait provided by the platform team and use them to assemble applications. They can simply enjoy PaaS-like experiences instead of directly interacting with the infra behind.</li>
</ul>
<p>These are made possible thanks to the flexible, extensible and programmable system of KubeVela and can be applied under varying environments.
<img decoding="async" loading="lazy" alt="Slide8.png" src="https://kubevela.io/assets/images/Slide8-b73a808e8a7b3d8e29917f8acfb8385f.png" width="1920" height="1080" class="img_ev3q"></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="unified-delivery">Unified Delivery<a href="https://kubevela.io/blog/2022/11/29/retro-2022/#unified-delivery" class="hash-link" aria-label="Direct link to Unified Delivery" title="Direct link to Unified Delivery" translate="no">​</a></h2>
<p>Application delivery could happen everywhere. Therefore, another goal for KubeVela application is to build up unified delivery and provide consistent usage for users under various scenarios.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="hybrid-cloud--multi-cluster">Hybrid-Cloud &amp; Multi-Cluster<a href="https://kubevela.io/blog/2022/11/29/retro-2022/#hybrid-cloud--multi-cluster" class="hash-link" aria-label="Direct link to Hybrid-Cloud &amp; Multi-Cluster" title="Direct link to Hybrid-Cloud &amp; Multi-Cluster" translate="no">​</a></h3>
<p>In addition to the abstraction layer, KubeVela also supports hybrid-cloud or multi-cluster architecture natively as modern cloud native applications are not only about containers but involves lots of cloud resources as well. Besides, more and more users and teams start facing the difficulties of deliverying applications to various environments or multi-clusters for different purposes, such as testing or high availability.
<img decoding="async" loading="lazy" alt="Slide9.png" src="https://kubevela.io/assets/images/Slide9-9898f7e3a145bf29befa4f96190a02ac.png" width="1920" height="1080" class="img_ev3q">
The KubeVela application allows user to define delivery targets and differentiated configurations through policies. The abstraction helps hide the details of how clusters are registered and connected and provide runtime-agnostic usages to app developers.
<img decoding="async" loading="lazy" alt="Slide10.png" src="https://kubevela.io/assets/images/Slide10-56d1ba92bd7ab679cf1ac654d56c0a90.png" width="1920" height="1080" class="img_ev3q"></p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="addon-integration">Addon Integration<a href="https://kubevela.io/blog/2022/11/29/retro-2022/#addon-integration" class="hash-link" aria-label="Direct link to Addon Integration" title="Direct link to Addon Integration" translate="no">​</a></h3>
<p>To enrich the delivery capability, users can leverage KubeVela addons to make extensions to their system. The addons are discoverable, reusable and easy-to-install capability bundles. They usually contain capability providers, including a wide range of third-party projects, like FluxCD, ClickHouse, Crossplane, etc. Addons not only install those projects into the system but create corresponding definitions for the integration concurrently, which extends the types of Component and Trait that application developers are able to use.
The KubeVela community currently have 50+ addons already. Platform builders could enjoy these out-of-box integrations in systems depending on their customized demands.
<img decoding="async" loading="lazy" alt="Slide11.png" src="https://kubevela.io/assets/images/Slide11-e5e424ca3b80f9bcd42fafbb40f6e7ea.png" width="1920" height="1080" class="img_ev3q"></p>
<p>With addons enabled in the system, it would be possible for end users to assemble applications in more customized ways, such as deploying cloud resources or using advanced workloads.
<img decoding="async" loading="lazy" alt="Slide12.png" src="https://kubevela.io/assets/images/Slide12-c20da940a5fd5d41db82e8fa64184c39.png" width="1920" height="1080" class="img_ev3q"></p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="kubevela-workflow">KubeVela Workflow<a href="https://kubevela.io/blog/2022/11/29/retro-2022/#kubevela-workflow" class="hash-link" aria-label="Direct link to KubeVela Workflow" title="Direct link to KubeVela Workflow" translate="no">​</a></h3>
<p>While the Open Application Model defines the composition of an application, in real cases, the delivery process of the compositions could still vary a lot. For example, the different components in one application could have inter dependencies or data passing where delivery steps must be executed in specific order. Furthermore, the delivery process sometimes also involves more actions apart from the delivery of resources, such as rollouts or notifications.
An extensible workflow is therefore designed to fulfill the needs of the process customization in KubeVela.
<img decoding="async" loading="lazy" alt="Slide13.png" src="https://kubevela.io/assets/images/Slide13-71561c9092d16c4ed7cc9e3afd9f829c.png" width="1920" height="1080" class="img_ev3q">
Similar to Component and Trait, KubeVela workflow also leverages CUE to define workflow steps, providing flexibility, extensibility and programmability. It can be seen as another form of Infrastructure as Code (IaC).
A bunch of build-in workflow steps has already provided rich out-of-box capabilities in KubeVela, such as making multi-cluster deployments and sending notifications through slack or email. The lightweight engine ensures the high performance and safety of step executions, compared to other types of engines involving running extra containers.
<img decoding="async" loading="lazy" alt="Slide14.png" src="https://kubevela.io/assets/images/Slide14-57b1e06c7fabdf3679d2884cc75739c4.png" width="1920" height="1080" class="img_ev3q">
Differ from the Component and Trait definitions in KubeVela, the WorkflowStep definition does not render templates into resources. Instead, it describes the actions to be executed in the step, which calls underlying atomic functions in various providers.
<img decoding="async" loading="lazy" alt="Slide15.png" src="https://kubevela.io/assets/images/Slide15-fa3ecfed8e7c842f6edc43061bc5f647.png" width="1920" height="1080" class="img_ev3q">
With the use of workflow and addons, users are able to build arbitrary delivery process and make customized integrations. For example, it is possible to let the Continuous Integration tools to trigger the delivery of KubeVela applications and implement the GitOps solutions combining FluxCD and other addons.
<img decoding="async" loading="lazy" alt="Slide16.png" src="https://kubevela.io/assets/images/Slide16-a8d2f6342cda2423e83a79f167b49670.png" width="1920" height="1080" class="img_ev3q"></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="day-2-management">Day-2 Management<a href="https://kubevela.io/blog/2022/11/29/retro-2022/#day-2-management" class="hash-link" aria-label="Direct link to Day-2 Management" title="Direct link to Day-2 Management" translate="no">​</a></h2>
<p>KubeVela cares more other than Day-1 Delivery. It also provides a unified Day-2 application management capability for all it's extensibility. The day-2 management is necessary for system operators and application developers to make continuous operation for the delivered applications and ensure the applications are always under control.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="resource-management">Resource Management<a href="https://kubevela.io/blog/2022/11/29/retro-2022/#resource-management" class="hash-link" aria-label="Direct link to Resource Management" title="Direct link to Resource Management" translate="no">​</a></h3>
<p>The basic capabilities for application management are for its resources.
KubeVela's core controller continuously watches the difference between the current state and the desired state of delivered resources. It makes sure that the live spec is accord with the declared spec recorded in the delivery process and therefore effectively prevents any configuration drifts.
<img decoding="async" loading="lazy" alt="Slide18.png" src="https://kubevela.io/assets/images/Slide18-353bc3b750d593441d3cb5ea1bf4b939.png" width="1920" height="1080" class="img_ev3q">
Besides, the automated garbage collection help recycle the resources that are not in-use during upgrades or deletion. There are also times resources need to be shared across multiple applications. These are all made possible in KubeVela application through the use of policies.
<img decoding="async" loading="lazy" alt="Slide19.png" src="https://kubevela.io/assets/images/Slide19-56b70c39817f8198593159556f892737.png" width="1920" height="1080" class="img_ev3q"></p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="version-control">Version Control<a href="https://kubevela.io/blog/2022/11/29/retro-2022/#version-control" class="hash-link" aria-label="Direct link to Version Control" title="Direct link to Version Control" translate="no">​</a></h3>
<p>KubeVela application keeps history records for deliveries. These snapshots are useful when new version publish are out of expectations. The change inspectation could be used to diagnose the possible error changes and the rollback allows fast recovery to the previous successful states.
<img decoding="async" loading="lazy" alt="Slide20.png" src="https://kubevela.io/assets/images/Slide20-5cd39e2d6b9aab1b6207d4bf27eced4a.png" width="1920" height="1080" class="img_ev3q"></p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="observability">Observability<a href="https://kubevela.io/blog/2022/11/29/retro-2022/#observability" class="hash-link" aria-label="Direct link to Observability" title="Direct link to Observability" translate="no">​</a></h3>
<p>KubeVela treats observability as first class citizen. It is the eyes to users for monitoring the state of applications and observing exceptions.
There are multiple tools and methods in KubeVela to do the observation job. One of the most straightforward way is to use the CLI tool of KubeVela. The Vela CLI is able to provide in-time status info for the application in fine-grain or aggregated level.
<img decoding="async" loading="lazy" alt="Slide21.jpg" src="https://kubevela.io/assets/images/Slide21-b7471b95e78e4bd8f259b39e7d51a4c0.jpg" width="2560" height="1440" class="img_ev3q">
For users that prefer web interfaces, VelaUX provides an alternative way to view application status.
<img decoding="async" loading="lazy" alt="Slide22.png" src="https://kubevela.io/assets/images/Slide22-909fa5fe4325f91e19d045acc5dfc980.png" width="1920" height="1080" class="img_ev3q">
In the cases applications are monitored through third-party projects, such as Grafana, Prometheus or Loki, KubeVela further provides addons for bootstrapping the observability infrastructures and empower users to customize the observing rules as codes in applications, through the abstraction layer.
<img decoding="async" loading="lazy" alt="Slide23.png" src="https://kubevela.io/assets/images/Slide23-f5d120b777d9c6ecf48efa8dfcaf9457.png" width="1920" height="1080" class="img_ev3q">
A series of out-of-box metrics and dashboards give users the basic capability of automated system observability. These can be used to diagnose system level exceptions and help improve the overall performance.
<img decoding="async" loading="lazy" alt="Slide24.png" src="https://kubevela.io/assets/images/Slide24-dcc83aaa0f146dad0a841f7dd3518cf8.png" width="1920" height="1080" class="img_ev3q"></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="eco-system">Eco-system<a href="https://kubevela.io/blog/2022/11/29/retro-2022/#eco-system" class="hash-link" aria-label="Direct link to Eco-system" title="Direct link to Eco-system" translate="no">​</a></h2>
<p>In addition to the above mentioned tools, KubeVela also has several other tools in the eco-systems to facilitate application delivery.</p>
<ul>
<li class="">Vela CLI: KubeVela CLI provides various commands that helps you to operate applications, such as managing definitions, viewing resources, restarting workflow, rolling versions.</li>
<li class="">VelaUX: VelaUX is the Web UI for KubeVela. Besides, it incorporates business logics into fundamental APIs and provides out-of-box user experiences for non-k8s-expert users.</li>
<li class="">Terraform Controller: The terraform controller in KubeVela allows users to use Terraform to manage cloud resources through Kubernetes Custom Resources.</li>
<li class="">Cluster Gateway: The gateway that provides unified multi-cluster access interface. Working as Kubernetes Aggregated API Server, the gateway leverages the native Authentication and Authorization modules and enforces secure and transparent access to managed clusters.</li>
<li class="">VelaD: Building on top of k3s &amp; k3d, VelaD integrates KubeVela with Kubernetes cores, which can be extremely helpful for building dev/test environment.</li>
<li class="">Vela Prism: The extension API server for KubeVela built upon the Kubernetes Aggregated API Server. It projects native APIs like creating dashboards on Grafana into Kubernetes resource APIs, so that users can manage 3rd-party resources as Kubernetes native resources.</li>
<li class="">Vela Workflow: The workflow engine translates CUE-based steps and executes them. It works as a pure delivery tool and can be used aside by the KubeVela application. Compared to Tekton, it mainly organize the process in CUE style, instead of using Pods and Jobs directly.</li>
</ul>
<p><img decoding="async" loading="lazy" alt="Slide25.png" src="https://kubevela.io/assets/images/Slide25-e5d94cbaceb729fe27bc5bd8f12195c7.png" width="1920" height="1080" class="img_ev3q"></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="stability">Stability<a href="https://kubevela.io/blog/2022/11/29/retro-2022/#stability" class="hash-link" aria-label="Direct link to Stability" title="Direct link to Stability" translate="no">​</a></h2>
<p>To ensure KubeVela is able to handle certain amount of applications under limited resources, multiple load testings have been conducted under various circumstances. The experiments have demonstrated that the performance of KubeVela system is capable of dealing thousands of applications in an ordinary-sized cluster. The observability infrastructure further exposes the bottleneck of KubeVela and guides system operators to do customized tunning to improve the performance in specific use environments.<img decoding="async" loading="lazy" alt="Slide26.png" src="https://kubevela.io/assets/images/Slide26-70e1c27dcd7247eecbb659f1d3aa7f4b.png" width="1920" height="1080" class="img_ev3q"></p>
<h1>In a nutshell</h1>
<p>Currently, KubeVela has already been applied in production by a number of adopters from various areas. Some mainly use KubeVela's abstraction capability to simplify the use and deploy of applications. Some build application-centric management system upon KubeVela. Some use the customized workflow to orchestrate the delivery process. It is especially welcomed in high-tech industries and shown to be helpful for delivering and managing enourmous applications.</p>
<h1><img decoding="async" loading="lazy" alt="Slide27.png" src="https://kubevela.io/assets/images/Slide27-a91f0005c7c97eed7920289a14f896d5.png" width="1920" height="1080" class="img_ev3q"></h1>
<p>The KubeVela community has attracted world-wide contributors and continuously evolves over the past two years. Nowadays, there are over 200 contributors from various contries have participated in the developing of KubeVela. Thousands of issues have been raised and 85% of them are already solved. There are also bi-weekly community meetings held in both English and Chinese community.</p>
<h1><img decoding="async" loading="lazy" alt="Slide28.png" src="https://kubevela.io/assets/images/Slide28-254b4f2cf0543c344c7fe3186d1d5259.png" width="1920" height="1080" class="img_ev3q"></h1>
<p>With more and more people coming into the community, KubeVela is consistently upgrading itself to fit into more complex, varying use cases and scenarios.</p>]]></content>
        <author>
            <name>Da Yin</name>
            <uri>https://github.com/Somefive</uri>
        </author>
        <category label="KubeVela" term="KubeVela"/>
        <category label="Kubernetes" term="Kubernetes"/>
        <category label="DevOps" term="DevOps"/>
        <category label="CNCF" term="CNCF"/>
        <category label="CI/CD" term="CI/CD"/>
        <category label="Application delivery" term="Application delivery"/>
        <category label="Open Application Model" term="Open Application Model"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Deploying your OAM applications in the Napptive cloud-native application platform]]></title>
        <id>https://kubevela.io/blog/2022/11/24/napptive-kubevela/</id>
        <link href="https://kubevela.io/blog/2022/11/24/napptive-kubevela/"/>
        <updated>2022-11-24T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This article introduces how KubeVela is applied in Napptive to build cloud-native application platform.]]></summary>
        <content type="html"><![CDATA[<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="application-delivery-on-kubernetes">Application Delivery on Kubernetes<a href="https://kubevela.io/blog/2022/11/24/napptive-kubevela/#application-delivery-on-kubernetes" class="hash-link" aria-label="Direct link to Application Delivery on Kubernetes" title="Direct link to Application Delivery on Kubernetes" translate="no">​</a></h2>
<p>The cloud-native landscape is formed by a fast-growing ecosystem of tools with the aim of improving the development of modern applications in a cloud environment. Kubernetes has become the de facto standard to deploy enterprise workloads by improving development speed, and accommodating the needs of a dynamic environment.</p>
<p>Kubernetes offers a comprehensive set of entities that enables any potential application to be deployed into it, independent of its complexity. This however has a significant impact from the point of view of its adoption. Kubernetes is becoming as complex as it is powerful, and that translates into a steep learning curve for newcomers into the ecosystem. Thus, this has generated a new trend focused on providing developers with tools that improve their day-to-day activities without losing the underlying capabilities of the underlying system.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="napptive-application-platform">Napptive Application Platform<a href="https://kubevela.io/blog/2022/11/24/napptive-kubevela/#napptive-application-platform" class="hash-link" aria-label="Direct link to Napptive Application Platform" title="Direct link to Napptive Application Platform" translate="no">​</a></h2>
<p>The NAPPTIVE Playground offers a cloud native application platform focused on providing a simplified method to operate on Kubernetes clusters and deploy complex applications without needing to work with low-level Kubernetes entities. This is especially important to be able to accommodate non-developer users' personas as the computing resources of a company are being consolidated in multi-purpose, multi-tenant clusters. Data scientists, business analysts, modeling experts and many more can benefit from simple solutions that do not require any type of knowledge of cloud computing infrastructures, or orchestration systems such as Kubernetes, which enable them to run their applications with ease in the existing infrastructure.</p>
<p>Any tool that works in this space must start by analyzing the existing abstractions. In particular, at Napptive, we focus on the Applications. This quite understood abstraction is not present in Kubernetes, requiring users to manually tag, identify and reason about the different components involved in an application. The Open Application Model provides an excellent abstraction to represent any type of application independently of the cloud provider, containerization technology, or deployment framework. The model is highly customizable by means of adding Traits, Policies, or new Component Definitions.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="kubevela-in-napptive">KubeVela in Napptive<a href="https://kubevela.io/blog/2022/11/24/napptive-kubevela/#kubevela-in-napptive" class="hash-link" aria-label="Direct link to KubeVela in Napptive" title="Direct link to KubeVela in Napptive" translate="no">​</a></h2>
<p>The Napptive Playground leverages Kubevela as the OAM runtime for Kubernetes deployments. Our Playground provides an environment abstraction with multi-tenant guarantees that is equivalent to partitioning a shared cluster by means of differentiated namespaces. The benefit of our approach is the transparency of its configuration using a higher abstraction level that does not involve any Kubernetes knowledge.</p>
<p>The following diagram describes the overall architecture of Napptive and Kubevela deployed in a Kubernetes cluster.</p>
<p><img decoding="async" loading="lazy" alt="napptive-arch" src="https://kubevela.io/assets/images/kubevela-napptive-1-d51e958ce512fafbdff8686f9cf9ab1f.png" width="941" height="525" class="img_ev3q"></p>
<p>The user has the ability to interact with the cluster by using the Napptive user interface (CLI or Web UI), or by means of using the standard Kubernetes API with kubectl. Isolated environments can be easily created to establish the logical separations such as type of environment (e.g., deployment, staging, production), or purpose (e.g., projectA, projectB), or any other approach to differentiate where to deploy an application. Once the OAM application is deployed on Kubernetes, Kubevela is in charge of managing the low-level application lifecycle creating the appropriate Kubernetes entities as a result. One of the main differences with other adopters of Kubevela, is the fact that we use Kubevela in a multi-tenant environment. The following figure shows the specifics of an application deployment in this type of scenario.</p>
<p><img decoding="async" loading="lazy" alt="napptive-arch" src="https://kubevela.io/assets/images/kubevela-napptive-2-f7ea866e8ca26db29edc4da13930d41f.png" width="941" height="525" class="img_ev3q"></p>
<p>The Napptive Playground is integrated with Kubernetes RBAC and offers a native user management layer that works in both on-premise and cloud deployments. User identity is associated with each environment, and Kubevela is able to take that information to ensure that users can only access their allowed resources. Once a user deploys an OAM application, Kubevela will intercept the call and attach the user identity as an annotation. After that, the rendering process will ensure that the user has access to the entities (e.g., trait, component, policy, workflow step definitions) and that the target namespaces are also accessible by the user. Once the application render is ready, the workflow orchestrator will create the different entities in the Kubernetes namespace.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="napptive-in-the-community">Napptive in the Community<a href="https://kubevela.io/blog/2022/11/24/napptive-kubevela/#napptive-in-the-community" class="hash-link" aria-label="Direct link to Napptive in the Community" title="Direct link to Napptive in the Community" translate="no">​</a></h2>
<p>In terms of our involvement with the OAM/Kubevela community, it has evolved overtime from being passive members of the community simply exploring the possibilities of OAM in Kubernetes, to becoming active contributor members in different areas. In particular, we have closely worked with the core Kubevela development team to test and overcome the different challenges related to using a multi-tenant, RBAC compliance installation of Kubevela. Security in this type of installation is critical and it is one of our main focuses within the Kubevela community.  We are committed to continue working with the community not only to ensure that multi-tenancy is maintained throughout the different releases, but also to add our own perspective representing our customer use cases.</p>
<p>The Kubevela community is growing at a fast pace, and we try to contribute our adaptations, features, feedback, and thoughts back to the community. This type of framework is deployed in a multitude of environments. The most common one is probably where one or more clusters are inside a company. In our particular application, we are interested in exploring methods to offer computing capabilities for a variety of user personas in a shared cluster, and we contribute our view and experience in the community.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="future-evolution">Future Evolution<a href="https://kubevela.io/blog/2022/11/24/napptive-kubevela/#future-evolution" class="hash-link" aria-label="Direct link to Future Evolution" title="Direct link to Future Evolution" translate="no">​</a></h2>
<p>In terms of future evolution, we believe the Napptive Playground is a great tool to experience working with the Open Application Model without the need of installing new clusters and frameworks. From the point of view of our contributions in the community, we are internally working in exploring QA mechanisms that ensure that customer applications remain working after upgrades, and identifying potential incompatibilities between releases. Once that work is ready, we plan to contribute our testing environment setup back to the community so that it can be adopted in the main branch. We are also excited with new functionalities that have been recently added to Kubevela such as multi-cluster support, and are exploring methods to adopt it inside the Playground. Moreover, we are actively working on an OAM-compatible application catalog that will simplify the way organizations store and make accessible application definitions so that they can be deployed into a cluster from a central repository. The catalog focuses on the OAM entities and relies on existing container registries for storing the image.</p>]]></content>
        <author>
            <name>Daniel Higuero</name>
            <uri>https://github.com/dhiguero</uri>
        </author>
        <category label="KubeVela" term="KubeVela"/>
        <category label="Napptive" term="Napptive"/>
        <category label="Kubernetes" term="Kubernetes"/>
        <category label="DevOps" term="DevOps"/>
        <category label="Cloud Native" term="Cloud Native"/>
        <category label="CNCF" term="CNCF"/>
        <category label="Application delivery" term="Application delivery"/>
        <category label="Open Application Model" term="Open Application Model"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[KubeVela 1.6 released, a Cloud-Native Application Platform with United Delivery and Day-2 Management]]></title>
        <id>https://kubevela.io/blog/2022/11/10/release-1.6/</id>
        <link href="https://kubevela.io/blog/2022/11/10/release-1.6/"/>
        <updated>2022-11-10T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This article discusses the announcement of the latest KubeVela release(v1.6) during the 2022 Apsara Conference.]]></summary>
        <content type="html"><![CDATA[<p>The community has released the new milestone release v1.6 of KubeVela during the 2022 Apsara Conference. This release is a qualitative change in KubeVela from application delivery to application management. It also creates a precedent in the industry to build an application platform with delivery and management integrated based on a extensible model.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="background">Background<a href="https://kubevela.io/blog/2022/11/10/release-1.6/#background" class="hash-link" aria-label="Direct link to Background" title="Direct link to Background" translate="no">​</a></h2>
<p>With the advent of the cloud-native era, developers have to use more and more complex APIs to build cloud-native-compliant application architectures from powerful infrastructure and clouds. But it's difficult to use and has a high learning curve for app developers. This also brings great stability risks due to the direct operation of the underlying infrastructure. Kubernetes provides a unified API integration interface for the infrastructure, but it’s a <em>platform for platform developers</em>. The <em>application-centric</em> interface is missing for upper-level application developers. <strong>Open Application Model (OAM) has come into being to meet these requirements. It was jointly released by Alibaba and Microsoft in 2019. The two companies brought a lot of practical experience in cloud-native application development and provided a theoretical basis for building an application platform in the cloud-native era.</strong></p>
<p>After OAM was released, it was welcomed and adopted by many enterprises, including Oracle, Tencent, ByteDance, and 4Paradigm. However, for some enterprises, OAM is a theoretical model with no practical platforms that can be used directly. Thus, it is difficult to land. As a result, Alibaba Cloud engineers joined forces with enterprises that adopted OAM in the community and built an out-of-the-box OAM implementation engine based on common practice. Then, KubeVela was born.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="standard-and-extensible-application-delivery-engine">Standard and Extensible Application Delivery Engine<a href="https://kubevela.io/blog/2022/11/10/release-1.6/#standard-and-extensible-application-delivery-engine" class="hash-link" aria-label="Direct link to Standard and Extensible Application Delivery Engine" title="Direct link to Standard and Extensible Application Delivery Engine" translate="no">​</a></h2>
<p><strong>KubeVela was officially released in November 2020 and has always adhered to the design principles of flexibility, extensibility, and separation of concerns. The goal is to connect cloud-native technology components and enterprise-level applications to help developers in the enterprise quickly obtain an easy, secure, and reliable software delivery and management experience</strong>. Less than a year after becoming open-source, it has provided core features (such as multi-cluster unified orchestration, infrastructure independence, and application delivery workflow). It officially joined CNCF in June 2021 and was widely welcomed by community users.</p>
<p>Today, <strong>KubeVela has been adopted by more than 300 domestic and overseas enterprises, including China Merchants Bank, ByteDance, Li Auto, and Shein. The entire OAM and KubeVela community contains dozens of ecological projects, which have accumulated more than 8000 stars and received many contributions from more than 300 developers from dozens of countries worldwide.</strong></p>
<p><img decoding="async" loading="lazy" src="https://kubevela.net/img/what-is-kubevela.png" alt="" class="img_ev3q">
<em>Picture 1: Unified Application Delivery of KubeVela</em></p>
<p>KubeVela helps enterprises build unified application delivery capabilities. With KubeVela's unified architecture, enterprises can simultaneously deliver microservice containers, cloud database, frontend static pages, and their internal custom extensions in one configuration file, completing the orchestration and operational management of diverse workloads. Developers of business applications no longer need to worry about the differences in Kubernetes resource versions or different disk specifications during delivery. KubeVela provides comprehensive version management, grayscale release, CI/CD docking, multi-cluster management, and other functions for the description of a unified application, significantly reducing the threshold for enterprises to use cloud-native technology.</p>
<p>With the development of the community, more enterprises use KubeVela as the core engine of the internal PaaS platform. Based on the unified model and addon extension mechanism at the upper layer of KubeVela, a series of advanced features have been developed, including security, observability, and GitOps. <strong>A large number of core contributors have emerged, including China Merchants Bank, Napptive, and JD Cloud. They contribute many new features and addons to the KubeVela ecosystem, gradually extending the boundaries of KubeVela from application delivery to application day-2 management.</strong></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="new-milestone-united-app-delivery-and-day-2-management">New Milestone: United App Delivery and Day-2 Management<a href="https://kubevela.io/blog/2022/11/10/release-1.6/#new-milestone-united-app-delivery-and-day-2-management" class="hash-link" aria-label="Direct link to New Milestone: United App Delivery and Day-2 Management" title="Direct link to New Milestone: United App Delivery and Day-2 Management" translate="no">​</a></h2>
<p>This release has four core directions.</p>
<ol>
<li class="">
<p><strong>Visualize Resource Status:</strong> From the first deployment of an application to the subsequent continuous delivery, KubeVela visualizes the delivery process and topology of the entire application resources and automatically generates an observability dashboard containing more than 100 core metrics to help developers locate problems by themselves. More importantly, the resource visualization capability can easily access user-defined resources to meet user-defined observability configuration requirements and realize unified observability at the multi-cluster level.</p>
</li>
<li class="">
<p><strong>Make Platform Capabilities More Like Addons:</strong> KubeVela has built a flexible, extensible, and self-installed platform capability addon center and more than 50 out-of-the-box addons. These addons include cloud resources, GitOps, observability, FinOps, IoT, and other scenarios. They help business developers flexibly build solutions for different scenarios and reduce the mental burden of users through the practical experience of the community.</p>
</li>
<li class="">
<p><strong>Automate the Delivery Process:</strong> The KubeVela declarative workflow system has the capability of operating system resources and adds a large number of advanced features (such as condition judgment, parameter transfer, and branch concurrency). Each process can be extended by configuration language programming. More than ten scenario-based workflows (including multi-cluster grayscale release, CI/CD docking, and secure and compliant access) help developers easily complete self-service application orchestration.</p>
</li>
<li class="">
<p><strong>Unify Environment Management:</strong> You no longer need to prepare a Kubernetes cluster in advance to install KubeVela. KubeVela provides a self-service one-click offline installation tool for developers to install a complete set of control panels locally or on virtual machines. It combines multi-cluster delivery and management capabilities to help developers realize unified management in the whole process and multi-environment of development, testing, and production.</p>
</li>
</ol>
<p><img decoding="async" loading="lazy" src="https://kubevela.io/assets/images/what-is-kubevela-1b6d211edd64da6c9052827fec7928fd.jpg" width="2056" height="942" class="img_ev3q">
<em>Picture 2: Application Platform with Integrated Delivery and Management</em></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="in-depth-interpretation-of-new-version-functions">In-Depth Interpretation of New Version Functions<a href="https://kubevela.io/blog/2022/11/10/release-1.6/#in-depth-interpretation-of-new-version-functions" class="hash-link" aria-label="Direct link to In-Depth Interpretation of New Version Functions" title="Direct link to In-Depth Interpretation of New Version Functions" translate="no">​</a></h2>
<p>Since KubeVela officially released version 1.0 in April 2021, OAM has been continuously verified by KubeVela and gradually stabilized. KubeVela's previous version iterations can always ensure the forward compatibility of the API, corresponding to OAM version 0.3.1. According to SemVer's international practice of naming versions, the version number released this time is <a href="https://github.com/kubevela/kubevela/releases/tag/v1.6.0" target="_blank" rel="noopener noreferrer" class="">1.6</a>. Although the version number has only increased by 0.1, this release is the overall presentation of KubeVela's application management capabilities since version 1.2 was released more than a year ago. Next, we will conduct an in-depth interpretation of the core functions one by one.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="prioritize-resource-visualization">Prioritize Resource Visualization<a href="https://kubevela.io/blog/2022/11/10/release-1.6/#prioritize-resource-visualization" class="hash-link" aria-label="Direct link to Prioritize Resource Visualization" title="Direct link to Prioritize Resource Visualization" translate="no">​</a></h3>
<p>Based on the OAM concept, extensibility and abstraction are the two core features of KubeVela. However, abstraction often represents a black box. Once users encounter problems that are difficult to troubleshoot and can't see the progress and status of resource delivery, management will be more difficult. We have solved the problem of resource visualization based on extensibility in this release. KubeVela automatically discovers Kubernetes native resources and helps users build resource topology maps. You can automatically generate a topology map for user-defined extended resources by describing the configuration of a resource association relationship.</p>
<p><strong>This also means resource visualization is prioritized in the KubeVela system. KubeVela can fully describe the topology, view underlying container events and logs, and obtain the overall delivery status for any workload contained in an application</strong>. The following picture shows the resource topology of KubeVela.</p>
<p><img decoding="async" loading="lazy" src="https://kubevela.io/assets/images/velaux-res-3fc4b0bb4726ab486a7521a43c58e762.png" width="1737" height="791" class="img_ev3q">
<em>Picture 3: VelaUX Resource Visualization Process</em></p>
<blockquote>
<p>VelaUX Documentation: <a href="https://kubevela.net/docs/reference/addons/velaux" target="_blank" rel="noopener noreferrer" class="">https://kubevela.net/docs/reference/addons/velaux</a></p>
</blockquote>
<p>In addition, <strong>KubeVela provides a <em>top</em> interactive interface for command-line users, which allows users to easily view the status of delivered resources and fully meet the usage habits of different developers</strong>.</p>
<p><img decoding="async" loading="lazy" src="https://kubevela.io/assets/images/velatop1-ebd850ee4c071621aa778de0f4219a26.png" width="1053" height="667" class="img_ev3q">
<img decoding="async" loading="lazy" src="https://kubevela.io/assets/images/velatop2-f9d395474c4ecd2ffe5e3f53e2fdc816.png" width="1053" height="907" class="img_ev3q">
<em>Picture 4: Diagram of Vela Top Command Line Operation</em></p>
<blockquote>
<p>Vela Top Command Line Operation Documentation: <a href="https://kubevela.net/docs/tutorials/vela-top" target="_blank" rel="noopener noreferrer" class="">https://kubevela.net/docs/tutorials/vela-top</a></p>
</blockquote>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="support-for-application-level-observability">Support for Application-Level Observability<a href="https://kubevela.io/blog/2022/11/10/release-1.6/#support-for-application-level-observability" class="hash-link" aria-label="Direct link to Support for Application-Level Observability" title="Direct link to Support for Application-Level Observability" translate="no">​</a></h3>
<p><strong>Observability</strong> is the top priority in application management. This release of KubeVela has also comprehensively improved observability. Specifically, it consists of observability infrastructure construction, application-oriented observability, and observability as code.</p>
<p>KubeVela Observability Documentation: <a href="https://kubevela.net/docs/platform-engineers/operations/observability" target="_blank" rel="noopener noreferrer" class="">https://kubevela.net/docs/platform-engineers/operations/observability</a></p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="observability-infrastructure">Observability Infrastructure<a href="https://kubevela.io/blog/2022/11/10/release-1.6/#observability-infrastructure" class="hash-link" aria-label="Direct link to Observability Infrastructure" title="Direct link to Observability Infrastructure" translate="no">​</a></h4>
<p>KubeVela's addon system can help users that do not have observability infrastructure create the entire observability software stack with one click. As shown in the following picture, it includes common observability services (such as Prometheus and Grafana) and metrics and log collection for business scenarios (such as mysql-exporter). After the addon is installed, you can automatically see the built-in dashboards of the platform and quickly build the observability application platform.</p>
<p><img decoding="async" loading="lazy" src="https://kubevela.io/assets/images/o11y-addon-stack-478fe1cb98f1eed6fd7666342e958aa2.jpg" width="1222" height="859" class="img_ev3q">
<em>Picture 5: Out-of-the-Box Observability Addons</em></p>
<p><strong>KubeVela allows users that already have observability services to integrate the deployed Prometheus and Grafana services through standard APIs, including the stable, reliable, and unlimited observability services that are self-created or provided by cloud vendors</strong>, such as <a href="https://www.alibabacloud.com/product/arm" target="_blank" rel="noopener noreferrer" class="">Alibaba Cloud ARMS</a>.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="application-oriented-observability">Application-Oriented Observability<a href="https://kubevela.io/blog/2022/11/10/release-1.6/#application-oriented-observability" class="hash-link" aria-label="Direct link to Application-Oriented Observability" title="Direct link to Application-Oriented Observability" translate="no">​</a></h4>
<p>A major feature of KubeVela is that it drives complete application delivery through a top-level application description (YAML). Observability is no exception. The KubeVela controller automatically generates a monitoring dashboard for the application by selecting the O&amp;M features corresponding to logs or metrics.</p>
<p><img decoding="async" loading="lazy" src="https://kubevela.io/assets/images/o11y-yaml-32db1093b47a99c6f06066240cc1f019.png" width="750" height="455" class="img_ev3q">
<em>Picture 6: Application-Oriented Observability</em></p>
<p>The user portal is an application-oriented dashboard. You can view the component status, version information, and the generated resources in the application. It also contains the dashboard links corresponding to various sub-resources. You can dive into the sub-resources and see detailed information as needed. <strong>You can easily understand the full picture of resources from the perspective of applications, whether they are Kubernetes native resources or custom resources</strong>.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="observability-as-code">Observability as Code<a href="https://kubevela.io/blog/2022/11/10/release-1.6/#observability-as-code" class="hash-link" aria-label="Direct link to Observability as Code" title="Direct link to Observability as Code" translate="no">​</a></h4>
<p>The ability to support the application observability underlying layer is completed by Infrastructure as Code (IaC). <strong>This also means KubeVela has made the full link IaC from metric collection (including log collection), parsing, enrichment, storage, data source registration and the dashboard visualization</strong>.</p>
<p>The following picture shows how to create a Grafana dashboard using IaC. The IaC module allows you to <em>”create-dashboard”</em>. Similarly, these include creating data sources, importing dashboards, etc. These routine actions are fully built-in in the KubeVela community, and you can use them directly without learning details. If you want to do some customization, you can orchestrate your process through IaC to customize observability for your platform.</p>
<p><img decoding="async" loading="lazy" src="https://kubevela.io/assets/images/o11y-as-code-b95a6a16a6ab56895f650694b9a30bf0.png" width="770" height="1197" class="img_ev3q">
<em>Picture 7: Observability as Code</em></p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="unified-management-of-multi-environment-pipeline">Unified Management of Multi-Environment Pipeline<a href="https://kubevela.io/blog/2022/11/10/release-1.6/#unified-management-of-multi-environment-pipeline" class="hash-link" aria-label="Direct link to Unified Management of Multi-Environment Pipeline" title="Direct link to Unified Management of Multi-Environment Pipeline" translate="no">​</a></h3>
<p>Development, testing, and production of different environment management are the problems of application management. KubeVela's unified application model can deliver applications and initialize the environment. It naturally supports the management of multi-cluster and can install infrastructure components of different clusters with one click. In version 1.4, we released the <a href="https://github.com/kubevela/velad" target="_blank" rel="noopener noreferrer" class="">VelaD project</a>, which can pull up the complete environment of KubeVela on the local machine without relying on Kubernetes. Developers can quickly build and validate applications locally (or in virtual machines) for an environment consistent with production. The management of different environments has been improved in this release.</p>
<p>This release adds an independent pipeline capability. Compared with the application-level workflows of KubeVela, the independent pipeline has the following features:</p>
<ol>
<li class="">
<p>It can manage multiple KubeVela applications and create them across multiple environments.</p>
</li>
<li class="">
<p>It is not bound to an application and can be used independently. For example, it scales in and out a group of resources, performs process-oriented grayscale release for an application, and performs a group of O&amp;M operations in batches.</p>
</li>
<li class="">
<p>It is one-time and does not manage resources. Deleting the pipeline in time will not delete the created resources.</p>
</li>
<li class="">
<p>It is homologous to the execution engine of the application pipeline, which inherits the characteristics of KubeVela's lightweight workflow. Compared with the traditional container-based CI pipeline, KubeVela's pipeline does not rely on containers and does not require additional computing resources when performing various resource operations.</p>
</li>
</ol>
<p>As shown in the following picture, when using it, we can obtain the built-in pipeline template, fill in the environment context parameters, and quickly execute. The following example shows multiple KubeVela platform addons opened through the pipeline. The KubeVela application is behind the addons.</p>
<p><img decoding="async" loading="lazy" src="https://kubevela.io/images/1.6/pipeline.gif" alt="" class="img_ev3q">
<em>Picture 8: KubeVela Pipeline UI Diagram</em></p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="integrate-and-manage-configurations">Integrate and Manage Configurations<a href="https://kubevela.io/blog/2022/11/10/release-1.6/#integrate-and-manage-configurations" class="hash-link" aria-label="Direct link to Integrate and Manage Configurations" title="Direct link to Integrate and Manage Configurations" translate="no">​</a></h3>
<p>Configuration management is one of the cores of application management. KubeVela's configuration management mainly helps users share configurations between applications and integrate configurations with third-party external systems to realize unified configuration management. For example, you can connect to external systems (such as container image repositories and Helm repositories) and third-party cloud services (such as the ARMS observability suite mentioned above).</p>
<p>KubeVela configuration management uses the Secret API of Kubernetes as the carrier of configuration data. The application is used for multi-cluster distribution on demand. Applications can read configurations by mounting secrets commonly used in Kubernetes and connecting to the permission system. In addition, if a business application supports reading configurations from a third-party configuration management platform (such as Nacos), you can specify to export the configuration content to the services when defining configuration templates, thus reusing the configuration distribution capabilities of registries.</p>
<p>You can perform configuration management operations from UI/CLI and perform configuration reading and writing operations in application workflows and pipelines. It combines the data transfer capabilities and motion orchestration capabilities of a pipeline to implement diverse scenarios (such as configuration sharing and automatic configuration injection among applications).</p>
<p><img decoding="async" loading="lazy" src="https://kubevela.io/images/1.6/config-management.gif" alt="" class="img_ev3q">
<em>Picture 9: Diagram of Configuration Management</em></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-ecology-and-future-of-kubevela">The Ecology and Future of KubeVela<a href="https://kubevela.io/blog/2022/11/10/release-1.6/#the-ecology-and-future-of-kubevela" class="hash-link" aria-label="Direct link to The Ecology and Future of KubeVela" title="Direct link to The Ecology and Future of KubeVela" translate="no">​</a></h2>
<p>This upgrade of KubeVela adds many application management capabilities to the original application delivery, which is a big step forward for the goal of <strong>helping application developers obtain an easy, reliable, and secure software development experience.</strong></p>
<p>Today, KubeVela is a Kubernetes-based controller and a platform with many ecological projects. From the connectivity of the underlying infrastructure, and user-oriented interface at the upper layer, to the extensible ecosystem integration, KubeVela is growing rapidly, fulfilling the beautiful vision of OAM at the beginning of its release - <em>to make the delivery and management of applications simpler, safer, and more reliable!</em></p>
<p><img decoding="async" loading="lazy" src="https://kubevela.io/assets/images/ecosystem-98e69ac80ca0a3ea52ef67d858888fa7.png" width="860" height="379" class="img_ev3q">
<em>Picture 10: Tool Ecosystem of KubeVela</em></p>
<p>In the future, the KubeVela community will continue to enrich out-of-the-box system addons, enrich scenario-oriented application delivery and management solutions, and gradually settle community practices into OAM application standards, building a development, unified, and standardized cloud-native application ecosystem.</p>]]></content>
        <author>
            <name>Jianbo Sun</name>
            <uri>https://github.com/wonderflow</uri>
        </author>
        <category label="KubeVela" term="KubeVela"/>
        <category label="release-note" term="release-note"/>
        <category label="Kubernetes" term="Kubernetes"/>
        <category label="DevOps" term="DevOps"/>
        <category label="CNCF" term="CNCF"/>
        <category label="CI/CD" term="CI/CD"/>
        <category label="Application delivery" term="Application delivery"/>
        <category label="Open Application Model" term="Open Application Model"/>
        <category label="Observability" term="Observability"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[An Introduction to KubeVela Addons: Extend Your Own Platform Capability]]></title>
        <id>https://kubevela.io/blog/2022/10/18/building-addon-introduction/</id>
        <link href="https://kubevela.io/blog/2022/10/18/building-addon-introduction/"/>
        <updated>2022-10-18T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Introduction to building KubeVela addons.]]></summary>
        <content type="html"><![CDATA[<p>As we all know, KubeVela is a highly extensible platform, on which users can build their own customizations using <a href="https://kubevela.io/docs/platform-engineers/oam/x-definition" target="_blank" rel="noopener noreferrer" class="">Definitions</a>. KubeVela addons are a convenient way to pack all these customizations and their dependencies together as a bundle, to extend your own platform capabilities!</p>
<p>This blog introduces the main concepts of an addon and guides you to quickly start building one. Finally, we'll show you the experience of the end user, and how the capabilities provided are glued in a consistent user-friendly experience.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="why-use-addons">Why use addons<a href="https://kubevela.io/blog/2022/10/18/building-addon-introduction/#why-use-addons" class="hash-link" aria-label="Direct link to Why use addons" title="Direct link to Why use addons" translate="no">​</a></h2>
<p>We typically use addons with <a href="https://github.com/kubevela/catalog" target="_blank" rel="noopener noreferrer" class="">addon catalog</a>, which is a registry contains addons that including all kinds of customizations that the KubeVela community carefully crafted. You can download and install these addons with just one click. For example, you can provide the ability to deploy Helm Chart in your KubeVela Application to your cluster by installing <a href="https://github.com/kubevela/catalog/tree/master/addons/fluxcd" target="_blank" rel="noopener noreferrer" class=""><code>fluxcd</code></a> addon.</p>
<p>Contrary to the convenience of one-key installation, without KubeVela addons, you have to manually install <a href="https://fluxcd.io/" target="_blank" rel="noopener noreferrer" class="">FluxCD</a> in this way:</p>
<ol>
<li class="">Install FluxCD using Helm Charts or downloaded yaml manifests</li>
<li class="">Glue FluxCD CRD with your system manually, it can be done by adding Component or Trait Definitions in KubeVela</li>
</ol>
<p>Actually, this is how we install FluxCD before KubeVela v1.1.
Although it seems like only 2 steps needed, we found it to be quite troublesome:</p>
<ol>
<li class=""><strong>Complicated installation</strong>: users are required to refer to documentations to manually install FluxCD and tackle possible errors</li>
<li class=""><strong>Scattered resources</strong>: users need to obtain different resource files from different places</li>
<li class=""><strong>Hard distribution</strong>: users having to download manifests manually makes it hard to distribute all these resources in a uniformed way</li>
<li class=""><strong>Lack multi-cluster support</strong>: KubeVela emphasizes multi-cluster delivery a lot. However, manual installation makes multi-cluster support hard to carry out.</li>
<li class=""><strong>No version management</strong>: users need to manage the relationship between definitions, controllers, and corresponding versions by themselves.</li>
</ol>
<p>KubeVela addons are born to solve these problems.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="how-kubevela-addons-work">How KubeVela addons work<a href="https://kubevela.io/blog/2022/10/18/building-addon-introduction/#how-kubevela-addons-work" class="hash-link" aria-label="Direct link to How KubeVela addons work" title="Direct link to How KubeVela addons work" translate="no">​</a></h2>
<p>KubeVela addons mainly contain two parts:</p>
<ul>
<li class="">One is the installation of the capability provider, which is usually a CRD Operator. The installation process are <strong>intrinsically leveraging KubeVela Application</strong> to work.</li>
<li class="">Another one is the glue layer, which is OAM Definitions and other extensions. These OAM Definitions usually depend on the capability provider and provide user-friendly abstraction from best practices.</li>
</ul>
<p><img decoding="async" loading="lazy" src="https://kubevela.io/assets/images/addon-mechanism-83290221f79423b455566ee5d66485f3.jpg" width="1739" height="978" class="img_ev3q"></p>
<p>The whole working mechanism of addon is shown as above. KubeVela Application has the multi-clusters capability that help deliver CRD operators of addon into these clusters. The definition files are only used by KubeVela control plane, so they will only existing in the control plane clusters.</p>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg 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</div><div class="admonitionContent_BuS1"><p>Once installed, an application object will be created and all related resources will mark ownerReference to this application. When we want to uninstall an addon, we just need to delete the application, the ownerReference mechanism of Kubernetes will help clean up all the other resources.</p></div></div>
<p>Let's build a Redis addon as example, which makes it possible to use Redis Components in Applications, to create a Redis cluster. Such addon will at least include a Redis Operator (to create Redis clusters) and a ComponentDefinition (to define what is a <code>redis</code> Component).</p>
<p>The installation process of an addon includes installing Applications (which includes a Redis Operator), Definitions and etc.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="create-your-own-addon">Create your own addon<a href="https://kubevela.io/blog/2022/10/18/building-addon-introduction/#create-your-own-addon" class="hash-link" aria-label="Direct link to Create your own addon" title="Direct link to Create your own addon" translate="no">​</a></h2>
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg 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</div><div class="admonitionContent_BuS1"><p>Make sure you're using KubeVela v1.5+ to have all these capabilities mentioned below.</p></div></div>
<p>We will guide you through the whole process of making an redis addon. The full source code of this guide is located at <a href="https://github.com/kubevela/catalog/tree/master/experimental/addons/redis-operator" target="_blank" rel="noopener noreferrer" class="">catalog/redis-operator</a>.</p>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg 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</div><div class="admonitionContent_BuS1"><p>As an introduction, we won't cover all features. If you are interested to build addon by your own, you'd better refer to the <a href="https://kubevela.io/docs/platform-engineers/addon/intro" target="_blank" rel="noopener noreferrer" class="">"Make Your Own Addon"</a> documentation for details.</p></div></div>
<p><strong>First, we need to consider what our addon can provide to end users.</strong> Let's say our Redis addon can provide a Component called <code>redis-failover</code>, which will create a whole Redis cluster when declared in application.</p>
<p><strong>Then we will figure out how to achieve this.</strong> To define a <code>redis-failover</code> Component, we need to write a ComponentDefinition. To be able to create a Redis Cluster, we use a <a href="https://github.com/spotahome/redis-operator" target="_blank" rel="noopener noreferrer" class="">Redis Operator</a> as the capability provider.</p>
<p>Now our goals are clear:</p>
<ul>
<li class="">Write an OAM Application, which includes the installation of a Redis Operator. (Refer to <a href="https://github.com/kubevela/catalog/blob/master/experimental/addons/redis-operator/template.cue" target="_blank" rel="noopener noreferrer" class=""><code>template.cue</code></a> and <a href="https://github.com/kubevela/catalog/tree/master/experimental/addons/redis-operator/resources" target="_blank" rel="noopener noreferrer" class=""><code>resources/</code></a> in the full source code.)</li>
<li class="">Write a <a href="https://kubevela.io/docs/platform-engineers/components/custom-component" target="_blank" rel="noopener noreferrer" class="">ComponentDefinition</a>, which defines Components called <code>redis-failover</code>. (Refer to <a href="https://github.com/kubevela/catalog/tree/master/experimental/addons/redis-operator/definitions" target="_blank" rel="noopener noreferrer" class=""><code>definitions/</code></a> folder in the full source code.)</li>
</ul>
<p>But before we start coding, we need to understand the structure of an addon directory. We will describe each file later, just have a basic understanding of what files are needed for now.</p>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg 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</div><div class="admonitionContent_BuS1"><p>The command <code>vela addon init</code> can help you create the scaffold addon directories and files as an initialization.</p></div></div>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">redis-operator/ </span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">├── definitions </span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">│   └── redis-failover.cue </span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">├── resources              </span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">│   ├── crd.yaml       </span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">│   ├── redis-operator.cue </span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">│   └── topology.cue       # (Optional)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">├── metadata.yaml          </span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">├── parameter.cue         </span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">├── README.md            </span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">└── template.cue       </span><br></span></code></pre></div></div>
<p>Let's explain all these files and folders one by one:</p>
<ol>
<li class=""><code>redis-operator/</code> is the directory name, which is the same as the addon name.</li>
<li class=""><code>definitions/</code> folder stores Definitions, including TraitDefinition, ComponentDefinition, and etc.</li>
<li class=""><code>redis-failover.cue</code> defines the ComponentDefinition that how the <code>redis-failover</code> component can be used, and how it integrates with the underlying resources.</li>
<li class=""><code>resources/</code> folder contain resource files which will be composed as a whole application in <code>template.cue</code>.</li>
<li class=""><code>crd.yaml</code> inside the <code>resources/</code> folder is the CRD that comes with Redis Operator. Yaml file inside this folder will be applied to Kubernetes directly.</li>
<li class=""><code>redis-operator.cue</code> defines a web-service Component, which installs the Redis Operator.</li>
<li class=""><code>topology.cue</code> is optional, it helps KubeVela build the relationships between Application and the underlying resources.</li>
<li class=""><code>metadata.yaml</code> defines metadata of this addon, including name, version, tags, maintainers and etc. This information can be an overview of addon exposed to any registry.</li>
<li class=""><code>parameter.cue</code> defines the parameters of this addon, end users can use them to customize their addon installation.</li>
<li class=""><code>README.md</code> guides the user to quickly start using this addon.</li>
<li class=""><code>template.cue</code> is the template of the addon which will form the whole Application when installed.</li>
</ol>
<p>Now let's go through the deep of how to write them one by one.</p>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg 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</div><div class="admonitionContent_BuS1"><p>We will use CUE language extensively in the following section, so <a href="https://kubevela.io/docs/platform-engineers/cue/basic" target="_blank" rel="noopener noreferrer" class="">CUE Basic</a> might be useful.</p></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="parametercue">parameter.cue<a href="https://kubevela.io/blog/2022/10/18/building-addon-introduction/#parametercue" class="hash-link" aria-label="Direct link to parameter.cue" title="Direct link to parameter.cue" translate="no">​</a></h3>
<div class="language-cue codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cue codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">parameter</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	</span><span class="token comment" style="color:rgb(98, 114, 164)">//+usage=Redis Operator image.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	image</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token operator">*</span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"quay.io/spotahome/redis-operator:v1.1.0"</span><span class="token plain"> </span><span class="token operator">|</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">string</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	</span><span class="token comment" style="color:rgb(98, 114, 164)">// ...omitted</span><br></span></code></pre></div></div>
<p>The parameters defined in <code>parameter.cue</code> are customizable by users when installing addons, just like Helm Values. You can access the values of these parameters in CUE later by <code>parameter.&lt;parameter-name&gt;</code>. In our example, <code>image</code> is provided to let the user customize Redis Operator image and can be accessed in <code>redis-operator.cue</code> by <code>parameter.image</code>.</p>
<p>Apart from customizing some fields, you can also do something creative, such as parameterized installation of addons. For example, <code>fluxcd</code> addon have a parameter called <a href="https://github.com/kubevela/catalog/blob/master/addons/fluxcd/parameter.cue" target="_blank" rel="noopener noreferrer" class=""><code>onlyHelmComponents</code></a>. Since <code>fluxcd</code> addon is a big one, which includes 5 different controllers, not all users want such a heavy installation. So if the <code>onlyHelmComponents</code> parameter is set to <code>true</code> by the user, only 2 controllers will be installed, making it a relatively light installation. If you are interested in how this is achieved, you can refer to <a href="https://github.com/kubevela/catalog/blob/master/addons/fluxcd/template.cue#L25" target="_blank" rel="noopener noreferrer" class="">fluxcd addon</a> for details.</p>
<p>When you design what parameters are provided to the user, you can follow our best practices to make it user friendly.</p>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg 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>best practices</div><div class="admonitionContent_BuS1"><ul>
<li class="">Do not provide every possible parameter to your user and let them figure out how to dial dozens of knobs by themselves. Abstract fine-grained knobs into some broad parameters, so that the user can input a few parameters and get a usable but customized addon.</li>
<li class="">Decide on sane defaults for starters. Let the user get started with your addon
even if they don't provide parameters (if possible).</li>
<li class="">Provide usage for each parameter, you can mark annotation above the parameter as the example does.</li>
<li class="">Keep parameters consistent across versions to avoid incompatibilities during upgrades.</li>
</ul></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="templatecue-and-resources-folder"><code>template.cue</code> and <code>resources/</code> folder<a href="https://kubevela.io/blog/2022/10/18/building-addon-introduction/#templatecue-and-resources-folder" class="hash-link" aria-label="Direct link to templatecue-and-resources-folder" title="Direct link to templatecue-and-resources-folder" translate="no">​</a></h3>
<p>OAM Application is stored here, which contains the actual installation process of addons. In our case, we will create an Application that includes a Redis Operator to give our cluster the ability to create Redis clusters.</p>
<p><code>template.cue</code> and <code>resources/</code> directory both serve the same purpose -- to define an Application. Aside from historical reasons, the reason why we split it into two places is readability. When we have a ton of resource in template.cue, it will eventually be too long to read. So we typically put the Application scaffold in <code>template.cue</code>, and Application Components in <code>resources</code> directory.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="templatecue">template.cue<a href="https://kubevela.io/blog/2022/10/18/building-addon-introduction/#templatecue" class="hash-link" aria-label="Direct link to template.cue" title="Direct link to template.cue" translate="no">​</a></h4>
<p><code>template.cue</code> defines the framework of one Application. Most of the contents here can be boilerplates, they're explained as annotations in the code block.</p>
<div class="language-cue codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cue codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">// package name should be the same as the CUE files in resources directory,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)">// so that we can refer to the files in resources/.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">package</span><span class="token plain"> main</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">output</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	</span><span class="token comment" style="color:rgb(98, 114, 164)">// This is just a plain OAM Application</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	apiVersion</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"core.oam.dev/v1beta1"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	kind</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">       </span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"Application"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	</span><span class="token comment" style="color:rgb(98, 114, 164)">// No metadata required</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	spec</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">		components</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">			</span><span class="token comment" style="color:rgb(98, 114, 164)">// Create a component that includes a Redis Operator</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">			redisOperator </span><span class="token comment" style="color:rgb(98, 114, 164)">// defined in resources/redis-operator.cue</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">		</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">		policies</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">		</span><span class="token comment" style="color:rgb(98, 114, 164)">// What namespace to install, whether install to sub-clusters</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">		</span><span class="token comment" style="color:rgb(98, 114, 164)">// Again, these are boilerplates. No need to remember them. Just refer to the full source code.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">		</span><span class="token comment" style="color:rgb(98, 114, 164)">// https://github.com/kubevela/catalog/blob/master/experimental/addons/redis-operator/template.cue</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">		</span><span class="token comment" style="color:rgb(98, 114, 164)">// Documentation: https://kubevela.io/docs/end-user/policies/references</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">		</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)">// Resource topology, which can help KubeVela glue resources together.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)">// We will discuss this in detail later.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)">// Documentation: https://kubevela.io/docs/reference/topology-rule</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">outputs</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> topology</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> resourceTopology </span><span class="token comment" style="color:rgb(98, 114, 164)">// defined in resources/topology.cue</span><br></span></code></pre></div></div>
<p>The <code>output</code> field is the keyword of this template, it contains the Application that will be deployed. In side the application, the <code>spec.components</code> field will reference the objects defined in the <code>resources/</code> folder.</p>
<p>The <code>outputs</code> field is another keyword that can be used to define any auxiliary resources you want to be deployed along with this addon. These resources <strong>MUST</strong> follow Kubernetes API.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="resources-folder"><code>resources/</code> folder<a href="https://kubevela.io/blog/2022/10/18/building-addon-introduction/#resources-folder" class="hash-link" aria-label="Direct link to resources-folder" title="Direct link to resources-folder" translate="no">​</a></h4>
<p>Here we define Application Components that will be referred to in <code>template.cue</code>. We will use a <code>webservice</code> Component to install Redis Operator. Of course, if you are comfortable with extra dependencies (FluxCD addon), you can use <code>helm</code> Components to install the Redis Operator Helm Chart directly. But one of the principles of writing an addon is to reduce external dependencies, so we use the <code>webservice</code> Component, which is a built-in Component of KubeVela, instead of <code>helm</code>.</p>
<div class="language-cue codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cue codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">// resources/redis-operator.cue</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)">// package name is the same as the one in template.cue. So we can use `redisOperator` below in template.cue</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">package</span><span class="token plain"> main</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">redisOperator</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	</span><span class="token comment" style="color:rgb(98, 114, 164)">// an OAM Application Component, which will create a Redis Operator</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	</span><span class="token comment" style="color:rgb(98, 114, 164)">// https://kubevela.io/docs/end-user/components/references</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"redis-operator"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"webservice"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">		</span><span class="token comment" style="color:rgb(98, 114, 164)">// Redis Operator container image (parameter.image is defined in parameter.cue)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">		image</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">           parameter</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">image</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">		imagePullPolicy</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"IfNotPresent"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	traits</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">		</span><span class="token comment" style="color:rgb(98, 114, 164)">// ...omitted</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></div></div>
<p>You can refer to the annotation inside the code block to learn the detail usage for every field.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="highlights-of-the-glue-capability-provided-by-kubevela">Highlights of the glue capability provided by KubeVela<a href="https://kubevela.io/blog/2022/10/18/building-addon-introduction/#highlights-of-the-glue-capability-provided-by-kubevela" class="hash-link" aria-label="Direct link to Highlights of the glue capability provided by KubeVela" title="Direct link to Highlights of the glue capability provided by KubeVela" translate="no">​</a></h4>
<p>One of the notable features is <a href="https://kubevela.io/docs/reference/topology-rule" target="_blank" rel="noopener noreferrer" class=""><em>Topology Rules</em></a> (or Resource Topologies, Resource Relationships). Although not required, it can help KubeVela build the topological relationships of the resources managed by a KubeVela Application. This is how KubeVela can glue all kinds of resources together into an Application. It is especially helpful when we use Kubernetes Custom Resource(CR) (which is exactly the case in this example).</p>
<div class="language-cue codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cue codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">// resources/topology.cue</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">package</span><span class="token plain"> main</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> </span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"encoding/json"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">resourceTopology</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	apiVersion</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"v1"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	kind</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">       </span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"ConfigMap"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	metadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">		name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">      </span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"redis-operator-topology"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">		namespace</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"vela-system"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">		labels</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">			</span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"rules.oam.dev/resources"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">       </span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"true"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">			</span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"rules.oam.dev/resource-format"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"json"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">		</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	data</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> rules</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> json</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">Marshal</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">		parentResourceType</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">			group</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"databases.spotahome.com"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">			kind</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">  </span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"RedisFailover"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">		</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">		</span><span class="token comment" style="color:rgb(98, 114, 164)">// RedisFailover CR manages the three resource below</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">		childrenResourceType</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">			</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">				apiVersion</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"apps/v1"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">				kind</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">  </span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"StatefulSet"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">			</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">			</span><span class="token comment" style="color:rgb(98, 114, 164)">// Topologies of Deployment and etc. are built-in.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">			</span><span class="token comment" style="color:rgb(98, 114, 164)">// So we don't need to go deeper to Pods.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">			</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">				apiVersion</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"apps/v1"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">				kind</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">  </span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"Deployment"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">			</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">			</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">				apiVersion</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"v1"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">				kind</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">  </span><span class="token string-literal string" style="color:rgb(255, 121, 198)">"Service"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">			</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">		</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></div></div>
<p>In our case, the <code>redis-failover</code> Component will create a CR, named <code>RedisFailover</code>. If we don't have <em>Topology Rules</em>, although we know <code>RedisFailover</code> is managing several Deployments and Services, KubeVela doesn't magically know this. So we can <em>tell</em> KubeVela our understanding with <em>Topology Rules</em>. Once KubeVela know what's inside a <code>RedisFailover</code>, it will know the relationships of all the resources inside an Application.</p>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg 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</div><div class="admonitionContent_BuS1"><p>This can bring huge benefits and give us a consistent experience for all extended resources:</p><ul>
<li class="">Resource topology graphs from application to underlying pods can be provided in VelaUX</li>
<li class="">Consistent execute commands into pods for all kinds of Application components using <code>vela exec</code></li>
<li class="">Consistent forward ports to pods for all kinds of Application components using <code>vela port-forward</code></li>
<li class="">Consistent get logs from pods for all kinds of Application components using <code>vela log</code></li>
<li class="">Consistent get Pods or access endpoints for all kinds of Application components using <code>vela status --pod/--endpoint</code></li>
</ul></div></div>
<p>You can refer to <a href="https://kubevela.io/blog/2022/10/18/building-addon-introduction/#run-our-addon" class="">run our addon</a> to see the real user experience.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="definitions-folder"><code>definitions/</code> folder<a href="https://kubevela.io/blog/2022/10/18/building-addon-introduction/#definitions-folder" class="hash-link" aria-label="Direct link to definitions-folder" title="Direct link to definitions-folder" translate="no">​</a></h3>
<p>Definitions folder contains KubeVela <a href="https://kubevela.io/docs/getting-started/definition" target="_blank" rel="noopener noreferrer" class="">Definitions</a>, including ComponentDefinitions, TraitDefinitions, and etc. <strong>This is the most important part of an addon as it provides the real capability to end users.</strong> With the Component and Trait types defined here, users can use them in their applications.</p>
<p>Writing Definitions for an addon is the same as writing regular OAM Definitions, this is a huge topic so we won't go to deep in our addon introduction, you can refer to following docs to learn how to write each kinds of definitions.</p>
<ul>
<li class=""><a href="https://kubevela.io/docs/platform-engineers/components/custom-component" target="_blank" rel="noopener noreferrer" class="">Component Definition</a></li>
<li class=""><a href="https://kubevela.io/docs/platform-engineers/traits/customize-trait" target="_blank" rel="noopener noreferrer" class="">Trait Definition</a></li>
<li class=""><a href="https://kubevela.io/docs/platform-engineers/policy/custom-policy" target="_blank" rel="noopener noreferrer" class="">Policy Definition</a></li>
<li class=""><a href="https://kubevela.io/docs/platform-engineers/workflow/workflow" target="_blank" rel="noopener noreferrer" class="">Workflow Step Definition</a>.</li>
</ul>
<p>In our redis addon example, we should refer to <a href="https://kubevela.io/docs/platform-engineers/components/custom-component" target="_blank" rel="noopener noreferrer" class="">Component Definition</a> and <a href="https://github.com/spotahome/redis-operator/blob/master/README.md" target="_blank" rel="noopener noreferrer" class="">Redis Operator</a> to write our ComponentDefinition. We'll name this component type as <code>redis-failover</code>. It will create a CR called RedisFailover. With RedisFailover created, the Redis Operator in our addon Application will create a Redis cluster for us.</p>
<p>You can refer to the source code <a href="https://github.com/kubevela/catalog/blob/master/experimental/addons/redis-operator/definitions/redis-failover.cue" target="_blank" rel="noopener noreferrer" class="">here</a>.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="metadatayaml">metadata.yaml<a href="https://kubevela.io/blog/2022/10/18/building-addon-introduction/#metadatayaml" class="hash-link" aria-label="Direct link to metadata.yaml" title="Direct link to metadata.yaml" translate="no">​</a></h3>
<p>Just the name implies, these are all metadata of an addon, including addon name, version, system requirements, and etc. You can refer to this <a href="https://kubevela.io/docs/platform-engineers/addon/intro#basic-information-file" target="_blank" rel="noopener noreferrer" class="">documentation</a> for the detail list. The example listed below contains all the fields available.</p>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg 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</div><div class="admonitionContent_BuS1"><p>There're some legacy supports, while we are focusing on the new addon format introduced in KubeVela v1.5+. For example, the old <code>deployTo.runtimeCluster</code> should be deprecated and using <code>topology policy define in application</code> as its alternative. You can refer to <a href="https://github.com/kubevela/catalog/blob/master/experimental/addons/redis-operator/template.cue#L28" target="_blank" rel="noopener noreferrer" class=""><code>template.cue</code></a> in the full source code.</p></div></div>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)"># addon name, the same as our directory name</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> redis</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">operator</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)"># addon description</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">description</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> Redis Operator creates/configures/manages high availability redis with sentinel automatic failover atop Kubernetes.</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)"># tags to show in VelaUX</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">tags</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> redis</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)"># addon version</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">version</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> 0.0.1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)"># addon icon</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">icon</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> https</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">//xxx.com</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)"># the webpage of this addon</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">url</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> https</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">//github.com/spotahome/redis</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">operator</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)"># other addon dependencies, e.g. fluxcd</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">dependencies</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)"># system version requirements</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">system</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">vela</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"&gt;=v1.5.0"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">kubernetes</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"&gt;=1.19"</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="run-our-addon">Run our addon<a href="https://kubevela.io/blog/2022/10/18/building-addon-introduction/#run-our-addon" class="hash-link" aria-label="Direct link to Run our addon" title="Direct link to Run our addon" translate="no">​</a></h2>
<p>Now we have finished most of our work. It is time to run it! If there's any details that were skipped, you can download the full <a href="https://github.com/kubevela/catalog/tree/master/experimental/addons/redis-operator" target="_blank" rel="noopener noreferrer" class="">source code</a> to complete them.</p>
<p>After we finish all the <code>redis-operator</code> addon, we can use command <code>vela addon enable redis-operator/</code> to enable it locally. It can help us debug and write docs about the end user experience.</p>
<p>As to say our example addon, you can refer to the <a href="https://github.com/kubevela/catalog/tree/master/experimental/addons/redis-operator/README.md" target="_blank" rel="noopener noreferrer" class="">README</a> to learn how should be introduced.</p>
<div class="theme-admonition theme-admonition-caution admonition_xJq3 alert alert--warning"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>caution</div><div class="admonitionContent_BuS1"><p>The README.md is very important as it guides users to start using an unfamiliar addon.</p></div></div>
<p>By using this addon, users only need to write <strong>4</strong> lines of yaml to get a Redis cluster with 3 nodes! Contrary to manually installing Redis Operator, even manually managing Redis instances, the use of an addon greatly improves user experience.</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token key atrule">apiVersion</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> core.oam.dev/v1beta1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> Application</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">metadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> redis</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">operator</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">sample</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">spec</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">components</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token comment" style="color:rgb(98, 114, 164)"># This component is provided by redis-operator addon.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token comment" style="color:rgb(98, 114, 164)"># In this example, 2 redis instance and 2 sentinel instance</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token comment" style="color:rgb(98, 114, 164)"># will be created.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> redis</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">failover</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> ha</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">redis</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token comment" style="color:rgb(98, 114, 164)"># You can increase/decrease this later to add/remove instances.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">replicas</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token number">3</span><br></span></code></pre></div></div>
<p>A whole tree of complicated resources are created with just a few lines of yaml, as shown in the figure below. Since we have written <em>Topology Rules</em> for our addon, users can easily see the topology of all the resources (Pods, Services) of a Redis Cluster. They are now not limited to the level of observability of KubeVela Applications, instead, they can have a glance on the statuses of low-level resource. For example, we can see certain Redis Pods are still not ready in our figure:</p>
<p><img decoding="async" loading="lazy" alt="redis-operator-sample-topology-graph" src="https://kubevela.io/assets/images/redis-operator-sample-topology-graph-40961c8c040f39ca8e6566f59db47401.png" width="2528" height="1350" class="img_ev3q"></p>
<p>Users can also choose the low-level resources of our sample Application, i.e., 3 Redis Pods and 3 Sentinal Pods, when executing <code>vela exec/log/port-forward</code>.</p>
<p><img decoding="async" loading="lazy" alt="redis-operator-sample-pod-topology" src="https://kubevela.io/assets/images/redis-operator-sample-pod-topology-1c802208e6a6fb264b6cf75f7d72ccb1.png" width="1096" height="315" class="img_ev3q"></p>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg 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</div><div class="admonitionContent_BuS1"><p>At the first glance, it may not seem that useful to <code>exec</code> into a Pod if you are running a single cluster. However, if you are running multi-cluster installations, having the option to choose resource spanning across multiple clusters is a huge time-saver.</p></div></div>
<p><code>vela status</code> can get the status of an Application. With <code>Topology Rules</code>, we can take one step further -- find out endpoints in an Application directly. In our example, users can get endpoints of Redis Sentinel to connect to by:</p>
<p><img decoding="async" loading="lazy" alt="redis-operator-sample-endpoint" src="https://kubevela.io/assets/images/redis-operator-sample-endpoint-00d6cb96cce1119eddc17f7137902b2d.png" width="1472" height="241" class="img_ev3q"></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="wrap-up">Wrap up<a href="https://kubevela.io/blog/2022/10/18/building-addon-introduction/#wrap-up" class="hash-link" aria-label="Direct link to Wrap up" title="Direct link to Wrap up" translate="no">​</a></h2>
<p>By the end of this guide, you probably already have a good grasp of what addons do and how to make addons. As a conclusion, you'll get the following benefits:</p>
<ol>
<li class="">Extend platform capability into a bundle that can be easy to use and share with the whole community.</li>
<li class="">Orchestrate and template all the infrastructure resources into multi-clusters in a flexible way powered by KubeVela application and CUE.</li>
<li class="">Provide consistent experience for end users with all kinds of extended capabilities.</li>
</ol>
<p>At last, if you have successfully built your own addon, you're extremely welcomed to contribute it to <a href="https://github.com/kubevela/catalog" target="_blank" rel="noopener noreferrer" class="">the addon catalog</a>. As a result, everyone in the KubeVela community can discover and benefit from extending your powerful platform capabilities!</p>]]></content>
        <author>
            <name>Charlie Chiang</name>
            <uri>https://github.com/charlie0129</uri>
        </author>
        <category label="KubeVela" term="KubeVela"/>
        <category label="addon" term="addon"/>
        <category label="extensibility" term="extensibility"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[KubeVela 1.5 released, the Flexible Selection of CNCF Atomic Capabilities to Build a Unique Enterprise Application Release Platform]]></title>
        <id>https://kubevela.io/blog/2022/09/17/release.1.5/</id>
        <link href="https://kubevela.io/blog/2022/09/17/release.1.5/"/>
        <updated>2022-09-17T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This article discusses a brief history of KubeVela and the latest release of KubeVela 1.5.]]></summary>
        <content type="html"><![CDATA[<p><a href="https://github.com/kubevela/kubevela/releases/tag/v1.5.0" target="_blank" rel="noopener noreferrer" class="">KubeVela 1.5</a> was released recently. This release brings more convenient application delivery capabilities to the community, including system observability, CloudShell terminals that move the Vela CLI to the browser, enhanced canary releases, and optimized multi-environment application delivery workflows. It also improved KubeVela's high extensibility as an application delivery platform. The community has started to promote the project to the CNCF Incubation stage. It has absorbed the practice sharing of multiple benchmark users in many community meetings, which proves the community's healthy development. The project is now mature to some extent, and its adoption has made periodical achievements, thanks to the contributions of more than 200 developers in the community.</p>
<p>KubeVela has released five major versions over the past year. Each iteration is a leap forward. The release of version 1.1 brought the ability to connect multiple clusters. Version 1.2/1.3 brought an extended system and a more developer-friendly experience. Version 1.4 introduced a security mechanism in the complete process. The release of 1.5 today brings us closer to KubeVela's vision of <em>making application delivery and management easier.</em> Along the way, we have stayed true to the same design philosophy and built a platform that automates the complexity of the underlying differentiated infrastructure without losing scalability. It helps application developers upgrade from business development to cloud-native R&amp;D at a low cost. Technically, it focuses on the complete process from code to cloud and from application delivery to management. It refines the framework capabilities of connecting infrastructure based on the Open Application Model (OAM). As shown in Figure 1, KubeVela has covered the complete capabilities of application definition, delivery, O&amp;M, and management, all of which are based on OAM scalability (OAM Definition) to connect to ecological projects in an addon way. <strong>In essence, each definition converts the experience of a specific capability into a reusable best practice module, which can be shared by enterprises or communities through addon packaging.</strong></p>
<p><img decoding="async" loading="lazy" src="https://kubevela.io/images/1.5/kubevela-extensiblity.png" alt="kubevela-extensibility" class="img_ev3q"></p>
<p><em>Figure 1: Core Structure of KubeVela Extensibility</em></p>
<p>The blossoming of atomic capabilities in cloud-native is an asset that raises the threshold in the field. Platform builders need to learn a large number of open-source projects and aggregate experience in multiple fields. It often takes months or longer to build a cloud-native support platform for the enterprise. However, the platform often passes the complexity to the application developer, which means they have to learn a lot of additional knowledge. KubeVela's design concept and existing technical achievements may help you quickly enter the cloud-native world. <strong>KubeVela's major addon integration specifications and unified application delivery experience in version 1.5 and previous versions have solved the problem of discrete atomic capabilities in the cloud-native field.</strong></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="addon-specification-upgrade-and-a-more-flexible-definition">Addon Specification Upgrade and a More Flexible Definition<a href="https://kubevela.io/blog/2022/09/17/release.1.5/#addon-specification-upgrade-and-a-more-flexible-definition" class="hash-link" aria-label="Direct link to Addon Specification Upgrade and a More Flexible Definition" title="Direct link to Addon Specification Upgrade and a More Flexible Definition" translate="no">​</a></h2>
<p>The KubeVela addon mechanism has been popular among community users since version 1.2. There are nearly 50 addons in the community addon repository. Nearly 50 developers participated in the contribution of the addon.</p>
<p>Please see <a href="https://github.com/kubevela/catalog" target="_blank" rel="noopener noreferrer" class="">this link</a> for more information</p>
<p>Starting from version 1.5, addon developers could have a better experience. Addon definition, distribution, and visual management are all improved. In addition to using YAML to define addons, developers can fully use CUE to define addons if they want a more flexible combination of addon resources and higher-level parametric control. The current specifications for addon definitions include the following parts:</p>
<ul>
<li class="">
<p>Combined with the resources directory, template.cue or template.yaml is used to define the runtime of an addon. For example, you need to run an Operator behind to extend a workload. This part is optional. For example, some lightweight addons can have no runtime behind them or reuse other runtimes. The combination of YAML and CUE configuration can cover most scenarios.</p>
</li>
<li class="">
<p>The definitions directory, which stores the definition, is the core part of the addon and defines how the capabilities extended by the addon are used by users.</p>
</li>
<li class="">
<p>The schema directory, which is used to assist the definition, defines custom rendering rules for related definitions on the UI side.</p>
</li>
<li class="">
<p>The views directory, which stores the syntax definition of VelaQL, is used to extend the query capabilities of VelaQL.</p>
</li>
<li class="">
<p>Addon metadata definition files like metadata.yaml and readme.md describe the basic information and environment requirements of the addon.</p>
</li>
</ul>
<p>Please refer to <a href="https://kubevela.net/docs/platform-engineers/addon/intro" target="_blank" rel="noopener noreferrer" class="">the document</a> for details.</p>
<p>Here is an example of integrating the delivery capability of the Helm Chart package. Currently, projects in the community like FluxCD or ArgoCD provide the atomic capability of deploying Chart packages. Their implementations are different, and each has its advantages. For KubeVela users, these two projects can be introduced through addons. As shown in Figure 2, we need to define a standard API for the end user to expose the necessary parameters to the end user according to the specific situation of the enterprise.</p>
<p><img decoding="async" loading="lazy" src="https://kubevela.io/images/1.5/kubevela-helm.png" alt="kubevela-helm" class="img_ev3q"></p>
<p><em>Figure 2: Process of KubeVela Extending the Helm Chart Package</em></p>
<p>As shown in Figure 3, according to the standard API, the frontend UI can automatically generate the corresponding interactive page to help the end user easily and conveniently deploy the Helm Chart package. The platform side automatically generates the driver configuration of the underlying capability based on the user's input parameters and addon definitions and intelligently sends the relevant status feedback to the user. These are based on addon specifications, such as integrating FluxCD. This project includes multiple controllers providing different atomic capabilities. First, we use template.cue to define the deployment method of FluxCD and deploy different components based on different parameter inputs. Then, the user experience is defined by definitions and schema directories.</p>
<p>Please see <a href="https://github.com/kubevela/catalog/tree/master/addons/fluxcd" target="_blank" rel="noopener noreferrer" class="">this link</a> for more information.</p>
<p><img decoding="async" loading="lazy" src="https://kubevela.io/images/1.5/helm-ui.png" alt="helm-ui" class="img_ev3q">
<em>Figure 3: Interaction for KubeVela to Deliver Helm Chart Packages</em></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="function-interpretation-based-on-addon-extensions">Function Interpretation Based on Addon Extensions<a href="https://kubevela.io/blog/2022/09/17/release.1.5/#function-interpretation-based-on-addon-extensions" class="hash-link" aria-label="Direct link to Function Interpretation Based on Addon Extensions" title="Direct link to Function Interpretation Based on Addon Extensions" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="telemetry-integrating-prometheus--grafana--exporters-to-support-system-observability">Telemetry Integrating Prometheus + Grafana + Exporters to Support System Observability<a href="https://kubevela.io/blog/2022/09/17/release.1.5/#telemetry-integrating-prometheus--grafana--exporters-to-support-system-observability" class="hash-link" aria-label="Direct link to Telemetry Integrating Prometheus + Grafana + Exporters to Support System Observability" title="Direct link to Telemetry Integrating Prometheus + Grafana + Exporters to Support System Observability" translate="no">​</a></h3>
<p>The system of application observability is closely related to application release. A good application observability system can make the management of application reliability easy. <strong>The KubeVela community includes application observability into the core features.</strong> In version 1.5, the community selected the KubeVela system observability as a case for system capability development. The following key points have been realized:</p>
<ol>
<li class="">
<p><strong>The multi-cluster observable infrastructure is installed through addons easily.</strong> First, we formed an observable addon set around the solution of Prometheus + Grafana + Exporters. It conveniently installs basic capabilities for different basic environments.</p>
</li>
<li class="">
<p><strong>It supports one-click open of multi-cluster Metrics data aggregation and uses the Thanos Query solution</strong> to implement multi-cluster metric aggregation query and visualization. A similar solution will gradually cover the Logger and Tracing dimensions.</p>
</li>
<li class="">
<p><strong>Grafana IaC:</strong> The configuration of Grafana data sources and dashboards are described through application models. The innovative application of extensible API makes the Grafana API change into runtime that KubeVela can operate.</p>
</li>
<li class="">
<p><strong>The Grafana dashboard is generated automatically.</strong> You can enable the Grafana addon to generate a KubeVela system observability dashboard automatically.</p>
</li>
</ol>
<p>Figure 4 shows the dashboard of KubeVela system operating indicators. The dashboard is automatically generated through the IaC system. You only need to enable the corresponding addon.</p>
<p><img decoding="async" loading="lazy" src="https://kubevela.io/images/1.5/system-dashboard.png" alt="system dashboard" class="img_ev3q">
<em>Figure 4: KubeVela System Observable Dashboard</em></p>
<p>Figure 5 shows the monitoring dashboard of the Kubernetes API Server service connected to KubeVela. Use addons to issue Exporters to all sub-clusters, expose data to the Prometheus service of each cluster, and aggregate it to the control cluster for centralized visualization. You can complete the data monitoring and dashboard access of many clusters at the same time.</p>
<p><img decoding="async" loading="lazy" src="https://kubevela.io/images/1.5/apiserver-dashboard.png" alt="apiserver dashboard" class="img_ev3q">
<em>Figure 5: KubeVela Multi-Cluster API Observation Dashboard</em></p>
<p>In the next release, the community will gradually integrate the unified description and delivery of application observability into the application delivery process. It covers Metric, Logger, and Tracing data acquisition, intermediate processing and transmission, storage and analysis, alerts and visualizations, and applications to the complete process of the application release workflow.</p>
<p>Reference: <a href="https://kubevela.net/docs/platform-engineers/operations/observability" target="_blank" rel="noopener noreferrer" class="">https://kubevela.net/docs/platform-engineers/operations/observability</a></p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="integrate-cloudshell-for-cli-and-ui-collaborated-application-delivery">Integrate CloudShell for CLI and UI Collaborated Application Delivery<a href="https://kubevela.io/blog/2022/09/17/release.1.5/#integrate-cloudshell-for-cli-and-ui-collaborated-application-delivery" class="hash-link" aria-label="Direct link to Integrate CloudShell for CLI and UI Collaborated Application Delivery" title="Direct link to Integrate CloudShell for CLI and UI Collaborated Application Delivery" translate="no">​</a></h3>
<p>Manipulating application delivery through a CLI black screen is convenient, easily replicated, and can be done in batches. Developers are fond of it. Delivering application interactions through UI is more elegant. Process operations help reduce learning costs and achieve stricter enterprise security controls. A high degree of visualization can help us master the application and perform relevant operations anytime and anywhere. KubeVela was very different in the CLI and UI dimensions in the past version, and data in the two dimensions do not communicate with each other. If the two terminal methods can be combined, application delivery and management can be smoother. In version 1.5, KubeVela introduced the CloudShell addon, which provides a Web Shell terminal for UI users. The unified portal solves the problem of CLI and UI separation and brings more capabilities. The main changes to this process are listed below:</p>
<ol>
<li class="">
<p><strong>Convenient Toolset:</strong> Unlike other platforms, which mainly provide Web Shell capabilities for entering the application runtime, CloudShell generates a terminal environment for each user, including CLI tools (such as Vela and Kubectl). You can manage multiple applications in the same environment.</p>
</li>
<li class="">
<p><strong>Automatic Authorization:</strong> Users do not need to care about how to allocate KubeConfig. The system automatically completes the authorization of the black screen environment according to the permissions owned by UI users, thus realizing the consistency of basic permissions between the white screen and black screen.</p>
</li>
<li class="">
<p><strong>Automatic Environment Recycling:</strong> The maximum survival time of each user's terminal environment is one hour. Automatic recycling after expiration prevents excessive resource consumption.</p>
</li>
<li class="">
<p><strong>Enhanced Vela CLI Capability:</strong> It re-implemented log, status, exec, port-forward, and other operation commands for Debug applications, realizing seamless compatibility for differentiated workloads under applications, which allows users to complete relevant operations without awareness. Whether it is the basic Deployment resource, a Helm-packaged load resource set, or a custom Operator-driven workload, Vela can automatically discover the underlying operation objects related to commands.</p>
</li>
<li class="">
<p><strong>Data Automatic Synchronization:</strong> CLI can create and update applications. Changes will be visualized on the UI until the user chooses to take over the application and subsequent releases through UI.</p>
</li>
</ol>
<p><img decoding="async" loading="lazy" src="https://kubevela.io/images/1.5/cloud-shell.png" alt="cloud shell" class="img_ev3q">
<em>Figure 6: KubeVela CloudShell Operating Terminal</em></p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="integrate-openkruise-rollout-to-provide-canary-release-capabilities">Integrate OpenKruise Rollout to Provide Canary Release Capabilities<a href="https://kubevela.io/blog/2022/09/17/release.1.5/#integrate-openkruise-rollout-to-provide-canary-release-capabilities" class="hash-link" aria-label="Direct link to Integrate OpenKruise Rollout to Provide Canary Release Capabilities" title="Direct link to Integrate OpenKruise Rollout to Provide Canary Release Capabilities" translate="no">​</a></h3>
<p>The KubeVela community incubated the Rollout project in the early days, similar to the implementation model of Argo Rollout. It works in the form of a new workload, mainly realizing the ability to release in batches. With the development of the community, KubeVela focuses more on the application global control layer and addon extension capabilities. Therefore, the rollout implementation at the workload level has been transferred to the OpenKruise community. With the joint efforts of both parties, canary release capabilities can be implemented for various workloads (such as native Deployment, StatefulSet, and OpenKruise extended workload CloneSet). At the same time, when it coexists with the Helm delivery mode in KubeVela, it can implement the canary release for Helm chart package applications without any changes. This is innovative in the industry and very convenient for users. Kruise Rollout is integrated into the KubeVela ecosystem as an addon. KubeVela users only need to enable addons to configure Rollout Trait in application components. At the same time, it can cooperate with gateway rules (such as Gateway and HTTPRoute). This implementation has the following advantages:</p>
<ol>
<li class="">
<p><strong>No Intrusion and Binding:</strong> Rollout capability is introduced through the bypass, and users do not need to make other changes to the existing application configuration. The introduction cost is low and can be removed at any time.</p>
</li>
<li class="">
<p><strong>Easy to Use:</strong> With a simple switching rule of the traffic configuration, combined with KubeVela's UI visualization, you can effectively observe the change in the number of replicas in the Rollout process and the additional resource relationship introduced.</p>
</li>
<li class="">
<p><strong>Good Compatibility:</strong> No matter what workload the user uses for packaging (Helm or custom Operator), Rollout can work in bypass form after discovering the current underlying load resources.</p>
</li>
</ol>
<p>Reference: <a href="https://kubevela.net/docs/end-user/traits/rollout" target="_blank" rel="noopener noreferrer" class="">https://kubevela.net/docs/end-user/traits/rollout</a></p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="velaux-adds-multi-environment-differentiated-visualized-configuration">VelaUX Adds Multi-Environment Differentiated Visualized Configuration<a href="https://kubevela.io/blog/2022/09/17/release.1.5/#velaux-adds-multi-environment-differentiated-visualized-configuration" class="hash-link" aria-label="Direct link to VelaUX Adds Multi-Environment Differentiated Visualized Configuration" title="Direct link to VelaUX Adds Multi-Environment Differentiated Visualized Configuration" translate="no">​</a></h3>
<p>VelaUX has had the multi-environment deployment capability since its launch. Until version 1.5, it supports the differentiation of multiple environments for user visual editing, truly matching the needs of user multi-environment application release. Override Policy configurations support the dimension differentiation of environments, clusters, or namespaces and the unified management of application baseline and configurations..</p>
<p>As shown in Figure 7, the Application Policy has a variety of available options built in, including differentiated configuration, application multi-cluster policies, application maintenance policies, and GC policies. Users can easily configure corresponding policies according to their needs through UI guidance.</p>
<p><img decoding="async" loading="lazy" src="https://kubevela.io/images/1.5/create-policy.png" alt="create policy" class="img_ev3q">
<em>Figure 7: KubeVela Policy Add/Edit Window</em></p>
<p>In version 1.5, the following convenient features are added before and after deployment for different environments:</p>
<ul>
<li class="">
<p><strong>DryRun (Trial Run) Capability:</strong> You can perform a DryRun before deploying an environment. Then, you can evaluate whether the application configuration meets expectations based on the UI feedback results to prevent the incorrect configuration from affecting the stability of online services after deployment.</p>
</li>
<li class="">
<p><strong>Environment Difference Insight:</strong> When switching to different environment views, the comparison of local configuration and deployment configuration is automatically compared. If there is a difference, the user will be prompted, and the configuration items of the difference will be displayed. It can prevent configuration drift or forgetting to go online for configurations scheduled to go online.</p>
</li>
<li class="">
<p><strong>Version Detail Query and Difference Comparison:</strong> You can view the application configuration rendering results of each version on the Version Management page. You can also compare the version configuration with the current running configuration or the latest local configuration. It is convenient for users to track the configuration change process.</p>
</li>
</ul>
<p>Reference: <a href="https://kubevela.net/docs/tutorials/multi-env" target="_blank" rel="noopener noreferrer" class="">https://kubevela.net/docs/tutorials/multi-env</a></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="improve-application-engine-capabilities">Improve Application Engine Capabilities<a href="https://kubevela.io/blog/2022/09/17/release.1.5/#improve-application-engine-capabilities" class="hash-link" aria-label="Direct link to Improve Application Engine Capabilities" title="Direct link to Improve Application Engine Capabilities" translate="no">​</a></h2>
<p>In addition to the preceding addon capabilities, a large number of updates have been made to the application engine. The performance is significantly improved, and the CPU consumption during workflow execution is reduced by 75%. The number of parallel executions has increased significantly. The important changes are listed below:</p>
<ol>
<li class="">
<p>Timeout control is added to Workflow. In the Workflow step, configure the timeout period. When the execution time is greater than the timeout period, Workflow will end and become terminated.</p>
</li>
<li class="">
<p>Workflow adds conditional judgment. Configure the If field in the Workflow step and support reading data from status or input to determine whether the current step needs to be executed. It also supports the If Always mechanism and supports scenarios where some steps need to be executed under any circumstances.</p>
</li>
<li class="">
<p>Workflow supports display switching mode, DAG, or the default StepByStep.</p>
</li>
<li class="">
<p>Add a shared resource policy. Different applications can describe the same resources, such as a namespace or a ConfigMap. If you set this parameter to a shared resource, it does not conflict.</p>
</li>
<li class="">
<p>The optimization of the application resource construction algorithm improves query efficiency in different scenarios and makes it easier to extend custom rules. It also adds some default rules.</p>
</li>
</ol>
<p>Please refer to <a href="https://github.com/kubevela/kubevela/releases/tag/v1.5.0" target="_blank" rel="noopener noreferrer" class="">this link</a> for more information about changes.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="summary">Summary<a href="https://kubevela.io/blog/2022/09/17/release.1.5/#summary" class="hash-link" aria-label="Direct link to Summary" title="Direct link to Summary" translate="no">​</a></h2>
<p>Overall, KubeVela 1.5 has made significant progress in multiple dimensions (such as product capabilities, community ecology, and benchmark users). User cases include finance, intelligent manufacturing, the Internet, and other industries. We expect more users to share practical experiences and help the KubeVela community find a more accurate way forward. Version 1.6 plans to bring more complete application observability, independent application workflow capabilities, continuous release control of multiple applications, and collaboration with observable systems. Developers with relevant needs and ideas can participate in community discussions at any time.</p>]]></content>
        <author>
            <name>Qingguo Zeng</name>
            <uri>https://github.com/barnettZQG</uri>
        </author>
        <category label="KubeVela" term="KubeVela"/>
        <category label="release-note" term="release-note"/>
        <category label="Kubernetes" term="Kubernetes"/>
        <category label="DevOps" term="DevOps"/>
        <category label="CNCF" term="CNCF"/>
        <category label="CI/CD" term="CI/CD"/>
        <category label="Application delivery" term="Application delivery"/>
        <category label="Role-Based Access Control" term="Role-Based Access Control"/>
        <category label="Telemetry" term="Telemetry"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[The Canary Rollout of the Helm Chart Application Is Coming!]]></title>
        <id>https://kubevela.io/blog/2022/08/17/helm-rollout/</id>
        <link href="https://kubevela.io/blog/2022/08/17/helm-rollout/"/>
        <updated>2022-08-17T00:00:00.000Z</updated>
        <content type="html"><![CDATA[<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="background">Background<a href="https://kubevela.io/blog/2022/08/17/helm-rollout/#background" class="hash-link" aria-label="Direct link to Background" title="Direct link to Background" translate="no">​</a></h2>
<p>Helm is an application packaging and deployment tool of client side widely used in the cloud-native field. Its simple design and easy-to-use features have been recognized by users and formed its ecosystem. Up to now, thousands applications have been packaged using Helm Chart. Helm's design concept is very concise and can be summarized in the following two aspects:</p>
<ol>
<li class="">
<p>Packaging and templating complex Kubernetes APIs and then abstracting and simplifying them into small number of parameters</p>
</li>
<li class="">
<p><strong>Giving Application Lifecycle Solutions:</strong> Production, upload (hosting), versioning, distribution (discovery), and deployment.</p>
</li>
</ol>
<p>These two design principles ensure that Helm is flexible and simple enough to cover all Kubernetes APIs, which solves the problem of one-off cloud-native application delivery. However, for enterprises with a certain scale, using Helm for continuous software delivery poses quite a challenge.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="challenges-of-the-continuous-delivery-of-helm">Challenges of the Continuous Delivery of Helm<a href="https://kubevela.io/blog/2022/08/17/helm-rollout/#challenges-of-the-continuous-delivery-of-helm" class="hash-link" aria-label="Direct link to Challenges of the Continuous Delivery of Helm" title="Direct link to Challenges of the Continuous Delivery of Helm" translate="no">​</a></h2>
<p>Helm was initially designed to ensure simplicity and ease of use instead of complex component orchestration. Therefore, <strong>Helm delivers all resources to Kubernetes clusters during the application deployment. It is expected to solve application dependency and orchestration problems automatically using Kubernetes' final-state oriented self-healing capabilities.</strong> Such a design may not be a problem during its first deployment, but it is too idealistic for the enterprise with a certain scale of production environment.</p>
<p>On the one hand, updating all resources when the application is upgraded may easily cause overall service interruption due to the short-term unavailability of some services. On the other hand, if there is a bug in the software, it cannot be rolled back in time, which may cause more trouble and make it difficult to control. In some serious scenarios, if some configurations in the production environment have been manually modified in O&amp;M, the original modifications would be overwritten due to the one-off deployment of Helm. What's more, the previous versions of Helm may be inconsistent with the production environment, so it cannot be recovered using rollback. All of these add up to a larger area of failure.</p>
<p><strong>Thus, with a certain scale, the grayscale and rollback capabilities of the software in the production environment are extremely important, and Helm itself cannot guarantee sufficient stability.</strong></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="how-do-we-enable-canary-rollout-for-helm">How Do We Enable Canary-Rollout for Helm?<a href="https://kubevela.io/blog/2022/08/17/helm-rollout/#how-do-we-enable-canary-rollout-for-helm" class="hash-link" aria-label="Direct link to How Do We Enable Canary-Rollout for Helm?" title="Direct link to How Do We Enable Canary-Rollout for Helm?" translate="no">​</a></h2>
<p>Typically, a rigorous software upgrade process follows a similar process: It is roughly divided into three stages. The first stage upgrades small number of pods (such as 20% ) and switches a small amount of traffic to the new version. After completing this stage, the upgrade is paused first. After manual confirmation, continue the second phase, which is to upgrade a larger proportion of pods and traffic (such as 90% ), and pause again for manual confirmation. In the final stage, the full upgrade to the new version is completed, and the verification is completed, thus the entire rollout process is completed. If any exceptions, including business metrics, are found during the upgrade, such as an increase in the CPU or memory usage rate or excessive log requests error 500, you can roll back quickly.</p>
<p><img decoding="async" loading="lazy" alt="image" src="https://kubevela.io/assets/images/rollout-step-aac2542c8f43139ed677cadab9565e19.jpg" width="1288" height="694" class="img_ev3q"></p>
<p>The image above is a typical canary rollout scenario, <em>so how do we complete the above process for the Helm chart application?</em> There are two typical ways in the industry:</p>
<ol>
<li class=""><strong>Modify the Helm chart to change workloads into two copies and expose different Helm parameters.</strong> During the rollout, the images, number of pods, and traffic ratio of the two workloads are continuously modified to implement the canary rollout.</li>
<li class=""><strong>Modify the Helm chart to change the original basic workload to a custom workload with the same features and with phased rollout capabilities and expose the Helm parameters.</strong> It's these canary rollout CRDs that are manipulated during the canary rollout.</li>
</ol>
<p>The two solutions are complex with considerable modification costs, especially <strong>when your Helm chart is a third-party component that cannot be modified or cannot maintain a Helm chart.</strong> Even if the two are modified, there are still stability risks compared to the original simple workload model. The reason is that <strong>Helm is only a package management tool, and it is incompatible with the canary rollout or workloads management.</strong></p>
<p>When we have in-depth communication with large number of users in the community, we find that most users' applications are not complicated, among which the most are classic types (such as Deployment and StatefulSet). Therefore, through the powerful addon mechanism of <a href="https://kubevela.net/" target="_blank" rel="noopener noreferrer" class="">KubeVela</a> and the <a href="https://openkruise.io/" target="_blank" rel="noopener noreferrer" class="">OpenKruise</a> community, we have made a canary rollout KubeVela Addon for these qualified types. <strong>This addon helps you easily complete the canary rollout of the Helm chart without any migration and modification.</strong> Also, if your Helm chart is more complicated, you can customize an addon for your scenario to get the same experience.
Let's take you through a practical example (using Deployment Workload as an example) to get a glimpse of the complete process.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="use-kubevela-for-canary-rollout">Use KubeVela for Canary Rollout<a href="https://kubevela.io/blog/2022/08/17/helm-rollout/#use-kubevela-for-canary-rollout" class="hash-link" aria-label="Direct link to Use KubeVela for Canary Rollout" title="Direct link to Use KubeVela for Canary Rollout" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="prepare-the-environment">Prepare the Environment<a href="https://kubevela.io/blog/2022/08/17/helm-rollout/#prepare-the-environment" class="hash-link" aria-label="Direct link to Prepare the Environment" title="Direct link to Prepare the Environment" translate="no">​</a></h3>
<ul>
<li class="">Install KubeVela</li>
</ul>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">$ curl -fsSL https://kubevela.io/script/install-velad.sh | bash</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">velad install</span><br></span></code></pre></div></div>
<p>See <a href="https://kubevela.net/docs/install#1-install-velad" target="_blank" rel="noopener noreferrer" class="">this document</a> for more installation details.</p>
<ul>
<li class="">Enable related addon</li>
</ul>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela addon enable fluxcd</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela addon enable ingress-nginx</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela addon enable kruise-rollout</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela addon enable velaux</span><br></span></code></pre></div></div>
<p>In this step, the following addons are started:</p>
<ol>
<li class="">The fluxcd addon helps us enable the capability of Helm delivery.</li>
<li class="">The ingress-nginx addon is used to provide traffic management capabilities of canary rollout.</li>
<li class="">The kruise-rollout provides canary rollout capability.</li>
<li class="">The velaux addon provides interface operation and visualization.</li>
</ol>
<ul>
<li class="">Map the Nginx ingress-controller port to local</li>
</ul>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela port-forward addon-ingress-nginx -n vela-system</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="first-deployment">First Deployment<a href="https://kubevela.io/blog/2022/08/17/helm-rollout/#first-deployment" class="hash-link" aria-label="Direct link to First Deployment" title="Direct link to First Deployment" translate="no">​</a></h3>
<p>Run the following command to deploy the Helm application for the first time. In this step, the deployment is done through KubeVela's CLI tool. If you are familiar with Kubernetes, you can also deploy through kubectl apply. The two work the same.</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">cat &lt;&lt;EOF | vela up -f -</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">apiVersion: core.oam.dev/v1beta1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">kind: Application</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">metadata:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  name: canary-demo</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  annotations:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    app.oam.dev/publishVersion: v1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">spec:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  components:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  - name: canary-demo</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    type: helm</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    properties:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      repoType: "helm"</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      url: "https://wangyikewxgm.github.io/my-charts/"</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      chart: "canary-demo"</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      version: "1.0.0"</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    traits:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    - type: kruise-rollout</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      properties:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        canary:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          # The first batch of Canary releases 20% Pods, and 20% traffic imported to the new version, require manual confirmation before subsequent releases are completed</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          steps:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          - weight: 20</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          # The second batch of Canary releases 90% Pods, and 90% traffic imported to the new version.</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          - weight: 90</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          trafficRoutings:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          - type: nginx</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">EOF</span><br></span></code></pre></div></div>
<p>In the example above, we declare an application named canary-demo, which contains a Helm-type component (KubeVela also supports other types of component deployment), and the parameter of the component contains information (such as chart address and version).</p>
<p>In addition, we declare the kruise-rollout OAM trait for this component, which are the capabilities added to the component after the kruise-rollout addon is installed. The upgrade policy of Helm can be specified. In the first stage, 20% of pods and traffic are upgraded. After manual approve, 90% is upgraded. Finally, the full version is upgraded to the latest version.</p>
<p><em>Note:</em> We have <a href="https://github.com/wangyikewxgm/my-charts/tree/main/canary-demo" target="_blank" rel="noopener noreferrer" class="">prepared a chart</a> to demonstrate the intuitive effect (reflecting the version changes). The body of the Helm chart contains a Deployment and Ingress object, which is the most common scenario when the Helm chart is made. If your Helm chart is also equipped with the resources above, you can also use this example to canary rollout your helm chart.</p>
<p>After the deployment is successful, we use the following command to access the gateway address in your cluster, and you will see the following result:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">$ curl -H "Host: canary-demo.com" http://localhost:8080/version</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Demo: V1</span><br></span></code></pre></div></div>
<p>In addition, through the resource topology graph of VelaUX, we can see that the five V1 pods are all ready.</p>
<p><img decoding="async" loading="lazy" alt="image" src="https://kubevela.io/assets/images/helm-rollout-v1-849f9b36c1e41eb4103f2f9368f16e6e.jpg" width="1761" height="806" class="img_ev3q"></p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="upgrade-an-application">Upgrade an Application<a href="https://kubevela.io/blog/2022/08/17/helm-rollout/#upgrade-an-application" class="hash-link" aria-label="Direct link to Upgrade an Application" title="Direct link to Upgrade an Application" translate="no">​</a></h3>
<p>Apply the following yaml to upgrade your application:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">cat &lt;&lt;EOF | vela up -f -</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">apiVersion: core.oam.dev/v1beta1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">kind: Application</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">metadata:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  name: canary-demo</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  annotations:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    app.oam.dev/publishVersion: v2</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">spec:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  components:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  - name: canary-demo</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    type: helm</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    properties:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      repoType: "helm"</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      url: "https://wangyikewxgm.github.io/my-charts/"</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      chart: "canary-demo"</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      # Upgade to version 2.0.0</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      version: "2.0.0"</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    traits:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    - type: kruise-rollout</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      properties:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        canary:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          # The first batch of Canary releases 20% Pods, and 20% traffic imported to the new version, require manual confirmation before subsequent releases are completed</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          steps:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          - weight: 20</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          # The second batch of Canary releases 90% Pods, and 90% traffic imported to the new version.</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          - weight: 90</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          trafficRoutings:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          - type: nginx</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">EOF</span><br></span></code></pre></div></div>
<p>We noticed that the new application only has two changes compared to the first deployment:</p>
<ol>
<li class="">
<p>We upgrade the annotation of the app.oam.dev/publishVersion from V1 to V2. This shows this revision is a new version.</p>
</li>
<li class="">
<p>We upgrade the version of the Helm chart to 2.0.0. The tag of the deployment image in this version of the chart is upgraded to V2.</p>
</li>
</ol>
<p>After a while, we will find that the upgrade process stops at the first batch we defined above. Only 20% of pods and traffic are upgraded. At this time, if you execute the command above to access the gateway multiple times, you will find that Demo: V1 and Demo: V2 appear alternately, and there is a probability of almost 20% of getting the result of Demo: V2.</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">$ curl -H "Host: canary-demo.com" http://localhost:8080/version</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Demo: V2</span><br></span></code></pre></div></div>
<p>Looking at the topology status of the application resources again, you will see that the rollout CR created by the kruise-rollout trait has created a new version of the pod for us, while the five old version pods created by the previous workload remain unchanged.</p>
<p><img decoding="async" loading="lazy" alt="image" src="https://kubevela.io/assets/images/helm-rollout-v2-2a59fa09805ad0e07a35107dc136028a.jpg" width="1802" height="884" class="img_ev3q"></p>
<p>Next, we execute the following command through KubeVela's CLI to resume the upgrade through manual review:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">$ vela workflow resume canary-demo</span><br></span></code></pre></div></div>
<p>After a while, we saw that five new versions of pods were created through the resource topology diagram. At this time, if we visit the gateway again, we will find that the probability of Demo: V2 has increased significantly, which is close to 90%.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="quick-rollback">Quick Rollback<a href="https://kubevela.io/blog/2022/08/17/helm-rollout/#quick-rollback" class="hash-link" aria-label="Direct link to Quick Rollback" title="Direct link to Quick Rollback" translate="no">​</a></h3>
<p>Generally, in the rollout of a real-world scenario, after a manual review, it is found that the status of the new version of the application is abnormal. You need to terminate the current upgrade and quickly roll back the application to the version before the upgrade starts.</p>
<p>We can execute the following command to suspend the current publishing workflow first:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">$ vela workflow suspend canary-demo</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Rollout default/canary-demo in cluster  suspended.</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Successfully suspend workflow: canary-demo</span><br></span></code></pre></div></div>
<p>Then, roll back to the version before the rollout, which is V1:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">$ vela workflow rollback canary-demo</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Application spec rollback successfully.</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Application status rollback successfully.</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Rollout default/canary-demo in cluster  rollback.</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Successfully rollback rolloutApplication outdated revision cleaned up.</span><br></span></code></pre></div></div>
<p>At this time, when we access the gateway again, we will find that all the request results have returned to the V1 state:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">$ curl -H "Host: canary-demo.com" http://localhost:8080/version</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Demo: V1</span><br></span></code></pre></div></div>
<p>At this time, we can see that all pods of the canary version have been deleted through the resource topology diagram, and from the beginning to the end, the five pods of V1, as the pods of the stable version, remain unchanged.</p>
<p><img decoding="async" loading="lazy" alt="image" src="https://kubevela.io/assets/images/helm-rollout-v1-849f9b36c1e41eb4103f2f9368f16e6e.jpg" width="1761" height="806" class="img_ev3q"></p>
<p>If you change the rollback operation above to resume the upgrade, the subsequent upgrade process will continue to complete the full rollout.</p>
<p>Please see <a href="https://kubevela.net/docs/tutorials/helm" target="_blank" rel="noopener noreferrer" class="">this link</a> for the complete operation procedure of the preceding demo.</p>
<p>Please refer to <a href="https://kubevela.net/docs/tutorials/k8s-object-rollout" target="_blank" rel="noopener noreferrer" class="">this link</a> if you want to directly use native Kubernetes resources to implement the process above.</p>
<p>In addition to Deployment, the kruise-rollout addon supports StatefulSet and OpenKruise CloneSet. If the workload types in your chart are one of the three types mentioned above, canary rollout can be implemented through the example above.</p>
<p>I believe you can also notice that the example above is a nginx-Ingress-controller-based seven-layer traffic splitting scheme. In addition, we support <a href="https://gateway-api.sigs.k8s.io/" target="_blank" rel="noopener noreferrer" class="">Kubernetes Gateway's API</a> to support more gateway types and four-layer traffic splitting schemes.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="how-can-the-stability-of-the-rollout-be-guaranteed">How Can the Stability of the Rollout Be Guaranteed?<a href="https://kubevela.io/blog/2022/08/17/helm-rollout/#how-can-the-stability-of-the-rollout-be-guaranteed" class="hash-link" aria-label="Direct link to How Can the Stability of the Rollout Be Guaranteed?" title="Direct link to How Can the Stability of the Rollout Be Guaranteed?" translate="no">​</a></h2>
<p>After the first deployment, the kruise rollout addon (hereinafter referred to as rollout) listens to the resources deployed by the Helm chart, which are deployment, service, and ingress in the example. StatefulSet and OpenKruise Cloneset are also supported. The rollout will take over the subsequent upgrade actions of this deployment.</p>
<p>During the upgrade, the new version of Helm takes effect first, and the deployment image is updated to V2. However, <strong>the upgrade process of the deployment will be taken over by the rollout process from the controller-manager</strong>, so the pods under the deployment will not be upgraded. At the same time, the rollout will copy a canary version of deployment, with V2 as the tag of the image, and create a service to filter the pods below it, together with an ingress pointing to this service. Finally, this ingress will receive the traffic of the canary version by setting the annotation corresponding to the ingress, thus enabling traffic splitting. For details, Please see <a href="https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#canary" target="_blank" rel="noopener noreferrer" class="">this link</a>.</p>
<p><strong>After all manual confirmation steps are passed, and the full rollout is completed, the rollout will return the upgrade control of deployment of the stable version to the controller-manager. At that time, the stable version of pods will be upgraded to the new version one after another. When the stable version pods are all ready, the canary version of deployment, service, and ingress will be destroyed one after another, thus ensuring that the request traffic will not hit the unready pod during the whole process nor cause abnormal requests.</strong></p>
<p>After that, we will continue to iterate in the following areas to support more scenarios and bring a more stable and reliable upgrade experience:</p>
<ol>
<li class="">The upgrade process is connected to KubeVela's workflow system, thus introducing a richer system of intermediate steps to expand the system and supporting functions (such as sending notifications through the workflow during the upgrade process). Even in the pause phase of each step, it can connect to the external observability system and automatically decide whether to continue publishing or roll back by checking indicators (such as logs or monitoring) to implement unattended publishing policies.</li>
<li class="">It integrates with more addons (such as istio) to support the traffic splitting solution of Service Mesh.</li>
<li class="">In addition to the percentage-based traffic splitting method, header-or cookie-based traffic splitting rules and features (such as blue-green publishing) are supported.</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="summary">Summary<a href="https://kubevela.io/blog/2022/08/17/helm-rollout/#summary" class="hash-link" aria-label="Direct link to Summary" title="Direct link to Summary" translate="no">​</a></h2>
<p>As mentioned earlier, Helm's canary rollout process is implemented by KubeVela through the addon system. fluxcd addon helps us deploy and manage the lifecycle of the Helm chart. The kruise-rollout addon helps us upgrade the workload pod and switch traffic during the upgrade process. By combining two addons, the full lifecycle management and canary upgrade of Helm applications are realized without any changes to your Helm chart. You can also <a href="https://kubevela.io/docs/platform-engineers/addon/intro" target="_blank" rel="noopener noreferrer" class="">write addon</a> for your scenarios to complete more special scenes or processes.</p>
<p><strong>Based on KubeVela's powerful scalability, you can flexibly combine these addons and dynamically replace the underlying capabilities according to different platforms or environments without any changes to the upper-level applications.</strong> For example, if you prefer to use argocd instead of fluxcd to implement the deployment of Helm applications, you can implement the same function by enabling the addon of argocd without any changes or migration at the upper-layer of Helm applications.</p>
<p>Now, the KubeVela community has provided dozens of addons, which can help the platform expand its capabilities in observability, GitOps, FinOps, rollout, etc.</p>
<p><img decoding="async" loading="lazy" alt="image" src="https://kubevela.io/assets/images/addon-list-9fa0714d5b3ffbd3306e42e471a6d9e2.jpg" width="1851" height="1149" class="img_ev3q"></p>
<p>You can find Addon's warehouse address <a href="https://github.com/kubevela/catalog" target="_blank" rel="noopener noreferrer" class="">here</a>. If you are interested in addons, you are welcome to submit your custom addon and contribute new ecological capabilities to the community!</p>]]></content>
        <author>
            <name>Yike Wang</name>
            <uri>https://github.com/kubevela/kubevela</uri>
        </author>
        <category label="KubeVela" term="KubeVela"/>
        <category label="use-case" term="use-case"/>
        <category label="helm chart" term="helm chart"/>
        <category label="Canary Rollout" term="Canary Rollout"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[How to migrate Existing Terraform Cloud Resources to KubeVela]]></title>
        <id>https://kubevela.io/blog/2022/07/20/migrate-erraform-cloud-resources-to-kubeVela/</id>
        <link href="https://kubevela.io/blog/2022/07/20/migrate-erraform-cloud-resources-to-kubeVela/"/>
        <updated>2022-07-20T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This blog discusses how to migrate existing Terraform cloud resources to KubeVela.]]></summary>
        <content type="html"><![CDATA[<p>You may have learned from <a class="" href="https://kubevela.io/blog/2022/06/27/terraform-integrate-with-vela/">this blog</a> that we can use vela to manage cloud resources (like s3 bucket, AWS EIP and so on) via the terraform plugin. We can create an application which contains some cloud resource components and this application will generate these cloud resources, then we can use vela to manage them.</p>
<p>Sometimes we already have some Terraform cloud resources which may be created and managed by the Terraform binary or something else. In order to have <a class="" href="https://kubevela.io/blog/2022/06/27/terraform-integrate-with-vela/#part-1-glue-terraform-module-as-kubevela-capability">the benefits of using KubeVela to manage the cloud resources</a> or just maintain consistency in the way you manage cloud resources, we may want to import these existing Terraform cloud resources into KubeVela and use vela to manage them. But if we just create an application which describes these cloud resources, the cloud resources will be recreated and may lead to errors. To fix this problem, we made <a href="https://github.com/kubevela/terraform-controller/tree/master/hack/tool/backup_restore" target="_blank" rel="noopener noreferrer" class="">a simple <code>backup_restore</code> tool</a>. This blog will show you how to use the <code>backup_restore</code> tool to import your existing Terraform cloud resources into KubeVela.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-1-create-terraform-cloud-resources">Step 1: Create Terraform Cloud Resources<a href="https://kubevela.io/blog/2022/07/20/migrate-erraform-cloud-resources-to-kubeVela/#step-1-create-terraform-cloud-resources" class="hash-link" aria-label="Direct link to Step 1: Create Terraform Cloud Resources" title="Direct link to Step 1: Create Terraform Cloud Resources" translate="no">​</a></h2>
<p>Since we are going to demonstrate how to import an existing cloud resource into KubeVela, we need to create one first. If you already have such resources, you can skip this step.</p>
<p>Before start, make sure you have:</p>
<ul>
<li class="">Installed <a href="https://www.terraform.io/downloads" target="_blank" rel="noopener noreferrer" class="">terraform CLI</a>.</li>
<li class="">Have a Cloud Service credentials, in this article, we will use aws as example.</li>
<li class="">Learn the basic knowledge of <a href="https://www.terraform.io/language" target="_blank" rel="noopener noreferrer" class="">how to use terraform</a>.</li>
</ul>
<p>Let's get started!</p>
<ol>
<li class="">
<p>Create an empty directory to start.</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">mkdir -p cloud-resources</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">cd cloud-resources</span><br></span></code></pre></div></div>
</li>
<li class="">
<p>Create a file named <code>main.tf</code> which will create a S3 bucket:</p>
<div class="language-hcl codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-hcl codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">resource "aws_s3_bucket" "bucket-acl" {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    bucket = var.bucket</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    acl    = var.acl</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">output "RESOURCE_IDENTIFIER" {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    description = "The identifier of the resource"</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    value       = aws_s3_bucket.bucket-acl.bucket_domain_name</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">output "BUCKET_NAME" {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    value       = aws_s3_bucket.bucket-acl.bucket_domain_name</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    description = "The name of the S3 bucket"</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">variable "bucket" {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    description = "S3 bucket name"</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    default     = "vela-website"</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    type        = string</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">variable "acl" {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    description = "S3 bucket ACL"</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    default     = "private"</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    type        = string</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span></code></pre></div></div>
</li>
<li class="">
<p>Configure the AWS Cloud provider credentials:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">export AWS_ACCESS_KEY_ID="your-accesskey-id"</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">export AWS_SECRET_ACCESS_KEY="your-accesskey-secret"</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">export AWS_DEFAULT_REGION="your-region-id"</span><br></span></code></pre></div></div>
</li>
<li class="">
<p>Set the variables in the <code>main.tf</code> file:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">export TF_VAR_acl="private"; export TF_VAR_bucket="your-bucket-name"</span><br></span></code></pre></div></div>
</li>
<li class="">
<p>(Optional) Create a <code>backend.tf</code> to configure your Terraform backend. We just use the default local backend in this example.</p>
</li>
<li class="">
<p>Run <code>terraform init</code> and <code>terraform apply</code> to create the S3 bucket:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">terraform init &amp;&amp; terraform apply</span><br></span></code></pre></div></div>
</li>
<li class="">
<p>Check the S3 bucket list to make sure the bucket is created successfully.</p>
</li>
<li class="">
<p>Run <code>terraform state pull</code> to get the Terraform state of the cloud resource and store it into a local file:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">terraform state pull &gt; state.json</span><br></span></code></pre></div></div>
</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-2-import-existing-terraform-cloud-resources-into-kubevela">Step 2: Import Existing Terraform Cloud Resources into KubeVela<a href="https://kubevela.io/blog/2022/07/20/migrate-erraform-cloud-resources-to-kubeVela/#step-2-import-existing-terraform-cloud-resources-into-kubevela" class="hash-link" aria-label="Direct link to Step 2: Import Existing Terraform Cloud Resources into KubeVela" title="Direct link to Step 2: Import Existing Terraform Cloud Resources into KubeVela" translate="no">​</a></h2>
<ol>
<li class="">
<p>Create the <code>application.yaml</code> file, please ensure that the description of each field of Component is consistent with your cloud resource configuration:</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token key atrule">apiVersion</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> core.oam.dev/v1beta1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> Application</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">metadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> app</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">aws</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">s3</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">spec</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">components</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> sample</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">s3</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> aws</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">s3</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">bucket</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> vela</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">website</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token number">202110191745</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">acl</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> private</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">writeConnectionSecretToRef</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> s3</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">conn</span><br></span></code></pre></div></div>
</li>
<li class="">
<p>Get the <a href="https://github.com/kubevela/terraform-controller/tree/master/hack/tool/backup_restore" target="_blank" rel="noopener noreferrer" class=""><code>backup_restore</code> tool</a>:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">git clone https://github.com/kubevela/terraform-controller.git</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">cd terraform-controller/hack/tool/backup_restore</span><br></span></code></pre></div></div>
</li>
<li class="">
<p>Run the <code>restore</code> command:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">go run main.go restore --application &lt;path/to/your/application.yaml&gt; --component sample-s3 --state &lt;path/to/your/state.json&gt;</span><br></span></code></pre></div></div>
<p>The above command will resume the Terraform backend in the Kubernetes first and then create the application without recreating the S3 bucket.</p>
</li>
</ol>
<p>That's all! You have successfully migrate the management of the S3 bucket to KubeVela!</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="whats-more">What's more<a href="https://kubevela.io/blog/2022/07/20/migrate-erraform-cloud-resources-to-kubeVela/#whats-more" class="hash-link" aria-label="Direct link to What's more" title="Direct link to What's more" translate="no">​</a></h2>
<p>For more information about the <code>backup_restore</code> tool, please read <a href="https://github.com/kubevela/terraform-controller/blob/master/hack/tool/backup_restore/README.md" target="_blank" rel="noopener noreferrer" class="">the doc</a>. If you have any problem, issues and pull requests are always welcome.</p>]]></content>
        <author>
            <name>Nan Li</name>
            <uri>https://github.com/loheagn</uri>
        </author>
        <category label="KubeVela" term="KubeVela"/>
        <category label="Terraform" term="Terraform"/>
        <category label="Kubernetes" term="Kubernetes"/>
        <category label="DevOps" term="DevOps"/>
        <category label="CNCF" term="CNCF"/>
        <category label="CI/CD" term="CI/CD"/>
        <category label="Application delivery" term="Application delivery"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Helm Chart Delivery in Multi-Cluster]]></title>
        <id>https://kubevela.io/blog/2022/07/07/helm-multi-cluster/</id>
        <link href="https://kubevela.io/blog/2022/07/07/helm-multi-cluster/"/>
        <updated>2022-07-07T00:00:00.000Z</updated>
        <content type="html"><![CDATA[<p><a href="https://artifacthub.io/packages/search?kind=0" target="_blank" rel="noopener noreferrer" class="">Helm Charts</a> are very popular that you can find almost 10K different software packaged in this way. While in today's multi-cluster/hybrid cloud business environment, we often encounter these typical requirements: distribute to multiple specific clusters, specific group distributions according to business need, and differentiated configurations for multi-clusters.</p>
<p>In this blog, we'll introduce how to use <a href="https://kubevela.io/" target="_blank" rel="noopener noreferrer" class="">KubeVela</a> to do multi cluster delivery for Helm Charts.</p>
<p>If you don't have multi clusters, don't worry, we'll introduce from scratch with only Docker or Linux System required. You can also refer to the <a href="https://kubevela.io/docs/tutorials/helm" target="_blank" rel="noopener noreferrer" class="">basic helm chart delivery</a> in single cluster.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="prerequisites">Prerequisites<a href="https://kubevela.io/blog/2022/07/07/helm-multi-cluster/#prerequisites" class="hash-link" aria-label="Direct link to Prerequisites" title="Direct link to Prerequisites" translate="no">​</a></h2>
<ul>
<li class="">Docker v20.10.5+ (runc &gt;= v1.0.0-rc93), or Linux system</li>
<li class=""><a href="https://github.com/kubevela/velad" target="_blank" rel="noopener noreferrer" class="">VelaD</a>, a lightweight deployment tool to set up KubeVela with Kubernetes.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="prepare-clusters">Prepare Clusters<a href="https://kubevela.io/blog/2022/07/07/helm-multi-cluster/#prepare-clusters" class="hash-link" aria-label="Direct link to Prepare Clusters" title="Direct link to Prepare Clusters" translate="no">​</a></h2>
<blockquote>
<p>This section is preparation for multi-cluster, we will start from scratch for convenience. if you're already KubeVela users and have <a href="https://kubevela.io/docs/platform-engineers/system-operation/managing-clusters" target="_blank" rel="noopener noreferrer" class="">multi-clusters joined</a>, you can skip this section.</p>
</blockquote>
<ol>
<li class="">Install KubeVela control plane</li>
</ol>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">velad install</span><br></span></code></pre></div></div>
<ol start="2">
<li class="">Export the KubeConfig for the newly created cluster</li>
</ol>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">export KUBECONFIG=$(velad kubeconfig --name default --host)</span><br></span></code></pre></div></div>
<p>Now you have successfully installed KubeVela. You can join your cluster to kubevela by:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela cluster join &lt;path-to-kubeconfig-of-cluster&gt; --name foo</span><br></span></code></pre></div></div>
<p>VelaD can also provide K3s clusters for convenience.</p>
<ol start="3">
<li class="">Create and Join a cluster created by velad named <code>foo</code></li>
</ol>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">velad install --name foo --cluster-only</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela cluster join $(velad kubeconfig --name foo --internal) --name foo</span><br></span></code></pre></div></div>
<p>As a fully extensible control plane, most of KubeVela's capabilities are pluggable. The following steps will guide you to install some addons for different capabilities.</p>
<ol start="4">
<li class="">Enable velaux addon, it will provide UI console for KubeVela</li>
</ol>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela addon enable velaux</span><br></span></code></pre></div></div>
<ol start="5">
<li class="">Enable fluxcd addon for helm component delivery</li>
</ol>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela addon enable fluxcd</span><br></span></code></pre></div></div>
<p>If you have already enabled the <code>fluxcd</code> addon before you joined the new cluster, you NEED to enable the addon for the newly joined cluster by:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela addon enable fluxcd --clusters foo</span><br></span></code></pre></div></div>
<p>Finally, we have finished all preparation, you can check the clusters joined:</p>
<div class="language-console codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-console codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">$ vela cluster ls</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">CLUSTER	ALIAS	TYPE           	ENDPOINT               	ACCEPTED	LABELS</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">local  	     	Internal       	-                      	true</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">foo    	     	X509Certificate	https://172.20.0.6:6443	true</span><br></span></code></pre></div></div>
<p>One cluster named <code>local</code> is the KubeVela control plane, another one named <code>foo</code> is the cluster we just joined.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="deploy-across-multi-clusters">Deploy across multi clusters<a href="https://kubevela.io/blog/2022/07/07/helm-multi-cluster/#deploy-across-multi-clusters" class="hash-link" aria-label="Direct link to Deploy across multi clusters" title="Direct link to Deploy across multi clusters" translate="no">​</a></h2>
<p>We can use <code>topology</code> policy to specify the delivery topology for helm chart like the following command:</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">cat &lt;&lt;EOF </span><span class="token punctuation" style="color:rgb(248, 248, 242)">|</span><span class="token plain"> vela up </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">f </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">apiVersion</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> core.oam.dev/v1beta1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> Application</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">metadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> helm</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">hello</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">spec</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">components</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> hello</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> helm</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">repoType</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"helm"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">url</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"https://jhidalgo3.github.io/helm-charts/"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">chart</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"hello-kubernetes-chart"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">version</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"3.0.0"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">policies</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> foo</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">cluster</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">only</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> topology</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">clusters</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">"foo"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">EOF</span><br></span></code></pre></div></div>
<p>The <code>clusters</code> field of topology policy is a slice, you can specify multiple cluster names here.
You can also use label selector or specify namespace with that, refer to the <a href="https://kubevela.io/docs/end-user/policies/references#topology" target="_blank" rel="noopener noreferrer" class="">reference docs</a> for more details.</p>
<p>After deployed, you can check the deployed application by:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela status helm-hello</span><br></span></code></pre></div></div>
<p>The expected output should be as follows if deployed successfully:</p>
<div class="language-console codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-console codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">About:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  Name:      	helm-hello</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  Namespace: 	default</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  Created at:	2022-06-09 19:14:57 +0800 CST</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  Status:    	running</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Workflow:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  mode: DAG</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  finished: true</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  Suspend: false</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  Terminated: false</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  Steps</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  - id:vtahj5zrz4</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    name:deploy-foo-cluster-only</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    type:deploy</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    phase:succeeded</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    message:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Services:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  - Name: hello</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    Cluster: foo  Namespace: default</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    Type: helm</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    Healthy Fetch repository successfully, Create helm release successfully</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    No trait applied</span><br></span></code></pre></div></div>
<p>You can check the deployed resource by:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">$ vela status helm-hello --tree</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">CLUSTER       NAMESPACE     RESOURCE             STATUS</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">foo       ─── default   ─┬─ HelmRelease/hello    updated</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                         └─ HelmRepository/hello updated</span><br></span></code></pre></div></div>
<p>You can also check the deployed resource by VelaUX.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="check-resources-from-ui-console">Check Resources from UI console<a href="https://kubevela.io/blog/2022/07/07/helm-multi-cluster/#check-resources-from-ui-console" class="hash-link" aria-label="Direct link to Check Resources from UI console" title="Direct link to Check Resources from UI console" translate="no">​</a></h2>
<p>By using the <code>velaux</code> UI console, you can get even more information with a unified experience for multi clusters. You can refer to <a href="https://kubevela.io/docs/install#2-install-velaux" target="_blank" rel="noopener noreferrer" class="">this doc</a> to learn how to visit VelaUX.</p>
<p>With the help of UI, you can:</p>
<ul>
<li class="">Check pod status and event from different clusters:</li>
</ul>
<p><img decoding="async" loading="lazy" alt="resource-detail" src="https://kubevela.io/assets/images/helm-pod-a743d5fe68172b8a4c0f0f7a3db3f1d8.jpg" width="4576" height="1844" class="img_ev3q"></p>
<ul>
<li class="">Check pod logs from different clusters:</li>
</ul>
<p><img decoding="async" loading="lazy" alt="resource-detail" src="https://kubevela.io/assets/images/helm-logs-a9b052a68e136b49759077cb9f21ae10.jpg" width="5072" height="2694" class="img_ev3q"></p>
<ul>
<li class="">Check resource topology and status:</li>
</ul>
<p><img decoding="async" loading="lazy" alt="resource-detail" src="https://kubevela.io/assets/images/helm-topology-b051f26eb702e6259e13b2e44b8ec939.jpg" width="4572" height="2088" class="img_ev3q"></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="deploy-with-override-configurations">Deploy with override configurations<a href="https://kubevela.io/blog/2022/07/07/helm-multi-cluster/#deploy-with-override-configurations" class="hash-link" aria-label="Direct link to Deploy with override configurations" title="Direct link to Deploy with override configurations" translate="no">​</a></h2>
<p>In some cases, we will deploy helm chart into different clusters with different values, then we can use the <a href="https://kubevela.io/docs/end-user/policies/references#override" target="_blank" rel="noopener noreferrer" class="">override policy</a>.</p>
<p>Below is a complex example that we will deploy one helm chart into two clusters and specify different values for each cluster. Let's deploy it:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">cat &lt;&lt;EOF | vela up -f -</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">apiVersion: core.oam.dev/v1beta1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">kind: Application</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">metadata:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  name: helm-hello</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">spec:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  components:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    - name: hello</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      type: helm</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      properties:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        repoType: "helm"</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        url: "https://jhidalgo3.github.io/helm-charts/"</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        chart: "hello-kubernetes-chart"</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        version: "3.0.0"</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  policies:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    - name: topology-local</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      type: topology</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      properties:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        clusters: ["local"]</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    - name: topology-foo</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      type: topology</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      properties:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        clusters: ["foo"]</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    - name: override-local</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      type: override</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      properties:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        components:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          - name: hello</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            properties:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">              values:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                configs:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                  MESSAGE: Welcome to Control Plane Cluster!</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    - name: override-foo</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      type: override</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      properties:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        components:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          - name: hello</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            properties:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">              values:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                configs:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                  MESSAGE: Welcome to Your New Foo Cluster!</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  workflow:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    steps:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      - name: deploy2local</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        type: deploy</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        properties:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          policies: ["topology-local", "override-local"]</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      - name: manual-approval</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        type: suspend</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      - name: deploy2foo</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        type: deploy</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        properties:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          policies: ["topology-foo", "override-foo"]</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">EOF</span><br></span></code></pre></div></div>
<blockquote>
<p><strong>Note: If you feel the policy and workflow is a bit complex, you can make them as an external object and just reference the object, the usage is the same with the <a href="https://kubevela.io/docs/case-studies/multi-cluster#use-policies-and-workflow-outside-the-application" target="_blank" rel="noopener noreferrer" class="">container delivery</a>.</strong></p>
</blockquote>
<p>The deploy process has three steps:</p>
<ul>
<li class="">
<ol>
<li class="">deploy to local cluster;</li>
</ol>
</li>
<li class="">
<ol start="2">
<li class="">wait for manual approval;</li>
</ol>
</li>
<li class="">
<ol start="3">
<li class="">deploy to foo cluster.</li>
</ol>
</li>
</ul>
<p>So you will find it was suspended after the first step, just like follows:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">$ vela status helm-hello</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">About:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  Name:      	helm-hello</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  Namespace: 	default</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  Created at:	2022-06-09 19:38:13 +0800 CST</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  Status:    	workflowSuspending</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Workflow:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  mode: StepByStep</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  finished: false</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  Suspend: true</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  Terminated: false</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  Steps</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  - id:ww4cydlvee</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    name:deploy2local</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    type:deploy</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    phase:succeeded</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    message:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  - id:xj6hu97e1e</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    name:manual-approval</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    type:suspend</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    phase:succeeded</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    message:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Services:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  - Name: hello</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    Cluster: local  Namespace: default</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    Type: helm</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    Healthy Fetch repository successfully, Create helm release successfully</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    No trait applied</span><br></span></code></pre></div></div>
<p>You can check the helm chart deployed in control plane with the value "Welcome to Control Plane Cluster!".</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela port-forward helm-hello</span><br></span></code></pre></div></div>
<p>It will automatically prompt with your browser with the following page:</p>
<p><img decoding="async" loading="lazy" alt="resource-detail" src="https://kubevela.io/assets/images/helm-c1-cc990e160108dd6fa8d2e2d044b2d650.jpg" width="977" height="534" class="img_ev3q"></p>
<p>Let's continue the workflow as we have checked the deployment has succeeded.</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela workflow resume helm-hello</span><br></span></code></pre></div></div>
<p>Then it will deploy to the foo cluster, you can check the resources with detailed information:</p>
<div class="language-console codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-console codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">$ vela status helm-hello --tree --detail</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">CLUSTER       NAMESPACE     RESOURCE             STATUS    APPLY_TIME          DETAIL</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">foo       ─── default   ─┬─ HelmRelease/hello    updated   2022-06-09 19:38:13 Ready: True  Status: Release reconciliation succeeded  Age: 64s</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                         └─ HelmRepository/hello updated   2022-06-09 19:38:13 URL: https://jhidalgo3.github.io/helm-charts/  Age: 64s  Ready: True</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                                                                               Status: stored artifact for revision 'ab876069f02d779cb4b63587af1266464818ba3790c0ccd50337e3cdead44803'</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">local     ─── default   ─┬─ HelmRelease/hello    updated   2022-06-09 19:38:13 Ready: True  Status: Release reconciliation succeeded  Age: 7m34s</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                         └─ HelmRepository/hello updated   2022-06-09 19:38:13 URL: https://jhidalgo3.github.io/helm-charts/  Age: 7m34s  Ready: True</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                                                                               Status: stored artifact for revision 'ab876069f02d779cb4b63587af1266464818ba3790c0ccd50337e3cdead44803'</span><br></span></code></pre></div></div>
<p>Use port forward again:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela port-forward helm-hello</span><br></span></code></pre></div></div>
<p>Then it will prompt some selections:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">? You have 2 deployed resources in your app. Please choose one:  [Use arrows to move, type to filter]</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">&gt; Cluster: foo | Namespace: default | Kind: HelmRelease | Name: hello</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  Cluster: local | Namespace: default | Kind: HelmRelease | Name: hello</span><br></span></code></pre></div></div>
<p>Choose the option with cluster <code>foo</code>, then you'll see the result that has was overridden with new message.</p>
<div class="language-console codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-console codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">$ curl http://127.0.0.1:8080/</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">...snip...</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      &lt;div id="message"&gt;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  Welcome to Your New Foo Cluster!</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">&lt;/div&gt;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">...snip...</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="specify-different-value-file-for-different-environment">Specify different value file for different environment<a href="https://kubevela.io/blog/2022/07/07/helm-multi-cluster/#specify-different-value-file-for-different-environment" class="hash-link" aria-label="Direct link to Specify different value file for different environment" title="Direct link to Specify different value file for different environment" translate="no">​</a></h2>
<p>You can choose different value file present in a helm chart for different environment. eg:</p>
<p>Please make sure your local cluster have two namespaces "test" and "prod" which represent two environments in our example.</p>
<p>We use the chart <code>hello-kubernetes-chart</code> as an example.This chart has two values files. You can pull this chart and have a look all contains files in it:</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">$ tree ./hello</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">kubernetes</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">chart</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">./hello</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">kubernetes</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">chart</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">├── Chart.yaml</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">├── templates</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">│ ├── NOTES.txt</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">│ ├── _helpers.tpl</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">│ ├── config</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">map.yaml</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">│ ├── deployment.yaml</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">│ ├── hpa.yaml</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">│ ├── ingress.yaml</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">│ ├── service.yaml</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">│ ├── serviceaccount.yaml</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">│ └── tests</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">│ └── test</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">connection.yaml</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">├── values</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">production.yaml</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">└── values.yaml</span><br></span></code></pre></div></div>
<p>As we can see, there are values files <code>values.yaml</code> <code>values-production.yaml</code> in this chart.</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">cat &lt;&lt;EOF </span><span class="token punctuation" style="color:rgb(248, 248, 242)">|</span><span class="token plain"> vela up </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">f </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">apiVersion</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> core.oam.dev/v1beta1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> Application</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">metadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> hello</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">kubernetes</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">spec</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">components</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> hello</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">kubernetes</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> helm</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">repoType</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"helm"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">url</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"https://wangyikewxgm.github.io/my-charts/"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">chart</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"hello-kubernetes-chart"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">version</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"0.1.0"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">policies</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> topology</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">test</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> topology</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">clusters</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">"local"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">namespace</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"test"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> topology</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">prod</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> topology</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">clusters</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">"local"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">namespace</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"prod"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> override</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">prod</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> override</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">components</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> hello</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">kubernetes</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">              </span><span class="token key atrule">valuesFiles</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"values-production.yaml"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">workflow</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">steps</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> deploy2test</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> deploy</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">policies</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">"topology-test"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> deploy2prod</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> deploy</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">policies</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">"topology-prod"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"override-prod"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain">  </span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">EOF</span><br></span></code></pre></div></div>
<p>Access the endpoints of application:</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela port</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">forward hello</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">kubernetes</span><br></span></code></pre></div></div>
<p>If you choose <code>Cluster: local | Namespace: test | Kind: HelmRelease | Name: hello-kubernetes</code> you will see:</p>
<p><img decoding="async" loading="lazy" alt="image" src="https://kubevela.io/assets/images/helm-files-test-29fed6a7be0841e2ec445d7012404459.jpg" width="901" height="442" class="img_ev3q"></p>
<p>If you choose <code>Cluster: local | Namespace: prod | Kind: HelmRelease | Name: hello-kubernetes</code> you will see:</p>
<p><img decoding="async" loading="lazy" alt="image" src="https://kubevela.io/assets/images/helm-files-prod-4c6afbbe4d282651c48b779b53783fca.jpg" width="1066" height="461" class="img_ev3q"></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="clean-up">Clean up<a href="https://kubevela.io/blog/2022/07/07/helm-multi-cluster/#clean-up" class="hash-link" aria-label="Direct link to Clean up" title="Direct link to Clean up" translate="no">​</a></h2>
<p>If you're using velad for this demo, you can clean up very easily by:</p>
<ul>
<li class="">Clean up the foo cluster</li>
</ul>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">velad uninstall -n foo</span><br></span></code></pre></div></div>
<ul>
<li class="">Clean up the default cluster</li>
</ul>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">velad uninstall</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="whats-more">What's More?<a href="https://kubevela.io/blog/2022/07/07/helm-multi-cluster/#whats-more" class="hash-link" aria-label="Direct link to What's More?" title="Direct link to What's More?" translate="no">​</a></h2>
<p>With the help of KubeVela and its addon, you can get the capability of <a href="https://kubevela.io/docs/tutorials/helm-rollout" target="_blank" rel="noopener noreferrer" class="">Canary Rollout</a> for your helm charts!</p>
<p>Go and ship Helm chart with KubeVela, makes deploying and operating applications across today's hybrid, multi-cloud environments easier, faster and more reliable.</p>]]></content>
        <author>
            <name>Jianbo Sun</name>
            <uri>https://github.com/kubevela/kubevela</uri>
        </author>
        <category label="KubeVela" term="KubeVela"/>
        <category label="use-case" term="use-case"/>
        <category label="helm chart" term="helm chart"/>
        <category label="multi-cluster" term="multi-cluster"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Glue Terraform Ecosystem into Kubernetes World]]></title>
        <id>https://kubevela.io/blog/2022/06/27/terraform-integrate-with-vela/</id>
        <link href="https://kubevela.io/blog/2022/06/27/terraform-integrate-with-vela/"/>
        <updated>2022-06-27T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This article discusses how to Integrate terraform ecosystem with KubeVela.]]></summary>
        <content type="html"><![CDATA[<p>If you're looking for something to glue Terraform ecosystem with the Kubernetes world, congratulations! You're getting exactly what you want in this blog.</p>
<p>We will introduce how to integrate terraform modules into KubeVela by fixing a real world problem -- "Fixing the Developer Experience of Kubernetes Port Forwarding" inspired by <a href="https://inlets.dev/blog/2022/06/24/fixing-kubectl-port-forward.html" target="_blank" rel="noopener noreferrer" class="">article</a> from Alex Ellis.</p>
<p>In general, this article will be divided into two parts:</p>
<ul>
<li class="">Part.1 will introduce how to glue Terraform with KubeVela, it needs some basic knowledge of both Terraform and KubeVela. You can just skip this part if you don't want to extend KubeVela as a Developer.</li>
<li class="">Part.2 will introduce how KubeVela can 1) provision a Cloud ECS instance by KubeVela with public IP; 2) Use the ECS instance as a tunnel sever to provide public access for any container service within an intranet environment.</li>
</ul>
<p>OK, let's go!</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="part-1-glue-terraform-module-as-kubevela-capability">Part 1. Glue Terraform Module as KubeVela Capability<a href="https://kubevela.io/blog/2022/06/27/terraform-integrate-with-vela/#part-1-glue-terraform-module-as-kubevela-capability" class="hash-link" aria-label="Direct link to Part 1. Glue Terraform Module as KubeVela Capability" title="Direct link to Part 1. Glue Terraform Module as KubeVela Capability" translate="no">​</a></h2>
<p>In general, <a href="https://kubevela.net/docs/" target="_blank" rel="noopener noreferrer" class="">KubeVela</a> is a modern software delivery control plane, you may ask: "What benefit from doing this":</p>
<ol>
<li class="">The power of gluing Terraform with Kubernetes ecosystem including Helm Charts in one unified solution, that helps you to do GitOps, CI/CD integration and application lifecycle management.<!-- -->
<ul>
<li class="">Thinking of deploy a product that includes Cloud Database, Container Service and several helm charts, now you can manage and deploy them together without switching to different tools.</li>
</ul>
</li>
<li class="">Declarative model for all the resources, KubeVela will run the reconcile loop until succeed.<!-- -->
<ul>
<li class="">You won't be blocked by the network issues from terraform CLI.</li>
</ul>
</li>
<li class="">A powerful CUE based workflow that you can define any preferred steps in the application delivery process.<!-- -->
<ul>
<li class="">You can compose the way you like, such as canary rollout, multi-clusters/multi-env promotion, notification.</li>
</ul>
</li>
</ol>
<p>If you're already a good hand of terraform, it's pretty easy for this integration.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="build-your-terraform-module">Build your terraform module<a href="https://kubevela.io/blog/2022/06/27/terraform-integrate-with-vela/#build-your-terraform-module" class="hash-link" aria-label="Direct link to Build your terraform module" title="Direct link to Build your terraform module" translate="no">​</a></h3>
<blockquote>
<p>This part can usually be skipped, if you already have a well-tested terraform module,</p>
</blockquote>
<p>Before start, make sure you have:</p>
<ul>
<li class="">Installed <a href="https://www.terraform.io/downloads" target="_blank" rel="noopener noreferrer" class="">terraform CLI</a>.</li>
<li class="">Have a Cloud Service credentials, in this article, we will use Alibaba Cloud as example.</li>
<li class="">Learn the basic knowledge of <a href="https://www.terraform.io/language" target="_blank" rel="noopener noreferrer" class="">how to use terraform</a>.</li>
</ul>
<p>Here's my terraform module( <a href="https://github.com/wonderflow/terraform-alicloud-ecs-instance" target="_blank" rel="noopener noreferrer" class="">https://github.com/wonderflow/terraform-alicloud-ecs-instance</a> ) for this demo.</p>
<ul>
<li class="">Clone this module:</li>
</ul>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">git clone https://github.com/wonderflow/terraform-alicloud-ecs-instance.git</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">cd terraform-alicloud-ecs-instance</span><br></span></code></pre></div></div>
<ul>
<li class="">Initialize and download the latest stable version of the Alibaba Cloud provider:</li>
</ul>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">terraform init</span><br></span></code></pre></div></div>
<ul>
<li class="">Configure the Alibaba Cloud provider credentials:</li>
</ul>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">export ALICLOUD_ACCESS_KEY="your-accesskey-id"</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">export ALICLOUD_SECRET_KEY="your-accesskey-secret"</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">export ALICLOUD_REGION="your-region-id"</span><br></span></code></pre></div></div>
<p>You can also create an <code>provider.tf</code> including the credentials instead:</p>
<div class="language-hcl codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-hcl codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">provider "alicloud" {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    access_key  = "your-accesskey-id"</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    secret_key   = "your-accesskey-secret"</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    region           = "cn-hangzhou"</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span></code></pre></div></div>
<ul>
<li class="">Test creating the resources:</li>
</ul>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">terraform apply -var-file=test/test.tfvars</span><br></span></code></pre></div></div>
<ul>
<li class="">Destroy all resources of tests:</li>
</ul>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">terraform destroy  -var-file=test/test.tfvars</span><br></span></code></pre></div></div>
<p>You can customize this module per your needs and push to github of your own.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="make-the-terraform-module-as-kubevela-capability">Make the Terraform module as KubeVela Capability<a href="https://kubevela.io/blog/2022/06/27/terraform-integrate-with-vela/#make-the-terraform-module-as-kubevela-capability" class="hash-link" aria-label="Direct link to Make the Terraform module as KubeVela Capability" title="Direct link to Make the Terraform module as KubeVela Capability" translate="no">​</a></h3>
<p>Before start, make sure you have <a href="https://kubevela.net/docs/install#1-install-velad" target="_blank" rel="noopener noreferrer" class="">installed kubevela control plane</a>, don't worry if you don't have Kubernetes cluster, velad is enough for the quick demo.</p>
<p>We'll use the terraform module we have already prepared just now.</p>
<ul>
<li class="">Generate Component Definition</li>
</ul>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela def init ecs --type component --provider alibaba --desc "Terraform configuration for Alibaba Cloud Elastic Compute Service" --git https://github.com/wonderflow/terraform-alicloud-ecs-instance.git &gt; alibaba-ecs-def.yaml</span><br></span></code></pre></div></div>
<blockquote>
<p>Change the git url with your own if you have customized.</p>
</blockquote>
<ul>
<li class="">Apply it to the vela control plane</li>
</ul>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela kube apply -f alibaba-ecs-def.yaml</span><br></span></code></pre></div></div>
<blockquote>
<p><code>vela kube apply</code> works the same with <code>kubectl apply</code>.</p>
</blockquote>
<p>Then the extension of ECS module has been added, you can learn more details from <a href="https://kubevela.net/docs/platform-engineers/components/component-terraform" target="_blank" rel="noopener noreferrer" class="">here</a>.</p>
<p>We have finished the integration, the end user can discover the capability immediately after the apply.</p>
<p>The end user can use following commands to check the parameters:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela show alibaba-ecs</span><br></span></code></pre></div></div>
<p>They can also view it from website by launching:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela show alibaba-ecs --web</span><br></span></code></pre></div></div>
<p>That's all of the integration needed.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="part-2-fixing-the-developer-experience-of-kubernetes-port-forwarding">Part 2. Fixing the Developer Experience of Kubernetes Port Forwarding<a href="https://kubevela.io/blog/2022/06/27/terraform-integrate-with-vela/#part-2-fixing-the-developer-experience-of-kubernetes-port-forwarding" class="hash-link" aria-label="Direct link to Part 2. Fixing the Developer Experience of Kubernetes Port Forwarding" title="Direct link to Part 2. Fixing the Developer Experience of Kubernetes Port Forwarding" translate="no">​</a></h2>
<p>In this part, we will introduce a solution that you can expose any of your Kubernetes service to public with a specific port. The solution is composed by:</p>
<ol>
<li class="">KubeVela environment, you already have if you have practiced in part 1.</li>
<li class="">Alibaba Cloud ECS, KubeVela will create a tiny ecs(<code>1u1g</code>) automatically by access key.</li>
<li class=""><a href="https://github.com/fatedier/frp" target="_blank" rel="noopener noreferrer" class="">frp</a>, KubeVela will launch this proxy both at server-side and client-side.</li>
</ol>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="prepare-kubevela-environment">Prepare KubeVela environment<a href="https://kubevela.io/blog/2022/06/27/terraform-integrate-with-vela/#prepare-kubevela-environment" class="hash-link" aria-label="Direct link to Prepare KubeVela environment" title="Direct link to Prepare KubeVela environment" translate="no">​</a></h3>
<ul>
<li class="">Install KubeVela</li>
</ul>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">curl -fsSL https://kubevela.io/script/install-velad.sh | bash</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">velad install</span><br></span></code></pre></div></div>
<p>Check <a href="https://kubevela.net/docs/install#1-install-velad" target="_blank" rel="noopener noreferrer" class="">this doc</a> to learn more details of installation.</p>
<ul>
<li class="">Enable Terraform Addon and Alibaba Provider</li>
</ul>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela addon enable terraform</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela addon enable terraform-alibaba</span><br></span></code></pre></div></div>
<ul>
<li class="">Add credentials as a provider</li>
</ul>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela config create terraform-alibaba-default -t terraform-alibaba ALICLOUD_ACCESS_KEY=&lt;"your-accesskey-id"&gt; ALICLOUD_SECRET_KEY="your-accesskey-secret" ALICLOUD_REGION=&lt;your-region&gt; </span><br></span></code></pre></div></div>
<div class="theme-admonition theme-admonition-warning admonition_xJq3 alert alert--warning"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>warning</div><div class="admonitionContent_BuS1"><p>Before the 1.6.0 version:</p><div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela provider add terraform-alibaba --ALICLOUD_ACCESS_KEY &lt;"your-accesskey-id"&gt; --ALICLOUD_SECRET_KEY "your-accesskey-secret" --ALICLOUD_REGION &lt;your-region&gt; --name terraform-alibaba-default</span><br></span></code></pre></div></div></div></div>
<p>Check <a href="https://kubevela.net/docs/reference/addons/terraform" target="_blank" rel="noopener noreferrer" class="">this doc</a> for more details about other clouds.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="launch-a-ecs-with-public-ip-and-deploy-the-frp-server">Launch a ECS with Public IP and Deploy the <code>frp</code> server<a href="https://kubevela.io/blog/2022/06/27/terraform-integrate-with-vela/#launch-a-ecs-with-public-ip-and-deploy-the-frp-server" class="hash-link" aria-label="Direct link to launch-a-ecs-with-public-ip-and-deploy-the-frp-server" title="Direct link to launch-a-ecs-with-public-ip-and-deploy-the-frp-server" translate="no">​</a></h3>
<p>After the environment prepared well, you can create an application as below.</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">cat &lt;&lt;EOF </span><span class="token punctuation" style="color:rgb(248, 248, 242)">|</span><span class="token plain"> vela up </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">f </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)"># YAML begins</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">apiVersion</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> core.oam.dev/v1beta1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> Application</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">metadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> ecs</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">demo</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">spec</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">components</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> ecs</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">demo</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> alibaba</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">ecs</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">providerRef</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> terraform</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">alibaba</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">default</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">writeConnectionSecretToRef</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> outputs</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">ecs          </span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"test-terraform-vela-123"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">instance_type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"ecs.n1.tiny"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">host_name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"test-terraform-vela"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">password</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Test-123456!"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">internet_max_bandwidth_out</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"10"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">associate_public_ip_address</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"true"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">instance_charge_type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"PostPaid"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">user_data_url</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"https://raw.githubusercontent.com/wonderflow/terraform-alicloud-ecs-instance/master/frp.sh"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">ports</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token number">8080</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token number">8081</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token number">8082</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token number">8083</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token number">9090</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token number">9091</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token number">9092</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">tags</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">created_by</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Terraform-of-KubeVela"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">created_from</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"module-tf-alicloud-ecs-instance"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)"># YAML ends</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">EOF</span><br></span></code></pre></div></div>
<p>This application will deploy an ECS instance with a public ip, explanation of some useful fields:</p>
<table><thead><tr><th style="text-align:center">Field</th><th style="text-align:center">Usage</th></tr></thead><tbody><tr><td style="text-align:center">providerRef</td><td style="text-align:center">reference to the provider credentials we added</td></tr><tr><td style="text-align:center">writeConnectionSecretToRef</td><td style="text-align:center">the outputs of terraform module will be written into the secret</td></tr><tr><td style="text-align:center">name</td><td style="text-align:center">name of the ecs instance</td></tr><tr><td style="text-align:center">instance_type</td><td style="text-align:center">ecs instance type</td></tr><tr><td style="text-align:center">host_name</td><td style="text-align:center">hostname of the ecs</td></tr><tr><td style="text-align:center">password</td><td style="text-align:center">password of the ecs instance, you can connect by <code>ssh</code></td></tr><tr><td style="text-align:center">internet_max_bandwidth_out</td><td style="text-align:center">internet bandwidth of the ecs instance</td></tr><tr><td style="text-align:center">associate_public_ip_address</td><td style="text-align:center">create public IP or not</td></tr><tr><td style="text-align:center">instance_charge_type</td><td style="text-align:center">the charge way of the resource</td></tr><tr><td style="text-align:center">user_data_url</td><td style="text-align:center">the installation script after the ecs instance created, we have installed the frp server in the script</td></tr><tr><td style="text-align:center">ports</td><td style="text-align:center">ports that will be allowd in the VPC and security group, 9090/9091 is must for frp server while others are preserved for client usage</td></tr><tr><td style="text-align:center">tags</td><td style="text-align:center">tags of the ECS instance</td></tr></tbody></table>
<p>You can learn more fields by:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela show alibaba-ecs</span><br></span></code></pre></div></div>
<p>After applied, you can check the status and logs of the application by:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela status ecs-demo</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela logs ecs-demo</span><br></span></code></pre></div></div>
<p>You can get the secret from the terraform resource contains the output values.</p>
<p>You may already see the result in <code>vela logs</code>, you can also check the output information from Terraform by:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">$ kubectl get secret outputs-ecs --template={{.data.this_public_ip}} | base64 --decode</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">["121.196.106.174"]</span><br></span></code></pre></div></div>
<blockquote>
<p>KubeVela will soon support query resource like this <a href="https://github.com/kubevela/kubevela/issues/4268" target="_blank" rel="noopener noreferrer" class="">https://github.com/kubevela/kubevela/issues/4268</a>.</p>
</blockquote>
<p>As a result, you can visit the frp server admin page on port <code>:9091</code>, the <code>admin</code> password is <code>vela123</code> in the script.</p>
<p>By now, we have finished the server part here.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="use-frp-client-in-kubevela">Use frp client in KubeVela<a href="https://kubevela.io/blog/2022/06/27/terraform-integrate-with-vela/#use-frp-client-in-kubevela" class="hash-link" aria-label="Direct link to Use frp client in KubeVela" title="Direct link to Use frp client in KubeVela" translate="no">​</a></h3>
<p>The usage of frp client is very straight-forward, we can provide public IP for any of the service inside the cluster.</p>
<p><img decoding="async" loading="lazy" src="https://kubevela.io/assets/images/terraform-ecs-62c62915b9a4cade62f4e539ef1206af.png" width="2576" height="1050" class="img_ev3q"></p>
<ol>
<li class="">Deploy as standalone to proxy for any <a href="https://kubernetes.io/docs/concepts/services-networking/service/" target="_blank" rel="noopener noreferrer" class="">Kubernetes Service</a>.</li>
</ol>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">cat &lt;&lt;EOF </span><span class="token punctuation" style="color:rgb(248, 248, 242)">|</span><span class="token plain"> vela up </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">f </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">apiVersion</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> core.oam.dev/v1beta1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> Application</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">metadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> frp</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">proxy</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">spec</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">components</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> frp</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">proxy</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> worker</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">image</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> oamdev/frpc</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">0.43.0</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">env</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> server_addr</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token key atrule">value</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"121.196.106.174"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> server_port</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token key atrule">value</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"9090"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> local_port</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token key atrule">value</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"80"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> connect_name</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token key atrule">value</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"velaux-service"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> local_ip</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token key atrule">value</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"velaux.vela-system"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> remote_port</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token key atrule">value</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"8083"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">EOF</span><br></span></code></pre></div></div>
<p>In this case, we specify the <code>local_ip</code> by <code>velaux.vela-system</code>, which means we're visiting the Kubernetes Service with name <code>velaux</code> in the namespace <code>vela-system</code>.</p>
<p>As a result, you can visit <a href="https://kubevela.io/docs/reference/addons/velaux" target="_blank" rel="noopener noreferrer" class="">velaux</a> service from the public IP <code>121.196.106.174:8083</code>.</p>
<ol start="2">
<li class="">Compose two components together for the same lifecycle.</li>
</ol>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">cat &lt;&lt;EOF </span><span class="token punctuation" style="color:rgb(248, 248, 242)">|</span><span class="token plain"> vela up </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">f </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)"># YAML begins</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">apiVersion</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> core.oam.dev/v1beta1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> Application</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">metadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> composed</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">app</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">spec</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">components</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> web</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">new</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> webservice</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">image</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> oamdev/hello</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">world</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">v2</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">ports</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">port</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token number">8000</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token key atrule">expose</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token boolean important">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> frp</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">web</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> worker</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">image</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> oamdev/frpc</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">0.43.0</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">env</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> server_addr</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token key atrule">value</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"121.196.106.174"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> server_port</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token key atrule">value</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"9090"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> local_port</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token key atrule">value</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"8000"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> connect_name</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token key atrule">value</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"composed-app"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> local_ip</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token key atrule">value</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"web-new.default"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> remote_port</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token key atrule">value</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"8082"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">EOF</span><br></span></code></pre></div></div>
<p>Wow! Then you can visiting the <code>hello-world</code> by:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">curl 121.196.106.174:8082</span><br></span></code></pre></div></div>
<p>The <code>webservice</code> type component will generate a service with the name of the component automatically. The <code>frp-web</code> component will proxy the traffic to the service <code>web-new</code> in the <code>default</code> namespace which is exactly the service generated.</p>
<p>When the application deleted, all of the resources defined in the same app are deleted together.</p>
<p>You can also compose the database together with them, then you can deliver all components needed in one time.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="clean-up">Clean Up<a href="https://kubevela.io/blog/2022/06/27/terraform-integrate-with-vela/#clean-up" class="hash-link" aria-label="Direct link to Clean Up" title="Direct link to Clean Up" translate="no">​</a></h3>
<p>You can clean up all the applications in the demo by <code>vela delete</code>:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela delete composed-app -y</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela delete frp-proxy -y</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">vela delete ecs-demo -y</span><br></span></code></pre></div></div>
<p>I think you've learned how to use KubeVela in this scenario now, just try it in your environment!</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="whats-more">What's more<a href="https://kubevela.io/blog/2022/06/27/terraform-integrate-with-vela/#whats-more" class="hash-link" aria-label="Direct link to What's more" title="Direct link to What's more" translate="no">​</a></h2>
<p>In this blog, we have introduced the way to integrate Terraform module with KubeVela. It provides interesting use case that allow you to expose any of inner service to public.</p>
<p>While KubeVela can do more things than that, go and discover it at <a href="https://kubevela.io/" target="_blank" rel="noopener noreferrer" class="">kubevela.io</a>!</p>]]></content>
        <author>
            <name>Jianbo Sun</name>
            <uri>https://github.com/kubevela/KubeVela</uri>
        </author>
        <category label="KubeVela" term="KubeVela"/>
        <category label="Terraform" term="Terraform"/>
        <category label="Kubernetes" term="Kubernetes"/>
        <category label="DevOps" term="DevOps"/>
        <category label="CNCF" term="CNCF"/>
        <category label="CI/CD" term="CI/CD"/>
        <category label="Application delivery" term="Application delivery"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[KubeVela 1.4 released, Make Application Delivery Safe, Foolproof, and Transparent]]></title>
        <id>https://kubevela.io/blog/2022/06/21/release-1.4/</id>
        <link href="https://kubevela.io/blog/2022/06/21/release-1.4/"/>
        <updated>2022-06-21T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This article discusses a brief history of KubeVela and the latest release of KubeVela 1.4.]]></summary>
        <content type="html"><![CDATA[<p><a href="https://kubevela.net/" target="_blank" rel="noopener noreferrer" class="">KubeVela</a> is a modern software delivery control panel. The goal is to make application deployment and O&amp;M simpler, more agile, and more reliable in today's hybrid multi-cloud environment. Since the release of <a href="https://kubevela.net/blog/2021/10/08/blog-1.1" target="_blank" rel="noopener noreferrer" class="">Version 1.1</a>, the KubeVela architecture has naturally solved the delivery problems of enterprises in the hybrid multi-cloud environments and has provided sufficient scalability based on the OAM model, which makes it win the favor of many enterprise developers. This also accelerates the iteration of KubeVela.</p>
<p>In <a href="https://kubevela.net/blog/2022/01/27/blog-1.2" target="_blank" rel="noopener noreferrer" class="">Version 1.2</a>, we released an out-of-the-box visual console, which allows the end user to publish and manage diverse workloads through the interface. The release of <a href="https://kubevela.net/blog/2022/04/06/multi-cluster-management" target="_blank" rel="noopener noreferrer" class="">Version 1.3</a> improved the expansion system with the OAM model as the core and provides rich plug-in functions. It also provides users with a large number of enterprise-level functions, including LDAP permission authentication, and provides more convenience for enterprise integration. You can obtain more than 30 addons in the <a href="https://github.com/kubevela/catalog" target="_blank" rel="noopener noreferrer" class="">addons registry</a> of the KubeVela community. There are well-known CNCF projects (such as argocd, istio, and traefik), database middleware (such as Flink and MySQL), and hundreds of cloud vendor resources.</p>
<p>In Version 1.4, we focused on <strong>making application delivery safe, foolproof, and transparent</strong>. We added core functions, including multi-cluster permission authentication and authorization, a complex resource topology display, and a one-click installation control panel. We comprehensively strengthened the delivery security in multi-tenancy scenarios, improved the consistent experience of application development and delivery, and made the application delivery process more transparent.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="core-features">Core Features<a href="https://kubevela.io/blog/2022/06/21/release-1.4/#core-features" class="hash-link" aria-label="Direct link to Core Features" title="Direct link to Core Features" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="out-of-the-box-authentication-and-authorization-connecting-to-kubernetes-rbac-and-naturally-supporting-multiple-clusters">Out-of-the-Box Authentication and Authorization, Connecting to Kubernetes RBAC and Naturally Supporting Multiple Clusters<a href="https://kubevela.io/blog/2022/06/21/release-1.4/#out-of-the-box-authentication-and-authorization-connecting-to-kubernetes-rbac-and-naturally-supporting-multiple-clusters" class="hash-link" aria-label="Direct link to Out-of-the-Box Authentication and Authorization, Connecting to Kubernetes RBAC and Naturally Supporting Multiple Clusters" title="Direct link to Out-of-the-Box Authentication and Authorization, Connecting to Kubernetes RBAC and Naturally Supporting Multiple Clusters" translate="no">​</a></h3>
<p>After solving the challenges of architecture upgrade and extensibility, we have noticed that the security of application delivery is a problem in the entire industry that needs to be solved urgently. We found many security risks from the use cases:</p>
<ul>
<li class="">
<p>In using traditional CI/CD, many users will directly embed the admin permission of the production cluster into the environment variable of CI and only have certain permission separation for which clusters are delivered to the most basic. CI systems are usually used intensively for development and testing, and it is easy to introduce uncontrolled risks. Once the CI system is attacked by hackers or some <strong>man-made mis-operations</strong> occur, it may lead to huge damage to centralized management and coarse-grained authority control.</p>
</li>
<li class="">
<p>A large number of CRD controllers rely on admin permissions to perform operations on cluster resources and do not impose constraints on API access. Kubernetes has rich RBAC control capabilities. However, due to the high threshold of permission management (which is also independent of the implementation of specific functions), most users do not care about the details. They only choose the default configuration and put it into production use. Controllers with high flexibility (such as the ability to distribute Helm Chart) can easily become targets of hacker attacks, such as embedding a YAML script in the helm to steal keys from other namespaces.</p>
</li>
</ul>
<p>KubeVela 1.4 has added <strong>authentication and authorization capabilities and naturally supports a multi-cluster hybrid environment.</strong> Each KubeVela platform administrator can customize any API permission combination in fine granularity, connect with the Kubernetes RBAC system, authorize these permission modules to developer users, and strictly restrict their permissions. They can also easily use the permission module preset on the KubeVela platform. For example, they can directly grant a user the permissions on a specific namespace of a cluster and the <em>read-only</em> permissions. This simplifies the learning costs and mental burdens of users and comprehensively strengthens the security of application delivery. The system automatically completes the underlying authorization and strictly verifies the scope and type of resources available for the project for users who use the UI, so the business layer RBAC permissions and the underlying Kubernetes RBAC system can be connected and work together to achieve security from the outside to the inside without expanding the permissions in any link.</p>
<p><img decoding="async" loading="lazy" alt="alt" src="https://kubevela.io/assets/images/impersonation-arch-e41b1e4a82948bc340a2a1f020f0369d.jpg" width="1695" height="673" class="img_ev3q"></p>
<p>Specifically, after the platform administrator <a href="https://kubevela.net/docs/platform-engineers/auth/basic" target="_blank" rel="noopener noreferrer" class="">authorizes a user</a>, the user's request will go through several stages (as shown in the figure).</p>
<ol>
<li class="">
<p>First, the webhook of KubeVela intercepts the user's request and sends the user's permission information (ServiceAccount) to the Application object.</p>
</li>
<li class="">
<p>When the KubeVela Controller executes the deployment plan of the Application, it changes the permissions of the corresponding users based on the <a href="https://kubernetes.io/docs/reference/access-authn-authz/authentication/#user-impersonation" target="_blank" rel="noopener noreferrer" class="">impersonation mechanism (impersonate)</a> of Kubernetes.</p>
</li>
<li class="">
<p>The KubeVela multi-cluster module (ClusterGateway) passes the corresponding permissions to the sub-cluster. The Kubernetes APIServer of the sub-cluster performs authentication based on the permissions of the sub-cluster. The permissions of the sub-cluster are created by the KubeVela authorization process.</p>
</li>
</ol>
<p>In short, KubeVela's multi-cluster authentication and authorization ensure that the permissions of <strong>each end user are strictly restricted and will not be amplified by the delivery system. At the same time, KubeVela's permissions are minimized</strong>, and the entire user experience is simple.</p>
<p>Please read the official <a href="https://kubevela.net/docs/platform-engineers/auth/basic" target="_blank" rel="noopener noreferrer" class="">Permission Authentication and Authorization</a> to learn more about the operating mechanisms behind them.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="lightweight-and-convenient-application-development-control-panel-offers-a-consistent-experience-for-local-development-and-production-deployment">Lightweight and Convenient Application Development Control Panel Offers a Consistent Experience for Local Development and Production Deployment<a href="https://kubevela.io/blog/2022/06/21/release-1.4/#lightweight-and-convenient-application-development-control-panel-offers-a-consistent-experience-for-local-development-and-production-deployment" class="hash-link" aria-label="Direct link to Lightweight and Convenient Application Development Control Panel Offers a Consistent Experience for Local Development and Production Deployment" title="Direct link to Lightweight and Convenient Application Development Control Panel Offers a Consistent Experience for Local Development and Production Deployment" translate="no">​</a></h3>
<p>With the prosperity of the ecosystem, we have seen more developers begin to pay attention to cloud-native technology, but they often don't know how to get started. The following are the main reasons:</p>
<ul>
<li class="">
<p>The application <strong>development environment is inconsistent with the production environment</strong>, and the experience is different. Cloud-native is a technology trend that has emerged in the last five or six years. It has developed rapidly, but most companies are still accustomed to developing a set of internal platforms shielding underlying technologies. As a result, even if ordinary business developers learn cloud-native technology, it is difficult to practice it in actual work. In the best case, they may have to reconnect the API and configuration, let alone the consistent experience.</p>
</li>
<li class="">
<p><strong>The deployment and use</strong> of cloud-native technologies with Kubernetes as the core <strong>is complicated</strong>. It is expensive to purchase host services from cloud vendors just for the sake of getting started. Even if it takes a lot of effort to learn to deploy a set of available local environments, it is difficult to connect many cloud-native technologies to complete the entire CI/CD process, which involves a lot of knowledge in the field of operation and maintenance, and ordinary developers usually do not need to care about it and have rare chance to use it.</p>
</li>
</ul>
<p>We have also observed in the community that more companies are beginning to realize that self-built platforms cannot keep up with the development of the community ecosystem. They hope to provide a consistent experience through KubeVela and OAM models without losing the scalability of the ecosystem. However, since KubeVela's control panel relies on Kubernetes, the threshold for getting started is still not low. In response to this problem, the community has been thinking and looking for solutions. We conclude that we need a tool that has these characteristics:</p>
<ul>
<li class="">
<p>Only rely on the container environment (such as Docker) to deploy and run, <strong>so every developer can easily obtain and use it</strong></p>
</li>
<li class="">
<p>The local development and production environment experience are consistent, and the configuration is reusable, which can simulate a hybrid multi-cluster environment.</p>
</li>
<li class="">
<p>A single binary package supports <strong>offline deployment</strong>, and the time for environment initialization does not exceed the time to drink a glass of water (three minutes).</p>
</li>
</ul>
<p>After several months of incubation, we can finally release this tool in 1.4: <a href="https://github.com/kubevela/velad/" target="_blank" rel="noopener noreferrer" class="">VelaD</a>. D represents Daemon and Developer. It can help KubeVela run on a single machine and does not rely on any existing Kubernetes cluster. At the same time, it works as a lightweight application development control panel with KubeVela, helping developers obtain integrated development, testing, and delivery experiences and simplifying the complexity of cloud-native application deployment and management.</p>
<p>You can use the <a href="https://github.com/kubevela/velad/blob/main/docs/01.simple.md" target="_blank" rel="noopener noreferrer" class="">Demo documentation</a> to install and try this tool to learn more about the implementation details. It only takes three minutes to initialize the installation.</p>
<p><img decoding="async" loading="lazy" alt="alt" src="https://kubevela.io/assets/images/demo-d56c28cd737c3ab9960d7601a75f1e65.gif" width="2084" height="1372" class="img_ev3q"></p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="show-resource-topology-and-status-to-make-the-delivery-process-transparent">Show Resource Topology and Status to Make the Delivery Process Transparent<a href="https://kubevela.io/blog/2022/06/21/release-1.4/#show-resource-topology-and-status-to-make-the-delivery-process-transparent" class="hash-link" aria-label="Direct link to Show Resource Topology and Status to Make the Delivery Process Transparent" title="Direct link to Show Resource Topology and Status to Make the Delivery Process Transparent" translate="no">​</a></h3>
<p>Another big demand in application delivery is the transparent management of the resource delivery process. For example, many users in the community like to use Helm Chart to package a lot of complex YAML together. However, once there are problems in the deployment, it will be difficult to troubleshoot due to the overall black box (even if it is a small problem). Some problems include the underlying storage is not provided normally, the associated resources are not created normally, and the underlying configuration is incorrect. There are many types of resources (especially in the modern hybrid multi-cluster hybrid environment) and how to obtain effective information from them and solve problems is a challenge.</p>
<p>In Version 1.4, we added the resource topology query function to improve KubeVela's application-centric delivery experience. When developers initiate application delivery, they only need to care about simple and consistent APIs. When they need to troubleshoot problems or focus on the delivery process, they can use the resource topology feature to quickly obtain the orchestration relationships of resources in different clusters <strong>from applications to the running status of Pod instances and automatically obtain the relationships of resources, including complex and black-box Helm Chart.</strong></p>
<p><img decoding="async" loading="lazy" src="https://kubevela.io/images/1.4/resource-graph.jpg" alt="resource graph" class="img_ev3q"></p>
<p>The application shown in the preceding figure is used as an example. A Redis cluster is delivered through the Helm Chart package. The first layer of the chart is the application name, the second layer is the cluster, and the third layer is the resources directly rendered by the application. The next third and fourth layers are the associated resources of the lower level tracked according to different resources.</p>
<p>Users can use graphs to observe the derived resources and their status during the application delivery process. The abnormal points are displayed in yellow or red and the specific reasons are displayed. Compared with the application shown in the following figure, it is a basic Webservice delivered to two clusters. Developers can find that the application creates Deployment and Service resources in the two clusters, respectively. Also, the Deployment resources in the ask-hongkong cluster are displayed in yellow since the Pod instance has not been fully started.</p>
<p><img decoding="async" loading="lazy" src="https://kubevela.io/images/1.4/multiple-cluster-graph.jpg" alt="multiple-cluster-graph" class="img_ev3q"></p>
<p>This feature also allows you to search, filter, and query using different clusters and components. This helps developers quickly identify problems and understand the delivery status of the underlying application at a very low threshold.</p>
<p>Please read the official blog <em><a href="https://kubevela.net/blog/2022/06/10/visualize-resources" target="_blank" rel="noopener noreferrer" class="">Visualize the Topological Relationship of Multi-cluster Resources</a></em> to learn more about the operation mechanism behind them.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="other-key-changes">Other Key Changes<a href="https://kubevela.io/blog/2022/06/21/release-1.4/#other-key-changes" class="hash-link" aria-label="Direct link to Other Key Changes" title="Direct link to Other Key Changes" translate="no">​</a></h2>
<p>In addition to the core functions and plug-in ecosystem, Version 1.4 also enhances core functions such as workflow:</p>
<ul>
<li class="">
<p>You can configure field ignore rules to maintain the application status. This enables KubeVela to work with other controllers, such as HPA and Istio.</p>
</li>
<li class="">
<p>Application Resource Recycling supports settings based on the resource type. Currently, it supports settings based on the component name, component type, feature type, and resource type.</p>
</li>
<li class="">
<p>Workflows support sub-steps. Sub-steps support concurrent execution, which accelerates the delivery of resources in multi-cluster high availability scenarios.</p>
</li>
<li class="">
<p>You can pause a workflow step for a certain period. After that, the workflow automatically continues.</p>
</li>
<li class="">
<p>Resource deployment and recycling support follows the component dependency rule settings and supports sequential deployment and recycling of resources.</p>
</li>
<li class="">
<p>Workflow steps support conditional judgment. Currently, the <em>if: always</em> rule is supported, which means the step is executed under any circumstances, thus supporting deployment failure notification.</p>
</li>
<li class="">
<p>You can set the deployment scope for O&amp;M features to separate O&amp;M features from the deployment status of components. O&amp;M features can be independently deployed in the control cluster.</p>
</li>
</ul>
<p>Thanks to the continued contributions and efforts from more than 30 organizations and individuals in China and internationally (such as Alibaba Cloud, China Merchants Bank, and Napptive), more than 200 functional features and repairs were completed in a short period of two months, which has made this iteration excellent.</p>
<p>Please see the <a href="https://github.com/kubevela/kubevela/releases/tag/v1.4.0" target="_blank" rel="noopener noreferrer" class="">release details</a> for more information.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="addon-ecosystem">Addon Ecosystem<a href="https://kubevela.io/blog/2022/06/21/release-1.4/#addon-ecosystem" class="hash-link" aria-label="Direct link to Addon Ecosystem" title="Direct link to Addon Ecosystem" translate="no">​</a></h2>
<p>Our plug-in ecology is also rapidly expanding because of the improvement of the 1.3 addon system:</p>
<ul>
<li class="">
<p>Updated fluxcd addon supports OCI registry, which allows you to select different values files in the chart during deployment</p>
</li>
<li class="">
<p>The cert-manager addon is added to automatically manage Kubernetes certificates.</p>
</li>
<li class="">
<p>Adds a flink-kubernetes-operator addon to deliver flink workloads.</p>
</li>
<li class="">
<p>The kruise-rollout addon is added to support various release policies (such as canary release).</p>
</li>
<li class="">
<p>The pyroscope addon is added to support continuous performance tuning.</p>
</li>
<li class="">
<p>The traefik plug-in is added to support configuration API Gateway.</p>
</li>
<li class="">
<p>The vegeta addon is added to support automated stress testing of workloads.</p>
</li>
<li class="">
<p>The argocd addon is added to support ArgoCD-based Helm delivery and GitOps.</p>
</li>
<li class="">
<p>The Dapr addon is added to support the O&amp;M capabilities of Dapr subscription and publishing.</p>
</li>
<li class="">
<p>The istio addon is added to support Istio-based gateway capabilities and traffic canaries.</p>
</li>
<li class="">
<p>The mysql-operator addon is added to support the deployment of highly available distributed mysql databases.</p>
</li>
</ul>
<p>Developers are welcome to participate in the community and <a href="https://kubevela.net/docs/platform-engineers/addon/intro" target="_blank" rel="noopener noreferrer" class="">create addon</a> to extend KubeVela's system capabilities.</p>
<p><img decoding="async" loading="lazy" src="https://kubevela.io/images/1.4/addon-list-new.jpg" alt="undefined" class="img_ev3q"></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="how-can-you-participate-in-the-community">How Can You Participate in the Community?<a href="https://kubevela.io/blog/2022/06/21/release-1.4/#how-can-you-participate-in-the-community" class="hash-link" aria-label="Direct link to How Can You Participate in the Community?" title="Direct link to How Can You Participate in the Community?" translate="no">​</a></h2>
<p><img decoding="async" loading="lazy" alt="alt" src="https://kubevela.io/assets/images/open-source-3d54618d995d7d440e2393e1cb0a0e42.png" width="907" height="505" class="img_ev3q"></p>
<p>KubeVela is an open-source, worldwide, Top-Level Project in the CNCF Foundation. There are more than 300 domestic and international contributors and more than 40 community members and maintainers. It is a bilingual international operation mode with more than 4000 community members, including code, documents, and community communication.</p>
<p>If you are interested in participating in the open-source community, we welcome you to join the KubeVela community. You can learn more about the methods of participating in the open-source community through the <a href="https://kubevela.io/docs/contributor/overview" target="_blank" rel="noopener noreferrer" class="">developer documentation of the KubeVela community</a>. The engineers of the community will guide you.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="recent-planning">Recent Planning<a href="https://kubevela.io/blog/2022/06/21/release-1.4/#recent-planning" class="hash-link" aria-label="Direct link to Recent Planning" title="Direct link to Recent Planning" translate="no">​</a></h2>
<p>KubeVela will continue to evolve around an iterative cycle of two months. We will focus on these three dimensions in the next release:</p>
<ul>
<li class="">
<p><strong>Observability</strong> will provide end-to-end rich application insights around logs, metrics, and tracing dimensions to lay a solid foundation for the stability and intelligence of application delivery.</p>
</li>
<li class="">
<p><strong>Workflow Delivery Capabilities</strong> will provide richer frameworks and integration capabilities, including custom step timeout, context information-based condition judgment, and branch workflow, and connect CI/CD, providing users with richer use cases and scenarios.</p>
</li>
<li class="">
<p><strong>Application (Including Plug-Ins) Management Ability:</strong> You can disable and restart applications. You can import, export, and upload applications to the application market.</p>
</li>
</ul>
<p>If you want to learn more about planning and become a contributor or partner, you can contact us by participating in <a href="https://github.com/kubevela/community" target="_blank" rel="noopener noreferrer" class="">community communication</a>. We are looking forward to hearing from you!</p>]]></content>
        <author>
            <name>Jianbo Sun, Qingguo Zeng</name>
            <uri>https://github.com/kubevela/KubeVela</uri>
        </author>
        <category label="KubeVela" term="KubeVela"/>
        <category label="release-note" term="release-note"/>
        <category label="Kubernetes" term="Kubernetes"/>
        <category label="DevOps" term="DevOps"/>
        <category label="CNCF" term="CNCF"/>
        <category label="CI/CD" term="CI/CD"/>
        <category label="Application delivery" term="Application delivery"/>
        <category label="Role-Based Access Control" term="Role-Based Access Control"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Trace and visualize the relationships between the kubernetes resources with KubeVela]]></title>
        <id>https://kubevela.io/blog/2022/06/10/visualize-resources/</id>
        <link href="https://kubevela.io/blog/2022/06/10/visualize-resources/"/>
        <updated>2022-06-10T00:00:00.000Z</updated>
        <content type="html"><![CDATA[<p>One of the biggest requests from KubeVela community is to provide a transparent delivery process for resources in the application. For example, many users prefer to use Helm Chart to package a lot of complex YAML, but once there is any issue during the deployment, such as the underlying storage can not be provided normally, the associated resources are not created normally, or the underlying configuration is incorrect, etc., even a small problem will be a huge threshold for troubleshooting due to the black box of Helm chart. Especially in the modern hybrid multi-cluster environment, there is a wide range of resources, how to obtain effective information and solve the problem? This can be a very big challenge.</p>
<p><img decoding="async" loading="lazy" src="https://kubevela.io/images/1.4/resource-graph.jpg" alt="resource graph" class="img_ev3q"></p>
<p>As shown in the figure above, KubeVela has offered a real-time observation resource topology graph for applications, which further improves KubeVela's application-centric delivery experience. Developers only need to care about simple and consistent APIs when initiating application delivery. When they need to troubleshoot problems or pay attention to the delivery process, they can use the resource topology graph to quickly obtain the arrangement relationship of resources in different clusters, from the application to the running status of the Pod instance. Automatically obtain resource relationships, including complex and black-box Helm Charts.</p>
<p>In this post, we will describe how this new feature of KubeVela is implemented and works, and the roadmap for this feature.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="application-resource-composition">Application resource composition<a href="https://kubevela.io/blog/2022/06/10/visualize-resources/#application-resource-composition" class="hash-link" aria-label="Direct link to Application resource composition" title="Direct link to Application resource composition" translate="no">​</a></h2>
<p>In KubeVela, an application consists of multiple components and traits and is associated with delivery workflow and delivery policy configuration. The application configuration generates Kubernetes resources through rendering and inspection and applies them to the target cluster. Take a simple application as an example:</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token key atrule">apiVersion</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> core.oam.dev/v1beta1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> Application</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">metadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> first</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">vela</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">app</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">spec</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">components</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> express</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">server</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> webservice</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">image</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> oamdev/hello</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">world</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">ports</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">         </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">port</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token number">8000</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">           </span><span class="token key atrule">expose</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token boolean important">false</span><br></span></code></pre></div></div>
<p>Based on the above configuration, a <code>Deployment</code> resource will be rendered and deployed to the target cluster, if we slightly add some configuration, such as:</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token key atrule">apiVersion</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> core.oam.dev/v1beta1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> Application</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">metadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> first</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">vela</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">app</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">spec</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">components</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> express</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">server</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> webservice</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">image</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> oamdev/hello</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">world</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">ports</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">         </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">port</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token number">8000</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">           </span><span class="token key atrule">expose</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">  </span><span class="token boolean important">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">traits</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> gateway</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token key atrule">domain</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> testsvc.example.com</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token key atrule">http</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">              </span><span class="token key atrule">"/"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token number">8000</span><br></span></code></pre></div></div>
<p>In the above configuration, we set the <code>expose</code> field of port 8000 to true, and add a trait with type <code>gateway</code>. The application will render three resources <code>Deployment</code> + <code>Service</code> + <code>Ingress</code>.</p>
<p>As mentioned above, the resources directly rendered by the application are called <b>Direct Resources</b>, and they will be stored in <code>ResourceTracker</code> as version records at the same time, and these resources can be obtained by direct indexing. When these resources are delivered to the target cluster, taking the <code>Deployment</code> resource as an example, the lower-level resource <code>ReplicaSet</code> will be generated, and then the lower-level resource <code>Pod</code> will be derived. These secondary derived resources from direct resources are called <b>Indirect Resources</b>. An application resource tree consists of direct resources and indirect resources, that work together to run dynamic applications at scale.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="trace-and-visualize-resources-relationships">Trace and Visualize resources’ relationships<a href="https://kubevela.io/blog/2022/06/10/visualize-resources/#trace-and-visualize-resources-relationships" class="hash-link" aria-label="Direct link to Trace and Visualize resources’ relationships" title="Direct link to Trace and Visualize resources’ relationships" translate="no">​</a></h2>
<p>The relationship chain <code>Deployment</code> =&gt; <code>ReplicaSet</code> =&gt; <code>Pod</code> described in the previous chapter is a resource cascade relationship, which is also the introductory knowledge of the Kubernetes system. We can build this relationship chain very easily through experience. Where <code>Deployment</code> is a direct resource, which we can index to based on (application &amp; component &amp; cluster) conditions. Next, we mainly build the relationship between the indirect resources.</p>
<p>In Kubernetes, the concept of Owner Reference is designed to record the relationship between resources. For example, in the following use case, the Pod resource records its parent resource ReplicaSet.</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token key atrule">apiVersion</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> v1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> Pod</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">metadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> kruise</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">rollout</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">controller</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">manager</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">696bdb76f8</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">92rsn</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">ownerReferences</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">apiVersion</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> apps/v1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">blockOwnerDeletion</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token boolean important">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">controller</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token boolean important">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> ReplicaSet</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> kruise</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">rollout</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">controller</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">manager</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">696bdb76f8</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">uid</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> aba76833</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">b6e3</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">4231</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">bf2e</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">539c81be9278</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">...</span><br></span></code></pre></div></div>
<p>Therefore, we can reversely build any resource-dependent link through the resource's Owner Reference. However, there are two difficulties here:</p>
<ol>
<li class="">
<p>The resource links in our experience may not necessarily be constructed through Owner Reference, such as the HelmRelease resource, which is the resource API defined by FluxCD to deliver the Helm Chart artifacts. In KubeVela, we use this API to deliver Helm Chart artifacts. Helm Chart can theoretically include any Kubernetes cluster resource type. From user experience, these resources are subordinate resources of HelmRelease, but HelmRelease cannot be the owner of these resources at present. That is to say, we cannot build a tracking link similar to the HelmRelease resource through Owner Reference.</p>
</li>
<li class="">
<p>When forward tracing resources, if you do not know the subordinate resource types, you need to traverse and query all types of resources and then filter them according to the Owner Reference, which results in a large amount of computation and puts a lot of pressure on the Kubernetes API.</p>
</li>
</ol>
<p>The cascading relationship of application resources is often the link when we troubleshoot application failures or configuration errors. If your Kubernetes experience cannot build such a link, it will be very difficult to troubleshoot Kubernetes application failures. For example, HelmRelease, once encountering a failure, maybe we need to check the definition source code of Chart to know which subordinate resources it will generate. This threshold may hinder 90% of developers and users.</p>
<p>There are many types resources that do not follow the Owner Reference in Kubernetes and continue to grow. Therefore, we need to enable the system to have the ability to learn to speed up forward queries and adapt to resources that do not follow the Owner Reference mechanism.</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token key atrule">apiVersion</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> v1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> ConfigMap</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">metadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> clone</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">set</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">relation</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">namespace</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> vela</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">system</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">labels</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">"rules.oam.dev/resources"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"true"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">data</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">rules</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">|</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">parentResourceType</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">group</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> apps.kruise.io</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> CloneSet</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">childrenResourceType</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">apiVersion</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> v1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> Pod</span><br></span></code></pre></div></div>
<p>The above is a configuration use case that informs KubeVela that the <code>CloneSet</code> resource cascades down the <code>Pod</code>, KubeVela will query the Pod that satisfies the Owner Reference condition from the same Namespace, so that the query complexity is O(1). A rule defines multiple resource types that are associated with a parent type down, this way is called static configuration learning. We need to implement more rules:</p>
<p>For example, if we need to pay attention to whether the Service is correctly associated with the Pod, and whether the PVC is correctly associated with the PV, there is no Owner Reference filter rule between these resources. If only configuring the type is not enough, we also need to have filter conditions, such as through labels, name, etc. At present, this part of the logic of KubeVela has some built-in rules. In addition, to simplify the user's burden of configuring static learning rules, we plan to implement dynamic learning capabilities. Based on all resource types in the current cluster, the system can dynamically analyze a certain type of resource as the owner of which types of resources. The result rules can be shared.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="visualize-the-resource-status-and-key-information">Visualize the resource status and key information<a href="https://kubevela.io/blog/2022/06/10/visualize-resources/#visualize-the-resource-status-and-key-information" class="hash-link" aria-label="Direct link to Visualize the resource status and key information" title="Direct link to Visualize the resource status and key information" translate="no">​</a></h2>
<p>If there is only a resource relationship, it cannot solve our difficulties. We also need to be able to directly reflect exceptions, so that developers can have O(1) complexity when troubleshooting errors. Different resources have slightly different state calculations, but the general resource state has a Condition field that represents its final state. Based on this, the resource state calculation logic is formed by adding the state calculation method of a specific resource. We divide the resource state into normal, in-progress and abnormal, which are represented by blue, yellow and red border colors on the topology graph node, which is convenient for users to distinguish.</p>
<p><img decoding="async" loading="lazy" src="https://kubevela.io/images/1.4/multiple-cluster-graph.jpg" alt="multiple-cluster-graph" class="img_ev3q"></p>
<p>In addition, different resources have different key information, such as whether PVC is bound, whether Pod instance is started, whether Service resource is associated with external IP and so on. These are called key information, and some information is displayed on the resource node bottom, others display when the mouse moves over the node. The information helps you quickly determine whether the resource configuration is correct and its status is normal.</p>
<p>Further, if you want to query the detailed configuration of ConfigMap, whether the capacity and access method of PersistentVolumes are correct, whether the RBAC authorization rules are correct, etc., you do not need to leave the VelaUX and manually dig through YAML files. Initiate a query by clicking the Detail button in the node extension area. KubeVela will securely query and display the latest configurations from the target cluster through the cluster gateway.</p>
<p><img decoding="async" loading="lazy" src="https://kubevela.net/assets/images/resouce-detail-0919c787c88e6b38f00ea490d558a927.jpg" alt="resource-detail" class="img_ev3q"></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="whats-next">What's next?<a href="https://kubevela.io/blog/2022/06/10/visualize-resources/#whats-next" class="hash-link" aria-label="Direct link to What's next?" title="Direct link to What's next?" translate="no">​</a></h2>
<ul>
<li class="">More intelligent</li>
</ul>
<p>We will continue to refine the default rules and find more ways to intelligently judge resource diagrams and key information so that developers can troubleshoot errors without too much experience.</p>
<ul>
<li class="">Application topology graph</li>
</ul>
<p>What we are currently building is the Kubernetes resource map, which is actually not our original intention. We prefer that business developers only pay attention to the application and all the relationships and states of its components, and at the same time combine business metrics analysis and monitoring data to reflect the operating pressure of the service.</p>
<ul>
<li class="">More runtimes</li>
</ul>
<p>The currently established resource relationship graph is mainly based on Kubernetes resources. KubeVela also has a core runtime that is a cloud service platform. We need to associate the resource system of cloud services with the resource topology graph. Makes it easier for developers to manage multi-cloud applications.</p>]]></content>
        <author>
            <name>Qingguo Zeng</name>
            <uri>https://github.com/barnettZQG</uri>
        </author>
        <category label="KubeVela" term="KubeVela"/>
        <category label="Observable" term="Observable"/>
    </entry>
</feed>