<script type="application/json" id="HeaderNotice-apollo-state-992f9e1e-c79c-43fb-96a9-089d825fa346">{}</script> <!-- glamorIds: 7 --> <script type="application/json" id="HeaderNotice-glamor-992f9e1e-c79c-43fb-96a9-089d825fa346">["1htug8r","1yodi52","iepywa","x5hg3h","u0iaox","9ilv8v","gwph6j"]</script> <style>@-webkit-keyframes animation_1htug8r{to{transform:rotate(360deg);-webkit-transform:rotate(360deg);}}@-moz-keyframes animation_1htug8r{to{transform:rotate(360deg);-webkit-transform:rotate(360deg);}}@-o-keyframes animation_1htug8r{to{transform:rotate(360deg);-webkit-transform:rotate(360deg);}}@keyframes animation_1htug8r{to{transform:rotate(360deg);-webkit-transform:rotate(360deg);}}@-webkit-keyframes animation_1yodi52{0%{background-position:0 0;}100%{background-position:100em 0;}}@-moz-keyframes animation_1yodi52{0%{background-position:0 0;}100%{background-position:100em 0;}}@-o-keyframes animation_1yodi52{0%{background-position:0 0;}100%{background-position:100em 0;}}@keyframes animation_1yodi52{0%{background-position:0 0;}100%{background-position:100em 0;}}@-webkit-keyframes animation_iepywa{0%, 100%{opacity:0;}50%{opacity:1;}}@-moz-keyframes animation_iepywa{0%, 100%{opacity:0;}50%{opacity:1;}}@-o-keyframes animation_iepywa{0%, 100%{opacity:0;}50%{opacity:1;}}@keyframes animation_iepywa{0%, 100%{opacity:0;}50%{opacity:1;}}@-webkit-keyframes animation_x5hg3h{100%{stroke-dashoffset:0;}}@-moz-keyframes animation_x5hg3h{100%{stroke-dashoffset:0;}}@-o-keyframes animation_x5hg3h{100%{stroke-dashoffset:0;}}@keyframes animation_x5hg3h{100%{stroke-dashoffset:0;}}@-webkit-keyframes animation_u0iaox{0%, 100%{transform:none;-webkit-transform:none;}50%{transform:scale3d(1.1, 1.1, 1);-webkit-transform:scale3d(1.1, 1.1, 1);}}@-moz-keyframes animation_u0iaox{0%, 100%{transform:none;-webkit-transform:none;}50%{transform:scale3d(1.1, 1.1, 1);-webkit-transform:scale3d(1.1, 1.1, 1);}}@-o-keyframes animation_u0iaox{0%, 100%{transform:none;-webkit-transform:none;}50%{transform:scale3d(1.1, 1.1, 1);-webkit-transform:scale3d(1.1, 1.1, 1);}}@keyframes animation_u0iaox{0%, 100%{transform:none;-webkit-transform:none;}50%{transform:scale3d(1.1, 1.1, 1);-webkit-transform:scale3d(1.1, 1.1, 1);}}@-webkit-keyframes animation_9ilv8v{100%{box-shadow:inset 0px 0px 0px 30px #068dfe;}}@-moz-keyframes animation_9ilv8v{100%{box-shadow:inset 0px 0px 0px 30px #068dfe;}}@-o-keyframes animation_9ilv8v{100%{box-shadow:inset 0px 0px 0px 30px #068dfe;}}@keyframes animation_9ilv8v{100%{box-shadow:inset 0px 0px 0px 30px #068dfe;}}.css-gwph6j,[data-css-gwph6j]{border-radius:2px;background-size:200% 100%;width:auto;height:auto;animation:20s animation_1yodi52 0s linear infinite;background:-webkit-linear-gradient(to right, #f1f1f1 0%, #fbfbfb 50%, #f1f1f1 100%); background: -moz-linear-gradient(to right, #f1f1f1 0%, #fbfbfb 50%, #f1f1f1 100%); background: linear-gradient(to right, #f1f1f1 0%, #fbfbfb 50%, #f1f1f1 100%);-webkit-animation:20s animation_1yodi52 0s linear infinite;}</style> <div id="HeaderNotice-react-component-992f9e1e-c79c-43fb-96a9-089d825fa346" data-ssr="true" ><div style="z-index:1000" class="css-gwph6j"></div></div> <script> renderComponent('HeaderNotice','HeaderNotice-react-component-992f9e1e-c79c-43fb-96a9-089d825fa346','HeaderNotice-apollo-state-992f9e1e-c79c-43fb-96a9-089d825fa346','HeaderNotice-glamor-992f9e1e-c79c-43fb-96a9-089d825fa346', 'apollo','{"mobile":false}'); </script>

Kubecon 2019 Takeaway: We Live in a Multi-Cluster and Multi-Distro World

815
Rafay Systems
Rafay's automation framework provides multi-cluster management and app operations at scale. Create, deploy, operate, monitor, upgrade and retire Kubernetes clusters & k8s-resident applications across multi-regions, clouds and environments.

This blog was co-authored by Rupinder (Robbie) Gill and Haseeb Budhani.

As more enterprise users deploy Kubernetes as their preferred container orchestrator, the following trend has become more widespread:

Development teams that are early in their Kubernetes journey build out larger clusters and use Kubernetes namespaces to implement multi-tenancy.

This seems like a logical choice, given the namespace concept is designed to do exactly this. But in practice, teams that have been at it for some time and have experienced multiple Kubernetes version upgrades tend to spin up many, smaller clusters and choose to group fewer services into the same cluster.

Why the difference in opinion? Experience.

The following are the technical reasons why these experienced teams are choosing to go with the many, smaller clusters approach:

  • Blast radius: Every time Kubernetes or a supporting component (e.g. service mesh or metrics collection packages) is upgraded, each service may need to be updated to work with the new version. Someone needs to make sure that all services in a given cluster are ready to work with new APIs if older APIs have been deprecated in the new version. This type of upgrade can impact schedules across multiple teams. Best to let teams run smaller clusters where the impact can be broken up into smaller morsels.
  • Security requirements: A set of services may have unique hardening and data retention requirements, and it may make sense to deploy these services in a hardened cluster with stringent auditing, auth and logging policies. But doing this across the board may lead to unnecessary slowdowns and overhead.
  • Scaling requirements: If a few services have massive scaling requirements, it may be best to deploy them into dedicated clusters to protect against other services experiencing “pod pending” events due to busier services taking up an inordinate percentage of available resources.
  • Integration requirements: Some services may need a special admission controller, high-speed storage, and so on, while others may not. Such special integration requirements may also apply to service meshes and key-management services. Services that need such integrations may be best grouped together in clusters that are pre-configured with required packages or the right storage class, while other services can be deployed on clusters running vanilla Kubernetes.
  • Custom enhancements: Some services may lead the DevOps team to develop enhancements to Kubernetes. To protect against unforeseen side effects (bugs) from such enhancements, services that need these enhancements can be deployed on customized clusters, while other services can be deployed on clusters running vanilla Kubernetes.
  • Network load requirements: Services that are expected to drive high network load (by way of Kubernetes API calls) are best deployed on separate clusters to protect other services that may get starved otherwise.

There are also valid business reasons for running many, smaller clusters:

  • Compliance: If end users are distributed globally, it's better to deploy clusters in target geographies to comply with data sovereignty or other regional regulations instead of implementing complex data management strategies centrally.
  • Hybrid or multi-cloud strategies: Many companies need to manage a mix of environments for a variety of reasons, ranging from pre-existing assets (colo contracts and servers), M&A activity to demanding customers (“I don’t do business with vendors that run their apps on AWS.”).
  • Performance: If the end user population is spread across geographies and, if the application is designed appropriately, it may make sense to deploy the web and application tiers in multiple regions, i.e. across multiple clusters. And if you’re thinking of running a cross-region cluster, be ready to address etcd sync issues and cross-pod traffic management across the WAN.

The fact that companies such as VMware (see Tanzu Mission Control) and Microsoft (see Azure Arc) recently announced tech previews of products to help companies manage clusters across hybrid environments implies they also realize this trend.

Because your peers are not only running multiple clusters, but are also leveraging more than one Kubernetes distributions, a high percentage of teams are running two or more Kubernetes distributions across their public cloud and on-premise footprints. The common belief is that cloud providers will do their best to optimize their Kubernetes offerings for their infrastructure, so its best to use EKS in AWS, GKE in GCP, AKS in Azure, and OpenShift or PKS on premises.

At Rafay, we follow the same methodology: We use the resident managed Kubernetes service in our cloud provider of choice instead of spinning up, for example, v1.16.1 ourselves on virtual machines. And - of course - we run many, small clusters.

There are many hurdles to cross in keeping modern applications operational, and if the public cloud (or VMware & RedHat) is able to take away the pain of keeping the Kubernetes control plane up and running, why would anyone not leverage that? What’s more, the cost of running Kubernetes in public clouds is fast approaching zero. You pay for the worker node VMs and the master node costs are a rounding error or downright free.

Operating services across multiple clusters and multiple distros simplifies the development process. Ongoing complexity is reduced because developers no longer have to add complex logic in each service to address environmental characteristics such as service meshes, storage classes and admission controllers. With a growing cluster fleet that may span multiple clouds & data centers, and leveraging multiple Kubernetes distributions, SRE/Ops need tooling to manage their cluster fleet. SRE/Ops teams must now solve for:

  1. Complete visibility and governance across the company’s fleet of Kubernetes clusters, regardless of distribution. They must be able to quickly figure out where a given service is running at present, which app is experiencing restarts in a given cluster, which apps have been upgraded across the fleet in the last month, and much more.
  2. On-demand Cluster bringup and customization in any cloud environment or on premises. In addition to simply bringing up EKS, GKE, etc., SRE/Ops are responsible for ensuring that a given cluster is customized appropriately and conforms to the business’ security/compliance requirements.
  3. Continuous deployment capabilities across the entire cluster fleet without requiring multiple deployment tools. SRE/Ops need access to deployment tools that work across any cluster type, in any environment, and do not require scripting/coding investments that traditionally fall on DevOps teams.

We live in a multi-distro, multi-cluster world. At Rafay, we run our SaaS controller as a cloud-native service that leverages a variety of open source and home-grown components - we are living the gospel we preach. We operate many, small clusters. And so should you, if you aren’t doing it already.

But this is an issue that cloud providers don’t have an incentive to solve for you. When engaging with a vendor focused on helping your SRE/Ops teams address the complexity of managing multiple clusters running a variety of distros, be sure to ask for their plan for the above 3 requirements. Rafay delivers these capabilities today and can simplify ongoing operations for Kubernetes environments as a service.

Want to understand how Rafay can help you operate a fleet of clusters across any environment? Get in touch.

Rafay Systems
Rafay's automation framework provides multi-cluster management and app operations at scale. Create, deploy, operate, monitor, upgrade and retire Kubernetes clusters & k8s-resident applications across multi-regions, clouds and environments.
Tools mentioned in article
<script type="application/json" id="Footer-apollo-state-b887cc69-1029-4251-be72-f428c4a31686">{}</script> <!-- glamorIds: 21 --> <script type="application/json" id="Footer-glamor-b887cc69-1029-4251-be72-f428c4a31686">["1htug8r","1yodi52","iepywa","x5hg3h","u0iaox","9ilv8v","ts0y2j","cs546h","1fco1ts","11a2nsi","1npm75a","1gn11bn","1y302zr","11gxadc","1iqd2ec","lneilx","de1dx1","1h53588","12k57td","j1o656","zr18wh"]</script> <style>@-webkit-keyframes animation_1htug8r{to{transform:rotate(360deg);-webkit-transform:rotate(360deg);}}@-moz-keyframes animation_1htug8r{to{transform:rotate(360deg);-webkit-transform:rotate(360deg);}}@-o-keyframes animation_1htug8r{to{transform:rotate(360deg);-webkit-transform:rotate(360deg);}}@keyframes animation_1htug8r{to{transform:rotate(360deg);-webkit-transform:rotate(360deg);}}@-webkit-keyframes animation_1yodi52{0%{background-position:0 0;}100%{background-position:100em 0;}}@-moz-keyframes animation_1yodi52{0%{background-position:0 0;}100%{background-position:100em 0;}}@-o-keyframes animation_1yodi52{0%{background-position:0 0;}100%{background-position:100em 0;}}@keyframes animation_1yodi52{0%{background-position:0 0;}100%{background-position:100em 0;}}@-webkit-keyframes animation_iepywa{0%, 100%{opacity:0;}50%{opacity:1;}}@-moz-keyframes animation_iepywa{0%, 100%{opacity:0;}50%{opacity:1;}}@-o-keyframes animation_iepywa{0%, 100%{opacity:0;}50%{opacity:1;}}@keyframes animation_iepywa{0%, 100%{opacity:0;}50%{opacity:1;}}@-webkit-keyframes animation_x5hg3h{100%{stroke-dashoffset:0;}}@-moz-keyframes animation_x5hg3h{100%{stroke-dashoffset:0;}}@-o-keyframes animation_x5hg3h{100%{stroke-dashoffset:0;}}@keyframes animation_x5hg3h{100%{stroke-dashoffset:0;}}@-webkit-keyframes animation_u0iaox{0%, 100%{transform:none;-webkit-transform:none;}50%{transform:scale3d(1.1, 1.1, 1);-webkit-transform:scale3d(1.1, 1.1, 1);}}@-moz-keyframes animation_u0iaox{0%, 100%{transform:none;-webkit-transform:none;}50%{transform:scale3d(1.1, 1.1, 1);-webkit-transform:scale3d(1.1, 1.1, 1);}}@-o-keyframes animation_u0iaox{0%, 100%{transform:none;-webkit-transform:none;}50%{transform:scale3d(1.1, 1.1, 1);-webkit-transform:scale3d(1.1, 1.1, 1);}}@keyframes animation_u0iaox{0%, 100%{transform:none;-webkit-transform:none;}50%{transform:scale3d(1.1, 1.1, 1);-webkit-transform:scale3d(1.1, 1.1, 1);}}@-webkit-keyframes animation_9ilv8v{100%{box-shadow:inset 0px 0px 0px 30px #068dfe;}}@-moz-keyframes animation_9ilv8v{100%{box-shadow:inset 0px 0px 0px 30px #068dfe;}}@-o-keyframes animation_9ilv8v{100%{box-shadow:inset 0px 0px 0px 30px #068dfe;}}@keyframes animation_9ilv8v{100%{box-shadow:inset 0px 0px 0px 30px #068dfe;}}.css-ts0y2j,[data-css-ts0y2j]{font-family:Open Sans, Helvetica Neue, Helvetica, Arial, sans;font-weight:400;font-size:13px;line-height:1.4;letter-spacing:normal;-webkit-font-smoothing:antialiased;background:#333;display:-webkit-box; display: -moz-box; display: -ms-flexbox; display: -webkit-flex; display: flex;justify-content:center;align-items:center;padding:50px 0 80px;-webkit-box-pack:center;-webkit-justify-content:center;-webkit-box-align:center;-webkit-align-items:center;}@media only screen and (max-width: 768px){.css-ts0y2j,[data-css-ts0y2j]{padding:0 0 40px;}}.css-cs546h,[data-css-cs546h]{max-width:1220px;}@media only screen and (max-width: 992px){.css-cs546h,[data-css-cs546h]{width:700px;}}@media only screen and (min-width: 993px){.css-cs546h,[data-css-cs546h]{width:955px;}}@media only screen and (min-width: 1200px){.css-cs546h,[data-css-cs546h]{width:1220px;}}.css-1fco1ts,[data-css-1fco1ts]{display:grid;grid-template-columns:repeat(4, 1fr);justify-items:center;column-gap:3%;-ms-grid-template-columns:repeat(4, 1fr);-webkit-column-gap:3%;-moz-column-gap:3%;}@media only screen and (max-width: 768px){.css-1fco1ts,[data-css-1fco1ts]{grid-template-columns:1fr;text-align:center;-ms-grid-template-columns:1fr;}}.css-11a2nsi,[data-css-11a2nsi]{display:-webkit-box; display: -moz-box; display: -ms-flexbox; display: -webkit-flex; display: flex;flex-direction:column;align-items:center;text-align:left;width:100%;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-webkit-box-align:center;-webkit-align-items:center;}.css-1npm75a,[data-css-1npm75a]{display:-webkit-box; display: -moz-box; display: -ms-flexbox; display: -webkit-flex; display: flex;flex-direction:column;color:#fff;font-size:14px;line-height:1.7;letter-spacing:0.3px;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;}.css-1npm75a a,[data-css-1npm75a] a{color:#fff;text-decoration:none;}.css-1npm75a a:visited,[data-css-1npm75a] a:visited{color:#fff;}.css-1npm75a a:hover,[data-css-1npm75a] a:hover{color:#068dfe;}.css-1npm75a a:hover span,[data-css-1npm75a] a:hover span{color:#fff;}.css-1npm75a a:active span,[data-css-1npm75a] a:active span{color:#fff;}@media only screen and (max-width: 768px){.css-1npm75a,[data-css-1npm75a]{align-items:center;width:95%;font-size:16px;line-height:2;-webkit-box-align:center;-webkit-align-items:center;}}.css-1gn11bn,[data-css-1gn11bn]{color:#fff;font-weight:600;font-size:20px;letter-spacing:0.38px;}@media only screen and (max-width: 768px){.css-1gn11bn,[data-css-1gn11bn]{margin-top:36px;margin-bottom:24px;}}.css-1y302zr,[data-css-1y302zr]{position:relative;}@media only screen and (min-width: 769px){.css-1y302zr,[data-css-1y302zr]{margin-right:auto;}}.css-11gxadc,[data-css-11gxadc]{padding:0;margin:8px 0;}.css-11gxadc li,[data-css-11gxadc] li{display:inline-block;margin:0 5px;}@media only screen and (min-width: 769px){.css-11gxadc li:first-child,[data-css-11gxadc] li:first-child{margin-left:0;}}@media only screen and (max-width: 768px){.css-11gxadc,[data-css-11gxadc]{margin:0 0 80px;}}.css-1iqd2ec svg:hover path,[data-css-1iqd2ec] svg:hover path{fill:#939393;}.css-lneilx,[data-css-lneilx]{margin-top:15px;line-height:100%;}.css-lneilx svg,[data-css-lneilx] svg{max-width:135px;}.css-lneilx svg g,[data-css-lneilx] svg g{fill:#fff;}@media only screen and (max-width: 768px){.css-lneilx,[data-css-lneilx]{margin-top:0;}}@media only screen and (max-width: 480px){.css-lneilx,[data-css-lneilx]{margin-top:0;}}.css-de1dx1,[data-css-de1dx1]{color:#fff;}.css-de1dx1 a,[data-css-de1dx1] a, .css-de1dx1 span, [data-css-de1dx1] span{display:inline-block;margin-right:8px;font-size:13px;letter-spacing:0.24px;}.css-de1dx1 a:last-child,[data-css-de1dx1] a:last-child{margin-right:0;}@media only screen and (max-width: 768px){.css-de1dx1,[data-css-de1dx1]{line-height:1.5;margin-top:14px;margin-bottom:11px;}}.css-1h53588,[data-css-1h53588]{margin:18px 0;}@media only screen and (max-width: 992px){.css-1h53588,[data-css-1h53588]{text-align:center;}}@media only screen and (max-width: 480px){.css-1h53588,[data-css-1h53588]{text-align:center;}}.css-12k57td,[data-css-12k57td]{font-family:Cerebri Sans Pro;margin-top:0;font-style:normal;font-weight:400;font-size:14px;line-height:25px;letter-spacing:0.375px;color:#fff;}.css-j1o656,[data-css-j1o656]{width:53px;height:53px;}.css-zr18wh,[data-css-zr18wh]{color:#c2c2c2;font-size:10px;margin-top:5px;}.css-zr18wh div,[data-css-zr18wh] div{white-space:nowrap;}@media only screen and (max-width: 768px){.css-zr18wh,[data-css-zr18wh]{font-size:13px;line-height:1.5;text-align:center;}}</style> <div id="Footer-react-component-b887cc69-1029-4251-be72-f428c4a31686" data-ssr="true" ><footer class="css-ts0y2j"><div class="css-cs546h"><div class="css-1fco1ts"><div class="css-11a2nsi"><div class="css-1npm75a"><h3 class="css-1gn11bn">Tools &amp; Services</h3><a href="/stackups/trending" title="Compare Tools">Compare Tools</a><a href="/search" title="Search Tools &amp; Services">Search</a><a href="/alternatives" title="Browse Tools &amp; Services">Browse Tool Alternatives</a><a href="/categories" title="Technology Tools &amp; Services">Browse Tool Categories</a><a href="/submit" title="Submit a Tool">Submit A Tool</a><a href="/admin/approval-tool" title="Approve Tools">Approve Tools</a></div></div><div class="css-11a2nsi"><div class="css-1npm75a"><h3 class="css-1gn11bn">Company</h3><a href="/featured-posts" title="Featured Posts">Blog</a><a href="/api" title="API">API</a><a href="/jobs" title="Jobs">Job Search</a><a href="/careers" title="Careers at StackShare" class="css-1y302zr">Careers</a><a href="/stackshare" title="Our Stack">Our Stack</a><a href="/vendors" title="Advertise With Us">Advertise With Us</a><a href="mailto:team@stackshare.io" title="Contact Us">Contact Us</a></div></div><div class="css-11a2nsi"><div class="css-1npm75a"><h3 class="css-1gn11bn">Follow Us</h3><ul class="css-11gxadc"><li><a href="https://twitter.com/stackshareio" target="_blank" rel="noreferrer noopener nofollow" class="css-1iqd2ec"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="#FFF" fill-rule="evenodd" d="M3.6 0h16.8A3.6 3.6 0 0 1 24 3.6v16.8a3.6 3.6 0 0 1-3.6 3.6H3.6A3.6 3.6 0 0 1 0 20.4V3.6A3.6 3.6 0 0 1 3.6 0zm14.29 9.964c.548-.389 1.005-.891 1.393-1.44a6.285 6.285 0 0 1-1.621.435c.594-.343 1.005-.891 1.21-1.553a5.867 5.867 0 0 1-1.758.685A2.759 2.759 0 0 0 15.08 7.2a2.788 2.788 0 0 0-2.787 2.81c0 .205.023.433.069.639A7.976 7.976 0 0 1 6.56 7.702a3.037 3.037 0 0 0-.365 1.417c0 .982.48 1.827 1.233 2.33-.456 0-.89-.138-1.256-.343v.022c0 1.37.96 2.49 2.238 2.764-.228.069-.48.092-.73.092-.183 0-.366-.023-.526-.046.343 1.119 1.394 1.873 2.604 1.896-.96.753-2.147 1.279-3.472 1.279a6 6 0 0 1-.662-.046c1.233.8 2.718 1.233 4.294 1.233 5.162 0 7.971-4.27 7.971-7.97v-.366z"></path></svg></a></li><li><a href="https://facebook.com/stackshareio" target="_blank" rel="noreferrer noopener nofollow" class="css-1iqd2ec"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="#FFF" fill-rule="evenodd" d="M16.478 24v-8h2.896l.201-3.069h-3.097v-2.237c0-.86.172-1.405 1.262-1.405h1.692l.143-2.925s-.86-.172-2.351-.172c-3.04 0-4.36 1.835-4.36 3.9v2.81H10.8V16h2.065v8H3.6A3.6 3.6 0 0 1 0 20.4V3.6A3.6 3.6 0 0 1 3.6 0h16.8A3.6 3.6 0 0 1 24 3.6v16.8a3.6 3.6 0 0 1-3.6 3.6h-3.922z"></path></svg></a></li><li><a href="https://www.linkedin.com/company/stackshare" target="_blank" rel="noreferrer noopener nofollow" class="css-1iqd2ec"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="#FFF" fill-rule="evenodd" d="M3.6 0h16.8A3.6 3.6 0 0 1 24 3.6v16.8a3.6 3.6 0 0 1-3.6 3.6H3.6A3.6 3.6 0 0 1 0 20.4V3.6A3.6 3.6 0 0 1 3.6 0zm5.521 17.16V9.378H6.374v7.782h2.747zM7.748 8.43c1.119 0 1.83-.807 1.83-1.815C9.554 5.578 8.868 4.8 7.749 4.8c-1.094 0-1.831.778-1.831 1.815 0 1.008.712 1.815 1.805 1.815h.026zm11.444 8.73v-4.12c0-2.518-1.246-4.12-3.205-4.12-1.119 0-1.932.661-2.288 1.653l-.102-1.195h-2.721c.025.305.076 1.83.076 1.83v5.952h2.747v-4.12c0-1.12.508-1.831 1.347-1.831.84 0 1.4.432 1.4 1.83v4.12h2.746z"></path></svg></a></li><li><a href="https://angel.co/stackshare" target="_blank" rel="noreferrer noopener nofollow" class="css-1iqd2ec"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="#FFF" fill-rule="evenodd" d="M3.6 0h16.8A3.6 3.6 0 0 1 24 3.6v16.8a3.6 3.6 0 0 1-3.6 3.6H3.6A3.6 3.6 0 0 1 0 20.4V3.6A3.6 3.6 0 0 1 3.6 0zm4.684 14.42c.365.493.708.877 1.029 1.153.322.276.579.413.769.413.14 0 .268-.064.385-.194a.624.624 0 0 0 .173-.42c0-.16-.114-.528-.341-1.11-.227-.58-.512-1.15-.849-1.71-.249-.418-.492-.733-.732-.947-.24-.214-.466-.319-.68-.319-.174 0-.366.111-.577.33-.212.223-.317.43-.317.622 0 .2.102.501.309.903.207.4.484.827.83 1.28zm6.062-4.06a89.757 89.757 0 0 0 1.296-3.767c.31-.99.465-1.598.465-1.824 0-.242-.053-.43-.155-.563h-.001a.51.51 0 0 0-.429-.2c-.23 0-.468.194-.707.582-.24.389-.505 1.014-.793 1.875l-1.238 3.622 1.562.275zm-4.45-.445a.982.982 0 0 1 .371-.058c.05 0 .149.005.298.013.147.01.392.03.73.063L9.958 6.022c-.347-.993-.615-1.644-.806-1.949-.19-.303-.397-.456-.619-.456a.513.513 0 0 0-.422.2c-.107.133-.16.313-.16.54 0 .384.144 1.052.433 2.004.29.953.724 2.202 1.303 3.749a.41.41 0 0 1 .21-.195zm6.22 2.129a1.006 1.006 0 0 0-.245-.293c-.338-.285-.998-.54-1.979-.765a13.608 13.608 0 0 0-3.068-.338c-.296 0-.508.05-.632.15-.124.1-.186.272-.186.516 0 .567.314.98.943 1.233.627.255 1.643.382 3.049.382h.508c.116 0 .21.044.279.133.07.088.118.219.142.394-.14.134-.43.287-.866.456-.438.172-.774.341-1.005.508a4.53 4.53 0 0 0-1.196 1.31 3.99 3.99 0 0 0-.198.374c-.04.09-.07.176-.102.263-.012.034-.029.067-.04.1-.018.063-.03.125-.044.188-.013.056-.032.11-.04.166-.006.039-.006.076-.01.114-.008.076-.019.154-.019.228v.001c0 .277.063.609.192.997.128.388.192.629.192.72v.086l-.025.112c-.364-.023-.65-.239-.863-.644-.21-.406-.315-.947-.315-1.622v-.112a.719.719 0 0 1-.192.125.553.553 0 0 1-.205.037c-.074 0-.144-.006-.212-.019a2.132 2.132 0 0 1-.222-.058v.001c.024.094.043.182.056.27a1.05 1.05 0 0 1-.34 1.003 1.22 1.22 0 0 1-.856.331c-.52 0-1.05-.256-1.587-.77-.537-.515-.806-1.017-.806-1.51 0-.091.01-.172.032-.243a.406.406 0 0 1 .104-.182c.115.142.278.35.483.627.545.76 1.05 1.14 1.512 1.14.157 0 .297-.05.422-.149.123-.1.185-.206.185-.313v-.001c0-.127-.083-.334-.248-.629a8.366 8.366 0 0 0-.681-.99c-.33-.425-.606-.736-.826-.933-.217-.196-.394-.295-.525-.295-.29 0-.557.157-.8.47a1.756 1.756 0 0 0-.366 1.11c0 .344.086.725.254 1.147.168.422.416.846.738 1.271a4.937 4.937 0 0 0 1.816 1.524c.723.355 1.522.532 2.4.532 1.611 0 2.96-.607 4.046-1.823 1.088-1.216 1.632-2.739 1.632-4.568 0-.56-.04-1.005-.124-1.337a1.67 1.67 0 0 0-.162-.425zm-4.733 2.915a6.14 6.14 0 0 1 .626-.682c.218-.206.449-.386.689-.545a8.167 8.167 0 0 1-1.01-.113 5.067 5.067 0 0 1-.912-.252c.133.268.25.535.354.802.103.268.188.532.253.79z"></path></svg></a></li></ul></div></div><div class="css-11a2nsi"><div class="css-1npm75a"><a href="/" class="css-lneilx"><svg width="203" height="31" viewBox="0 0 812 124" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414"><g id="Layer1" fill-rule="nonzero"><path d="M221.086 85.794c0 7.342-2.55 12.933-7.651 16.775-5.101 3.842-12.731 5.762-22.889 5.762-5.208 0-9.647-.352-13.318-1.056-3.671-.704-7.107-1.739-10.308-3.105V88.035c3.628 1.707 7.715 3.137 12.261 4.29 4.546 1.152 8.547 1.728 12.005 1.728 7.085 0 10.628-2.048 10.628-6.146 0-1.537-.469-2.785-1.408-3.746-.939-.96-2.561-2.048-4.866-3.265-2.305-1.216-5.379-2.636-9.22-4.258-5.506-2.305-9.551-4.439-12.133-6.402-2.583-1.964-4.461-4.215-5.635-6.755-1.173-2.54-1.76-5.666-1.76-9.38 0-6.36 2.465-11.279 7.395-14.758 4.93-3.479 11.919-5.218 20.968-5.218 8.623 0 17.01 1.878 25.163 5.634l-5.891 14.086c-3.585-1.537-6.936-2.796-10.052-3.778a31.589 31.589 0 0 0-9.54-1.472c-5.762 0-8.643 1.558-8.643 4.674 0 1.75.928 3.265 2.785 4.546 1.857 1.28 5.922 3.18 12.197 5.698 5.591 2.262 9.689 4.375 12.293 6.339 2.604 1.963 4.524 4.225 5.762 6.786 1.238 2.561 1.857 5.613 1.857 9.156zM259.924 92.773c3.415 0 7.513-.747 12.293-2.241v14.534c-4.866 2.177-10.841 3.265-17.927 3.265-7.811 0-13.499-1.974-17.063-5.922-3.564-3.948-5.346-9.871-5.346-17.767V50.131h-9.348v-8.259l10.756-6.531 5.635-15.11h12.485v15.238h20.04v14.662h-20.04v34.511c0 2.774.779 4.823 2.337 6.146 1.558 1.323 3.617 1.985 6.178 1.985zM325.59 107.051l-3.778-9.732h-.512c-3.287 4.14-6.669 7.011-10.148 8.611-3.479 1.601-8.014 2.401-13.606 2.401-6.872 0-12.282-1.963-16.23-5.89-3.949-3.927-5.923-9.519-5.923-16.775 0-7.598 2.657-13.2 7.971-16.807 5.315-3.607 13.329-5.602 24.042-5.986l12.421-.384v-3.138c0-7.256-3.713-10.884-11.14-10.884-5.72 0-12.443 1.728-20.168 5.186l-6.467-13.19c8.238-4.311 17.372-6.466 27.403-6.466 9.604 0 16.967 2.091 22.089 6.274s7.683 10.543 7.683 19.08v47.7H325.59zm-5.763-33.166l-7.555.256c-5.677.171-9.902 1.195-12.677 3.074-2.774 1.878-4.162 4.738-4.162 8.579 0 5.506 3.159 8.259 9.476 8.259 4.525 0 8.142-1.301 10.853-3.905 2.71-2.604 4.065-6.061 4.065-10.372v-5.891zM381.843 108.331c-22.281 0-33.421-12.229-33.421-36.687 0-12.165 3.03-21.459 9.091-27.883 6.061-6.424 14.748-9.636 26.059-9.636 8.281 0 15.708 1.622 22.281 4.866l-5.762 15.11c-3.074-1.238-5.933-2.251-8.58-3.041-2.646-.79-5.293-1.185-7.939-1.185-10.159 0-15.238 7.214-15.238 21.641 0 14.001 5.079 21.001 15.238 21.001 3.756 0 7.235-.502 10.436-1.505 3.202-1.003 6.403-2.571 9.604-4.706v16.711c-3.158 2.006-6.349 3.394-9.572 4.162-3.222.768-7.288 1.152-12.197 1.152zM432.398 68.123l8.516-10.885 20.04-21.769h22.025l-28.428 31.053 30.157 40.529h-22.537l-20.617-29.004-8.387 6.723v22.281h-19.528V7.426h19.528V51.86l-1.025 16.263h.256z"></path><path d="M538.336 85.794c0 7.342-2.55 12.933-7.651 16.775-5.101 3.842-12.73 5.762-22.889 5.762-5.208 0-9.647-.352-13.318-1.056-3.671-.704-7.107-1.739-10.308-3.105V88.035c3.628 1.707 7.715 3.137 12.261 4.29 4.546 1.152 8.548 1.728 12.005 1.728 7.086 0 10.628-2.048 10.628-6.146 0-1.537-.469-2.785-1.408-3.746-.939-.96-2.561-2.048-4.866-3.265-2.305-1.216-5.378-2.636-9.22-4.258-5.506-2.305-9.551-4.439-12.133-6.402-2.582-1.964-4.46-4.215-5.634-6.755-1.174-2.54-1.761-5.666-1.761-9.38 0-6.36 2.465-11.279 7.395-14.758 4.93-3.479 11.92-5.218 20.969-5.218 8.622 0 17.009 1.878 25.162 5.634l-5.89 14.086c-3.586-1.537-6.937-2.796-10.053-3.778a31.589 31.589 0 0 0-9.54-1.472c-5.762 0-8.643 1.558-8.643 4.674 0 1.75.928 3.265 2.785 4.546 1.857 1.28 5.923 3.18 12.197 5.698 5.592 2.262 9.689 4.375 12.293 6.339 2.604 1.963 4.525 4.225 5.763 6.786 1.237 2.561 1.856 5.613 1.856 9.156zM613.093 107.051h-19.528V65.242c0-10.33-3.841-15.495-11.524-15.495-5.464 0-9.412 1.857-11.845 5.571-2.433 3.713-3.65 9.732-3.65 18.055v33.678h-19.528V7.426h19.528v20.296c0 1.58-.149 5.293-.448 11.141l-.448 5.762h1.024c4.354-7 11.269-10.5 20.745-10.5 8.409 0 14.79 2.262 19.144 6.787 4.353 4.524 6.53 11.012 6.53 19.464v46.675zM672.1 107.051l-3.778-9.732h-.512c-3.286 4.14-6.669 7.011-10.148 8.611-3.479 1.601-8.014 2.401-13.606 2.401-6.872 0-12.282-1.963-16.23-5.89-3.948-3.927-5.923-9.519-5.923-16.775 0-7.598 2.657-13.2 7.972-16.807 5.314-3.607 13.328-5.602 24.042-5.986l12.421-.384v-3.138c0-7.256-3.714-10.884-11.141-10.884-5.72 0-12.442 1.728-20.168 5.186l-6.467-13.19c8.238-4.311 17.373-6.466 27.403-6.466 9.604 0 16.967 2.091 22.089 6.274 5.123 4.183 7.684 10.543 7.684 19.08v47.7H672.1zm-5.762-33.166l-7.555.256c-5.677.171-9.903 1.195-12.678 3.074-2.774 1.878-4.161 4.738-4.161 8.579 0 5.506 3.158 8.259 9.475 8.259 4.525 0 8.142-1.301 10.853-3.905 2.71-2.604 4.066-6.061 4.066-10.372v-5.891zM739.238 34.125c2.646 0 4.845.192 6.595.576l-1.473 18.312c-1.579-.427-3.5-.641-5.762-.641-6.232 0-11.088 1.601-14.566 4.802-3.479 3.202-5.218 7.684-5.218 13.446v36.431h-19.528V35.469h14.79l2.881 12.037h.96c2.22-4.012 5.218-7.245 8.996-9.7 3.777-2.454 7.886-3.681 12.325-3.681zM779.293 48.019c-4.141 0-7.385 1.312-9.732 3.937-2.348 2.625-3.692 6.349-4.034 11.173h27.403c-.085-4.824-1.344-8.548-3.777-11.173s-5.72-3.937-9.86-3.937zm2.753 60.312c-11.525 0-20.531-3.18-27.019-9.54-6.488-6.36-9.732-15.366-9.732-27.019 0-11.994 2.998-21.267 8.996-27.819 5.997-6.552 14.288-9.828 24.874-9.828 10.116 0 17.991 2.881 23.625 8.643 5.635 5.763 8.452 13.723 8.452 23.882v9.476h-46.163c.213 5.549 1.857 9.882 4.93 12.997 3.073 3.116 7.384 4.674 12.933 4.674 4.311 0 8.388-.448 12.229-1.344 3.842-.897 7.854-2.326 12.037-4.29v15.11c-3.414 1.708-7.064 2.978-10.948 3.81-3.885.832-8.622 1.248-14.214 1.248z"></path></g><g fill="#008ff9"><path d="M101.98 83c-3.9 0-7.157 2.792-7.886 6.482-.212 1.564 0 3.123 0 3.123.73 3.687 3.986 6.477 7.885 6.477 4.434 0 8.042-3.605 8.042-8.04 0-4.434-3.608-8.042-8.042-8.042M32.041 54C27.607 54 24 57.606 24 62.041c0 4.433 3.607 8.041 8.041 8.041 4.435 0 8.042-3.608 8.042-8.041 0-4.435-3.607-8.041-8.042-8.041m69.924-12.918c4.435 0 8.042-3.608 8.042-8.041 0-4.435-3.607-8.041-8.042-8.041-3.898 0-7.155 2.791-7.885 6.48v.049s-.18 1.654 0 3.073c.73 3.689 3.987 6.48 7.885 6.48"></path><path d="M101.965 105.961c-6.965 0-12.841-4.655-14.692-11.022H73.376l-.076.043-16.575-28.517H46.592c-1.852 6.367-7.727 11.023-14.694 11.023-8.451 0-15.303-6.852-15.303-15.303 0-8.452 6.852-15.305 15.303-15.305 6.967 0 12.842 4.656 14.694 11.025h9.905l.128-.217L73.3 28.999l.141.083h13.768c1.852-6.369 7.727-11.025 14.692-11.025 8.453 0 15.305 6.853 15.305 15.305 0 8.451-6.852 15.304-15.305 15.304-6.965 0-12.84-4.656-14.692-11.025h-9.03l-14.14 24.326-.006.023.005.022L78.2 86.378h9.073c1.851-6.369 7.727-11.026 14.692-11.026 8.453 0 15.305 6.853 15.305 15.305s-6.852 15.304-15.305 15.304zM124.996 0H8.004C3.584 0 0 3.561 0 7.953v108.094C0 120.44 3.584 124 8.004 124h116.992c4.421 0 8.004-3.56 8.004-7.953V7.953C133 3.561 129.417 0 124.996 0z"></path></g></svg></a><div class="css-de1dx1"><a href="/terms">Terms</a><span>·</span><a href="/privacy">Privacy</a></div><div class="css-1h53588"><h3 class="css-12k57td">SOC 2 Type 2 Certified</h3><a href="http://www.aicpa.org/soc4so" rel="nofollow noreferrer noopener" target="_blank" title="SOC2 badge"><img src="https://img.stackshare.io/fe/SOC2.png" class="css-j1o656"/></a></div><div class="css-zr18wh"><div>Copyright © <!-- -->2022<!-- --> StackShare, Inc. </div><div>All rights reserved.</div></div><div class="css-de1dx1"><a href="/html-sitemaps/stackups/main.html">Sitemap</a></div></div></div></div></div></footer></div> <script> renderComponent('Footer','Footer-react-component-b887cc69-1029-4251-be72-f428c4a31686','Footer-apollo-state-b887cc69-1029-4251-be72-f428c4a31686','Footer-glamor-b887cc69-1029-4251-be72-f428c4a31686', 'apollo','{"isAdmin":null}'); </script>